RestorableFrame.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39: package xeij;
40:
41: import java.awt.*;
42: import java.awt.event.*;
43: import java.awt.image.*;
44: import java.lang.*;
45: import java.util.*;
46: import javax.swing.*;
47:
48: public class RestorableFrame extends JFrame {
49:
50:
51: protected static HashMap<String,RestorableFrame> rfmKeyToFrame = new HashMap<String,RestorableFrame> ();
52: protected static HashMap<String,Rectangle> rfmKeyToBounds = new HashMap<String,Rectangle> ();
53: protected static HashMap<String,Integer> rfmKeyToState = new HashMap<String,Integer> ();
54: protected static HashMap<String,Boolean> rfmKeyToOpened = new HashMap<String,Boolean> ();
55:
56:
57:
58:
59:
60: public static Rectangle rfmGetBounds (String key) {
61: return rfmKeyToBounds.containsKey (key) ? rfmKeyToBounds.get (key) : new Rectangle ();
62: }
63:
64:
65:
66: public static void rfmSetBounds (String key, Rectangle bounds) {
67: rfmKeyToBounds.put (key, bounds);
68: if (rfmKeyToFrame.containsKey (key)) {
69: RestorableFrame frame = rfmKeyToFrame.get (key);
70: if (frame.isShowing ()) {
71: frame.setLocation (bounds.x, bounds.y);
72: if (frame.rfmResizable) {
73: if (bounds.width > 0 && bounds.height > 0) {
74: frame.setSize (bounds.width, bounds.height);
75: }
76: }
77: }
78: }
79: }
80:
81:
82:
83: public static int rfmGetState (String key) {
84: return rfmKeyToState.containsKey (key) ? rfmKeyToState.get (key) : Frame.NORMAL;
85: }
86:
87:
88:
89: public static void rfmSetState (String key, int state) {
90: rfmKeyToState.put (key, state);
91: if (rfmKeyToFrame.containsKey (key)) {
92: RestorableFrame frame = rfmKeyToFrame.get (key);
93: if (frame.isShowing ()) {
94: frame.setExtendedState (state);
95: }
96: }
97: }
98:
99:
100:
101: public static boolean rfmGetOpened (String key) {
102: return rfmKeyToOpened.containsKey (key) && rfmKeyToOpened.get (key);
103: }
104:
105:
106:
107: public static void rfmSetOpened (String key, boolean opened) {
108: rfmKeyToOpened.put (key, opened);
109:
110: }
111:
112:
113:
114: public static BufferedImage rfmCapture (String key) {
115: if (rfmGetOpened (key)) {
116: rfmKeyToFrame.get (key).rfmUpdate ();
117: Rectangle rect = rfmGetBounds (key);
118: if (!rect.isEmpty ()) {
119: try {
120: BufferedImage image = new Robot().createScreenCapture (rect);
121: return image;
122: } catch (Exception e) {
123: }
124: }
125: }
126: return null;
127: }
128:
129:
130: private String rfmKey;
131: private boolean rfmRestored;
132: private boolean rfmResizable;
133:
134:
135: public RestorableFrame (String key, String title) {
136: this (key, title, true);
137: }
138:
139: @SuppressWarnings ("this-escape") public RestorableFrame (String key, String title, boolean resizable) {
140: super (title, GraphicsEnvironment.getLocalGraphicsEnvironment ().getDefaultScreenDevice ().getDefaultConfiguration ());
141: rfmKey = key;
142: rfmRestored = false;
143: rfmResizable = resizable;
144: if (rfmKeyToFrame.containsKey (key)) {
145: throw new IllegalArgumentException ("RestorableFrame: Key " + key + " is already used.");
146: }
147: rfmKeyToFrame.put (key, this);
148: if (rfmKeyToBounds.containsKey (key)) {
149: rfmRestoreBounds (rfmKeyToBounds.get (key));
150: } else {
151: rfmKeyToBounds.put (key, new Rectangle ());
152: }
153: if (rfmKeyToState.containsKey (key)) {
154: setExtendedState (rfmKeyToState.get (key));
155: } else {
156: rfmKeyToState.put (key, Frame.NORMAL);
157: }
158:
159: addComponentListener (new ComponentAdapter () {
160: @Override public void componentMoved (ComponentEvent ce) {
161: rfmUpdate ();
162: }
163: @Override public void componentResized (ComponentEvent ce) {
164: rfmUpdate ();
165: }
166: });
167:
168: addWindowListener (new WindowAdapter () {
169: @Override public void windowClosing (WindowEvent we) {
170:
171: rfmKeyToOpened.put (rfmKey, false);
172: }
173: @Override public void windowOpened (WindowEvent we) {
174: rfmKeyToOpened.put (rfmKey, true);
175: }
176: });
177:
178: addWindowStateListener (new WindowStateListener () {
179: @Override public void windowStateChanged (WindowEvent we) {
180: rfmUpdate ();
181: }
182: });
183: }
184:
185:
186:
187: private void rfmUpdate () {
188: if (!isShowing ()) {
189: return;
190: }
191: for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment ().getScreenDevices ()) {
192: if (gd.getFullScreenWindow () == this) {
193: return;
194: }
195: }
196: if (!rfmRestored) {
197: rfmRestored = true;
198: rfmRestoreBounds (rfmKeyToBounds.get (rfmKey));
199: setExtendedState (rfmKeyToState.get (rfmKey));
200: } else {
201: Point p = getLocationOnScreen ();
202: Dimension d = getSize ();
203: int state = getExtendedState ();
204:
205: Rectangle bounds = rfmKeyToBounds.get (rfmKey);
206: if ((state & (Frame.ICONIFIED | Frame.MAXIMIZED_HORIZ)) == 0) {
207:
208: bounds.x = p.x;
209: bounds.width = d.width;
210: }
211: if ((state & (Frame.ICONIFIED | Frame.MAXIMIZED_VERT)) == 0) {
212:
213: bounds.y = p.y;
214: bounds.height = d.height;
215: }
216:
217: rfmKeyToState.put (rfmKey, state);
218: }
219: }
220:
221:
222:
223:
224:
225: private void rfmRestoreBounds (Rectangle bounds) {
226: Rectangle location = bounds;
227: test:
228: {
229: Rectangle testBounds = new Rectangle (bounds.x, bounds.y, bounds.width, 16);
230: for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment ().getScreenDevices ()) {
231: for (GraphicsConfiguration gc : gd.getConfigurations ()) {
232: Rectangle intersectionBounds = testBounds.intersection (gc.getBounds ());
233: if (intersectionBounds.width >= 64 && intersectionBounds.height >= 16) {
234:
235: break test;
236: }
237: }
238: }
239:
240: location = GraphicsEnvironment.getLocalGraphicsEnvironment ().getDefaultScreenDevice ().getDefaultConfiguration ().getBounds ();
241: }
242: setLocation (location.x, location.y);
243: if (rfmResizable) {
244: if (bounds.width > 0 && bounds.height > 0) {
245: setSize (bounds.width, bounds.height);
246: }
247: }
248: }
249:
250: }
251:
252:
253: