1 | /* |
2 | * $Id: JEmbeddedFrame.java,v 1.6 2006/03/07 23:30:50 hastings Exp $ |
3 | * |
4 | * (c) Copyright, Moebius Solutions, Inc., 2004 |
5 | * |
6 | * All Rights Reserved |
7 | * |
8 | * This material may be reproduced by or for the U. S. Government |
9 | * pursuant to the copyright license under the clause at |
10 | * DFARS 252.227-7014 (OCT 2001). |
11 | */ |
12 | |
13 | package com.moesol.ui; |
14 | |
15 | import java.awt.event.ActionEvent; |
16 | import java.awt.event.ActionListener; |
17 | import java.awt.event.HierarchyEvent; |
18 | import java.awt.event.HierarchyListener; |
19 | import java.awt.event.WindowAdapter; |
20 | import java.awt.event.WindowEvent; |
21 | import java.util.logging.Level; |
22 | import java.util.logging.Logger; |
23 | |
24 | import javax.swing.JFrame; |
25 | import javax.swing.Timer; |
26 | |
27 | import com.moesol.bindings.platform_sdk.windows_api.HWND; |
28 | |
29 | |
30 | /** |
31 | * @author robert |
32 | */ |
33 | public class JEmbeddedFrame extends JFrame { |
34 | private static final Logger s_logger = Logger.getLogger(JEmbeddedFrame.class.getName()); |
35 | public static final int DEFAULT_REPAINT_PERIOD = 500; |
36 | |
37 | private HWND m_hwnd_parent; |
38 | private HWND m_hwnd; |
39 | private Timer m_paint_timer = null; |
40 | |
41 | public JEmbeddedFrame(HWND hwnd) { |
42 | s_logger.log(Level.FINEST, "Created JEmbeddedFrame, parent={0}", hwnd); |
43 | m_hwnd_parent = hwnd; |
44 | setUndecorated(true); |
45 | setLocation(0, 0); |
46 | addHierarchyListener(new EmbedOnDisplay()); |
47 | addWindowListener(new WindowAdapter() { |
48 | public void windowClosed(WindowEvent arg0) { |
49 | stopRepaintTimer(); |
50 | } |
51 | }); |
52 | setVisible(true); |
53 | } |
54 | |
55 | private class EmbedOnDisplay implements HierarchyListener { |
56 | public void hierarchyChanged(HierarchyEvent e) { |
57 | if (!isDisplayabilityChange(e)) { return; } |
58 | if (!isDisplayable()) { |
59 | m_hwnd = null; |
60 | return; |
61 | } |
62 | m_hwnd = jni_getHwnd(); |
63 | if (m_hwnd == null) { |
64 | throw new RuntimeException("Displayable, but no HWND"); |
65 | } |
66 | |
67 | if (m_hwnd_parent == null) { return; } |
68 | jni_reparentWindow(m_hwnd, m_hwnd_parent); |
69 | } |
70 | private boolean isDisplayabilityChange(HierarchyEvent e) { |
71 | return (0 != (HierarchyEvent.DISPLAYABILITY_CHANGED & e.getChangeFlags())); |
72 | } |
73 | } |
74 | private native HWND jni_getHwnd(); |
75 | private native boolean jni_reparentWindow(HWND hwnd, HWND hwnd_parent); |
76 | |
77 | /** |
78 | * This method starts a repaint timer that will repaint this frame every |
79 | * half second. This is a hack that fixes up a few repaint problems we have |
80 | * with this window when embedded. You should only call this method if you |
81 | * are experiencing repaint problems and your window can afford to be |
82 | * repainted every half second. |
83 | */ |
84 | public void startRepaintTimer() { |
85 | startRepaintTimer(DEFAULT_REPAINT_PERIOD); |
86 | } |
87 | public void startRepaintTimer(int period) { |
88 | if (m_paint_timer == null) { |
89 | m_paint_timer = createRepaintTimer(); |
90 | } |
91 | m_paint_timer.setCoalesce(true); |
92 | m_paint_timer.setInitialDelay(period); |
93 | m_paint_timer.setDelay(period); |
94 | m_paint_timer.setRepeats(true); |
95 | m_paint_timer.setLogTimers(false); |
96 | m_paint_timer.start(); |
97 | } |
98 | |
99 | public void stopRepaintTimer() { |
100 | if (m_paint_timer == null) { |
101 | return; |
102 | } |
103 | m_paint_timer.stop(); |
104 | } |
105 | |
106 | private Timer createRepaintTimer() { |
107 | return new Timer(DEFAULT_REPAINT_PERIOD, new ActionListener() { |
108 | public void actionPerformed(ActionEvent arg0) { |
109 | repaint(); |
110 | } |
111 | }); |
112 | } |
113 | } |
114 | |