25
26 package javax.swing.plaf.basic;
27
28 import java.awt.*;
29 import java.awt.event.*;
30 import javax.swing.*;
31 import javax.swing.plaf.*;
32 import javax.swing.event.*;
33 import java.beans.*;
34 import sun.swing.DefaultLookup;
35 import sun.swing.UIAction;
36
37 /**
38 * A basic L&F implementation of JInternalFrame.
39 *
40 * @author David Kloba
41 * @author Rich Schiavi
42 */
43 public class BasicInternalFrameUI extends InternalFrameUI
44 {
45
46 protected JInternalFrame frame;
47
48 private Handler handler;
49 protected MouseInputAdapter borderListener;
50 protected PropertyChangeListener propertyChangeListener;
51 protected LayoutManager internalFrameLayout;
52 protected ComponentListener componentListener;
53 protected MouseInputListener glassPaneDispatcher;
54 private InternalFrameListener internalFrameListener;
55
56 protected JComponent northPane;
57 protected JComponent southPane;
58 protected JComponent westPane;
59 protected JComponent eastPane;
60
61 protected BasicInternalFrameTitlePane titlePane; // access needs this
62
63 private static DesktopManager sharedDesktopManager;
64 private boolean componentListenerAdded = false;
65
66 private Rectangle parentBounds;
67
68 private boolean dragging = false;
69 private boolean resizing = false;
70
71 /**
72 * As of Java 2 platform v1.3 this previously undocumented field is no
73 * longer used.
74 * Key bindings are now defined by the LookAndFeel, please refer to
75 * the key bindings specification for further details.
76 *
77 * @deprecated As of Java 2 platform v1.3.
78 */
79 @Deprecated
80 protected KeyStroke openMenuKey;
81
82 private boolean keyBindingRegistered = false;
83 private boolean keyBindingActive = false;
84
85 /////////////////////////////////////////////////////////////////////////////
86 // ComponentUI Interface Implementation methods
87 /////////////////////////////////////////////////////////////////////////////
88 public static ComponentUI createUI(JComponent b) {
89 return new BasicInternalFrameUI((JInternalFrame)b);
90 }
91
92 public BasicInternalFrameUI(JInternalFrame b) {
93 LookAndFeel laf = UIManager.getLookAndFeel();
94 if (laf instanceof BasicLookAndFeel) {
95 ((BasicLookAndFeel)laf).installAWTEventListener();
96 }
97 }
98
99 public void installUI(JComponent c) {
100
101 frame = (JInternalFrame)c;
102
103 installDefaults();
104 installListeners();
105 installComponents();
106 installKeyboardActions();
107
108 LookAndFeel.installProperty(frame, "opaque", Boolean.TRUE);
109 }
110
111 public void uninstallUI(JComponent c) {
112 if(c != frame)
113 throw new IllegalComponentStateException(
114 this + " was asked to deinstall() "
115 + c + " when it only knows about "
116 + frame + ".");
117
118 uninstallKeyboardActions();
119 uninstallComponents();
120 uninstallListeners();
121 uninstallDefaults();
122 updateFrameCursor();
123 handler = null;
124 frame = null;
125 }
126
127 protected void installDefaults(){
128 Icon frameIcon = frame.getFrameIcon();
129 if (frameIcon == null || frameIcon instanceof UIResource) {
130 frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
131 }
132
133 // Enable the content pane to inherit background color from its
134 // parent by setting its background color to null.
135 Container contentPane = frame.getContentPane();
136 if (contentPane != null) {
137 Color bg = contentPane.getBackground();
138 if (bg instanceof UIResource)
139 contentPane.setBackground(null);
140 }
141 frame.setLayout(internalFrameLayout = createLayoutManager());
142 frame.setBackground(UIManager.getLookAndFeelDefaults().getColor("control"));
143
144 LookAndFeel.installBorder(frame, "InternalFrame.border");
145
146 }
147 protected void installKeyboardActions(){
148 createInternalFrameListener();
149 if (internalFrameListener != null) {
150 frame.addInternalFrameListener(internalFrameListener);
151 }
152
153 LazyActionMap.installLazyActionMap(frame, BasicInternalFrameUI.class,
154 "InternalFrame.actionMap");
155 }
156
157 static void loadActionMap(LazyActionMap map) {
158 map.put(new UIAction("showSystemMenu") {
159 public void actionPerformed(ActionEvent evt) {
160 JInternalFrame iFrame = (JInternalFrame)evt.getSource();
161 if (iFrame.getUI() instanceof BasicInternalFrameUI) {
162 JComponent comp = ((BasicInternalFrameUI)
163 iFrame.getUI()).getNorthPane();
164 if (comp instanceof BasicInternalFrameTitlePane) {
165 ((BasicInternalFrameTitlePane)comp).
166 showSystemMenu();
167 }
168 }
169 }
170
171 public boolean isEnabled(Object sender){
172 if (sender instanceof JInternalFrame) {
173 JInternalFrame iFrame = (JInternalFrame)sender;
174 if (iFrame.getUI() instanceof BasicInternalFrameUI) {
175 return ((BasicInternalFrameUI)iFrame.getUI()).
176 isKeyBindingActive();
177 }
178 }
179 return false;
180 }
181 });
182
183 // Set the ActionMap's parent to the Auditory Feedback Action Map
184 BasicLookAndFeel.installAudioActionMap(map);
185 }
186
187 protected void installComponents(){
188 setNorthPane(createNorthPane(frame));
189 setSouthPane(createSouthPane(frame));
190 setEastPane(createEastPane(frame));
191 setWestPane(createWestPane(frame));
192 }
193
194 /**
195 * @since 1.3
196 */
197 protected void installListeners() {
198 borderListener = createBorderListener(frame);
199 propertyChangeListener = createPropertyChangeListener();
200 frame.addPropertyChangeListener(propertyChangeListener);
201 installMouseHandlers(frame);
202 glassPaneDispatcher = createGlassPaneDispatcher();
203 if (glassPaneDispatcher != null) {
204 frame.getGlassPane().addMouseListener(glassPaneDispatcher);
205 frame.getGlassPane().addMouseMotionListener(glassPaneDispatcher);
206 }
207 componentListener = createComponentListener();
208 if (frame.getParent() != null) {
209 parentBounds = frame.getParent().getBounds();
210 }
211 if ((frame.getParent() != null) && !componentListenerAdded) {
212 frame.getParent().addComponentListener(componentListener);
213 componentListenerAdded = true;
214 }
240
241 InputMap getInputMap(int condition) {
242 if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
243 return createInputMap(condition);
244 }
245 return null;
246 }
247
248 InputMap createInputMap(int condition) {
249 if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
250 Object[] bindings = (Object[])DefaultLookup.get(
251 frame, this, "InternalFrame.windowBindings");
252
253 if (bindings != null) {
254 return LookAndFeel.makeComponentInputMap(frame, bindings);
255 }
256 }
257 return null;
258 }
259
260 protected void uninstallDefaults() {
261 Icon frameIcon = frame.getFrameIcon();
262 if (frameIcon instanceof UIResource) {
263 frame.setFrameIcon(null);
264 }
265 internalFrameLayout = null;
266 frame.setLayout(null);
267 LookAndFeel.uninstallBorder(frame);
268 }
269
270 protected void uninstallComponents(){
271 setNorthPane(null);
272 setSouthPane(null);
273 setEastPane(null);
274 setWestPane(null);
275 if(titlePane != null) {
276 titlePane.uninstallDefaults();
277 }
278 titlePane = null;
279 }
280
281 /**
282 * @since 1.3
283 */
284 protected void uninstallListeners() {
285 if ((frame.getParent() != null) && componentListenerAdded) {
286 frame.getParent().removeComponentListener(componentListener);
287 componentListenerAdded = false;
288 }
289 componentListener = null;
290 if (glassPaneDispatcher != null) {
291 frame.getGlassPane().removeMouseListener(glassPaneDispatcher);
292 frame.getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
293 glassPaneDispatcher = null;
294 }
295 deinstallMouseHandlers(frame);
296 frame.removePropertyChangeListener(propertyChangeListener);
297 propertyChangeListener = null;
298 borderListener = null;
299 }
300
301 protected void uninstallKeyboardActions(){
302 if (internalFrameListener != null) {
303 frame.removeInternalFrameListener(internalFrameListener);
304 }
305 internalFrameListener = null;
306
307 SwingUtilities.replaceUIInputMap(frame, JComponent.
308 WHEN_IN_FOCUSED_WINDOW, null);
309 SwingUtilities.replaceUIActionMap(frame, null);
310
311 }
312
313 void updateFrameCursor() {
314 if (resizing) {
315 return;
316 }
317 Cursor s = frame.getLastCursor();
318 if (s == null) {
319 s = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
320 }
321 frame.setCursor(s);
322 }
323
324 protected LayoutManager createLayoutManager(){
325 return getHandler();
326 }
327
328 protected PropertyChangeListener createPropertyChangeListener(){
329 return getHandler();
330 }
331
332
333
334 public Dimension getPreferredSize(JComponent x) {
335 if(frame == x)
336 return frame.getLayout().preferredLayoutSize(x);
337 return new Dimension(100, 100);
338 }
339
340 public Dimension getMinimumSize(JComponent x) {
341 if(frame == x) {
342 return frame.getLayout().minimumLayoutSize(x);
343 }
344 return new Dimension(0, 0);
345 }
346
347 public Dimension getMaximumSize(JComponent x) {
348 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
349 }
350
351
352
353 /**
354 * Installs necessary mouse handlers on <code>newPane</code>
355 * and adds it to the frame.
356 * Reverse process for the <code>currentPane</code>.
357 *
358 * @param currentPane this {@code Jcomponent} is the current pane being
359 * viewed that has mouse handlers installed
360 * @param newPane this {@code Jcomponent} is the pane which will be added
361 * and have mouse handlers installed
362 */
363 protected void replacePane(JComponent currentPane, JComponent newPane) {
364 if(currentPane != null) {
365 deinstallMouseHandlers(currentPane);
366 frame.remove(currentPane);
367 }
368 if(newPane != null) {
369 frame.add(newPane);
370 installMouseHandlers(newPane);
371 }
372 }
373
374 protected void deinstallMouseHandlers(JComponent c) {
375 c.removeMouseListener(borderListener);
376 c.removeMouseMotionListener(borderListener);
377 }
378
379 protected void installMouseHandlers(JComponent c) {
380 c.addMouseListener(borderListener);
381 c.addMouseMotionListener(borderListener);
382 }
383
384 protected JComponent createNorthPane(JInternalFrame w) {
385 titlePane = new BasicInternalFrameTitlePane(w);
386 return titlePane;
387 }
388
389
390 protected JComponent createSouthPane(JInternalFrame w) {
391 return null;
392 }
393
394 protected JComponent createWestPane(JInternalFrame w) {
395 return null;
396 }
397
398 protected JComponent createEastPane(JInternalFrame w) {
399 return null;
400 }
401
402
403 protected MouseInputAdapter createBorderListener(JInternalFrame w) {
404 return new BorderListener();
405 }
406
407 protected void createInternalFrameListener(){
408 internalFrameListener = getHandler();
409 }
410
411 protected final boolean isKeyBindingRegistered(){
412 return keyBindingRegistered;
413 }
414
415 protected final void setKeyBindingRegistered(boolean b){
416 keyBindingRegistered = b;
417 }
418
419 public final boolean isKeyBindingActive(){
420 return keyBindingActive;
421 }
422
423 protected final void setKeyBindingActive(boolean b){
424 keyBindingActive = b;
425 }
426
427
428 protected void setupMenuOpenKey(){
429 // PENDING(hania): Why are these WHEN_IN_FOCUSED_WINDOWs? Shouldn't
430 // they be WHEN_ANCESTOR_OF_FOCUSED_COMPONENT?
431 // Also, no longer registering on the desktopicon, the previous
432 // action did nothing.
433 InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
434 SwingUtilities.replaceUIInputMap(frame,
435 JComponent.WHEN_IN_FOCUSED_WINDOW, map);
436 //ActionMap actionMap = getActionMap();
437 //SwingUtilities.replaceUIActionMap(frame, actionMap);
438 }
439
440 protected void setupMenuCloseKey(){
441 }
442
443 public JComponent getNorthPane() {
444 return northPane;
445 }
446
447 public void setNorthPane(JComponent c) {
448 if (northPane != null &&
449 northPane instanceof BasicInternalFrameTitlePane) {
450 ((BasicInternalFrameTitlePane)northPane).uninstallListeners();
451 }
452 replacePane(northPane, c);
453 northPane = c;
454 if (c instanceof BasicInternalFrameTitlePane) {
455 titlePane = (BasicInternalFrameTitlePane)c;
456 }
457 }
458
459 public JComponent getSouthPane() {
460 return southPane;
461 }
462
463 public void setSouthPane(JComponent c) {
464 southPane = c;
465 }
466
467 public JComponent getWestPane() {
468 return westPane;
469 }
470
471 public void setWestPane(JComponent c) {
472 westPane = c;
473 }
474
475 public JComponent getEastPane() {
476 return eastPane;
477 }
478
479 public void setEastPane(JComponent c) {
480 eastPane = c;
481 }
482
483 public class InternalFramePropertyChangeListener implements
484 PropertyChangeListener {
485 // NOTE: This class exists only for backward compatibility. All
486 // its functionality has been moved into Handler. If you need to add
487 // new functionality add it to the Handler, but make sure this
488 // class calls into the Handler.
489 /**
490 * Detects changes in state from the JInternalFrame and handles
491 * actions.
492 */
493 public void propertyChange(PropertyChangeEvent evt) {
494 getHandler().propertyChange(evt);
495 }
496 }
497
498 public class InternalFrameLayout implements LayoutManager {
499 // NOTE: This class exists only for backward compatibility. All
500 // its functionality has been moved into Handler. If you need to add
501 // new functionality add it to the Handler, but make sure this
502 // class calls into the Handler.
503 public void addLayoutComponent(String name, Component c) {
504 getHandler().addLayoutComponent(name, c);
505 }
506
507 public void removeLayoutComponent(Component c) {
508 getHandler().removeLayoutComponent(c);
509 }
510
511 public Dimension preferredLayoutSize(Container c) {
512 return getHandler().preferredLayoutSize(c);
513 }
514
515 public Dimension minimumLayoutSize(Container c) {
516 return getHandler().minimumLayoutSize(c);
517 }
518
519 public void layoutContainer(Container c) {
520 getHandler().layoutContainer(c);
521 }
522 }
523
524 /// DesktopManager methods
525 /**
526 * Returns the proper DesktopManager. Calls getDesktopPane() to
527 * find the JDesktop component and returns the desktopManager from
528 * it. If this fails, it will return a default DesktopManager that
529 * should work in arbitrary parents.
530 */
531 protected DesktopManager getDesktopManager() {
532 if(frame.getDesktopPane() != null
533 && frame.getDesktopPane().getDesktopManager() != null)
534 return frame.getDesktopPane().getDesktopManager();
535 if(sharedDesktopManager == null)
536 sharedDesktopManager = createDesktopManager();
537 return sharedDesktopManager;
538 }
539
540 protected DesktopManager createDesktopManager(){
541 return new DefaultDesktopManager();
542 }
543
544 /**
545 * This method is called when the user wants to close the frame.
546 * The <code>playCloseSound</code> Action is fired.
547 * This action is delegated to the desktopManager.
548 *
549 * @param f the {@code JInternalFrame} being viewed
550 */
551 protected void closeFrame(JInternalFrame f) {
552 // Internal Frame Auditory Cue Activation
553 BasicLookAndFeel.playSound(frame,"InternalFrame.closeSound");
554 // delegate to desktop manager
555 getDesktopManager().closeFrame(f);
556 }
557
558 /**
559 * This method is called when the user wants to maximize the frame.
636 */
637 protected void deactivateFrame(JInternalFrame f) {
638 getDesktopManager().deactivateFrame(f);
639 }
640
641 /////////////////////////////////////////////////////////////////////////
642 /// Border Listener Class
643 /////////////////////////////////////////////////////////////////////////
644 /**
645 * Listens for border adjustments.
646 */
647 protected class BorderListener extends MouseInputAdapter implements SwingConstants
648 {
649 // _x & _y are the mousePressed location in absolute coordinate system
650 int _x, _y;
651 // __x & __y are the mousePressed location in source view's coordinate system
652 int __x, __y;
653 Rectangle startingBounds;
654 int resizeDir;
655
656
657 protected final int RESIZE_NONE = 0;
658 private boolean discardRelease = false;
659
660 int resizeCornerSize = 16;
661
662 public void mouseClicked(MouseEvent e) {
663 if(e.getClickCount() > 1 && e.getSource() == getNorthPane()) {
664 if(frame.isIconifiable() && frame.isIcon()) {
665 try { frame.setIcon(false); } catch (PropertyVetoException e2) { }
666 } else if(frame.isMaximizable()) {
667 if(!frame.isMaximum())
668 try { frame.setMaximum(true); } catch (PropertyVetoException e2) { }
669 else
670 try { frame.setMaximum(false); } catch (PropertyVetoException e3) { }
671 }
672 }
673 }
674
675 // Factor out finishMouseReleased() from mouseReleased(), so that
676 // it can be called by cancelResize() without passing it a null
1097 frame.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
1098 }
1099 else
1100 updateFrameCursor();
1101 return;
1102 }
1103
1104 updateFrameCursor();
1105 }
1106
1107 public void mouseEntered(MouseEvent e) {
1108 updateFrameCursor();
1109 }
1110
1111 public void mouseExited(MouseEvent e) {
1112 updateFrameCursor();
1113 }
1114
1115 } /// End BorderListener Class
1116
1117 protected class ComponentHandler implements ComponentListener {
1118 // NOTE: This class exists only for backward compatibility. All
1119 // its functionality has been moved into Handler. If you need to add
1120 // new functionality add it to the Handler, but make sure this
1121 // class calls into the Handler.
1122 /** Invoked when a JInternalFrame's parent's size changes. */
1123 public void componentResized(ComponentEvent e) {
1124 getHandler().componentResized(e);
1125 }
1126
1127 public void componentMoved(ComponentEvent e) {
1128 getHandler().componentMoved(e);
1129 }
1130 public void componentShown(ComponentEvent e) {
1131 getHandler().componentShown(e);
1132 }
1133 public void componentHidden(ComponentEvent e) {
1134 getHandler().componentHidden(e);
1135 }
1136 }
1137
1138 protected ComponentListener createComponentListener() {
1139 return getHandler();
1140 }
1141
1142
1143 protected class GlassPaneDispatcher implements MouseInputListener {
1144 // NOTE: This class exists only for backward compatibility. All
1145 // its functionality has been moved into Handler. If you need to add
1146 // new functionality add it to the Handler, but make sure this
1147 // class calls into the Handler.
1148 public void mousePressed(MouseEvent e) {
1149 getHandler().mousePressed(e);
1150 }
1151
1152 public void mouseEntered(MouseEvent e) {
1153 getHandler().mouseEntered(e);
1154 }
1155
1156 public void mouseMoved(MouseEvent e) {
1157 getHandler().mouseMoved(e);
1158 }
1159
1160 public void mouseExited(MouseEvent e) {
1161 getHandler().mouseExited(e);
1162 }
1163
1164 public void mouseClicked(MouseEvent e) {
1165 getHandler().mouseClicked(e);
1166 }
1167
1168 public void mouseReleased(MouseEvent e) {
1169 getHandler().mouseReleased(e);
1170 }
1171
1172 public void mouseDragged(MouseEvent e) {
1173 getHandler().mouseDragged(e);
1174 }
1175 }
1176
1177 protected MouseInputListener createGlassPaneDispatcher() {
1178 return null;
1179 }
1180
1181
1182 protected class BasicInternalFrameListener implements InternalFrameListener
1183 {
1184 // NOTE: This class exists only for backward compatibility. All
1185 // its functionality has been moved into Handler. If you need to add
1186 // new functionality add it to the Handler, but make sure this
1187 // class calls into the Handler.
1188 public void internalFrameClosing(InternalFrameEvent e) {
1189 getHandler().internalFrameClosing(e);
1190 }
1191
1192 public void internalFrameClosed(InternalFrameEvent e) {
1193 getHandler().internalFrameClosed(e);
1194 }
1195
1196 public void internalFrameOpened(InternalFrameEvent e) {
1197 getHandler().internalFrameOpened(e);
1198 }
1199
1200 public void internalFrameIconified(InternalFrameEvent e) {
1201 getHandler().internalFrameIconified(e);
1202 }
1203
1204 public void internalFrameDeiconified(InternalFrameEvent e) {
1205 getHandler().internalFrameDeiconified(e);
1206 }
1207
1208 public void internalFrameActivated(InternalFrameEvent e) {
1209 getHandler().internalFrameActivated(e);
1210 }
1211
1212
1213 public void internalFrameDeactivated(InternalFrameEvent e) {
1214 getHandler().internalFrameDeactivated(e);
1215 }
1216 }
1217
1218 private class Handler implements ComponentListener, InternalFrameListener,
1219 LayoutManager, MouseInputListener, PropertyChangeListener,
1220 WindowFocusListener, SwingConstants {
1221
1222 public void windowGainedFocus(WindowEvent e) {
1223 }
1224
1225 public void windowLostFocus(WindowEvent e) {
1226 // Cancel a resize which may be in progress, when a
1227 // WINDOW_LOST_FOCUS event occurs, which may be
1228 // caused by an Alt-Tab or a modal dialog popup.
1229 cancelResize();
1230 }
1231
1232 // ComponentHandler methods
|
25
26 package javax.swing.plaf.basic;
27
28 import java.awt.*;
29 import java.awt.event.*;
30 import javax.swing.*;
31 import javax.swing.plaf.*;
32 import javax.swing.event.*;
33 import java.beans.*;
34 import sun.swing.DefaultLookup;
35 import sun.swing.UIAction;
36
37 /**
38 * A basic L&F implementation of JInternalFrame.
39 *
40 * @author David Kloba
41 * @author Rich Schiavi
42 */
43 public class BasicInternalFrameUI extends InternalFrameUI
44 {
45 /** frame */
46 protected JInternalFrame frame;
47
48 private Handler handler;
49 /** border listener */
50 protected MouseInputAdapter borderListener;
51 /** property change listener */
52 protected PropertyChangeListener propertyChangeListener;
53 /** internal frame layout */
54 protected LayoutManager internalFrameLayout;
55 /** component listener */
56 protected ComponentListener componentListener;
57 /** glass pane dispatcher */
58 protected MouseInputListener glassPaneDispatcher;
59 private InternalFrameListener internalFrameListener;
60
61 /** north pane */
62 protected JComponent northPane;
63 /** south pane */
64 protected JComponent southPane;
65 /** west pane */
66 protected JComponent westPane;
67 /** east pane */
68 protected JComponent eastPane;
69 /** title pane */
70 protected BasicInternalFrameTitlePane titlePane; // access needs this
71
72 private static DesktopManager sharedDesktopManager;
73 private boolean componentListenerAdded = false;
74
75 private Rectangle parentBounds;
76
77 private boolean dragging = false;
78 private boolean resizing = false;
79
80 /**
81 * As of Java 2 platform v1.3 this previously undocumented field is no
82 * longer used.
83 * Key bindings are now defined by the LookAndFeel, please refer to
84 * the key bindings specification for further details.
85 *
86 * @deprecated As of Java 2 platform v1.3.
87 */
88 @Deprecated
89 protected KeyStroke openMenuKey;
90
91 private boolean keyBindingRegistered = false;
92 private boolean keyBindingActive = false;
93
94 /////////////////////////////////////////////////////////////////////////////
95 // ComponentUI Interface Implementation methods
96 /////////////////////////////////////////////////////////////////////////////
97 /**
98 * Returns a component UI.
99 * @param b a component
100 * @return a component UI
101 */
102 public static ComponentUI createUI(JComponent b) {
103 return new BasicInternalFrameUI((JInternalFrame)b);
104 }
105
106 /**
107 * Constructs a {@code BasicInternalFrameUI}.
108 * @param b the internal frame
109 */
110 public BasicInternalFrameUI(JInternalFrame b) {
111 LookAndFeel laf = UIManager.getLookAndFeel();
112 if (laf instanceof BasicLookAndFeel) {
113 ((BasicLookAndFeel)laf).installAWTEventListener();
114 }
115 }
116
117 /**
118 * Install the UI.
119 * @param c the component
120 */
121 public void installUI(JComponent c) {
122
123 frame = (JInternalFrame)c;
124
125 installDefaults();
126 installListeners();
127 installComponents();
128 installKeyboardActions();
129
130 LookAndFeel.installProperty(frame, "opaque", Boolean.TRUE);
131 }
132
133 /**
134 * Uninstall the UI.
135 * @param c the component
136 */
137 public void uninstallUI(JComponent c) {
138 if(c != frame)
139 throw new IllegalComponentStateException(
140 this + " was asked to deinstall() "
141 + c + " when it only knows about "
142 + frame + ".");
143
144 uninstallKeyboardActions();
145 uninstallComponents();
146 uninstallListeners();
147 uninstallDefaults();
148 updateFrameCursor();
149 handler = null;
150 frame = null;
151 }
152
153 /**
154 * Install the defaults.
155 */
156 protected void installDefaults(){
157 Icon frameIcon = frame.getFrameIcon();
158 if (frameIcon == null || frameIcon instanceof UIResource) {
159 frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
160 }
161
162 // Enable the content pane to inherit background color from its
163 // parent by setting its background color to null.
164 Container contentPane = frame.getContentPane();
165 if (contentPane != null) {
166 Color bg = contentPane.getBackground();
167 if (bg instanceof UIResource)
168 contentPane.setBackground(null);
169 }
170 frame.setLayout(internalFrameLayout = createLayoutManager());
171 frame.setBackground(UIManager.getLookAndFeelDefaults().getColor("control"));
172
173 LookAndFeel.installBorder(frame, "InternalFrame.border");
174
175 }
176 /**
177 * Install the keyboard actions.
178 */
179 protected void installKeyboardActions(){
180 createInternalFrameListener();
181 if (internalFrameListener != null) {
182 frame.addInternalFrameListener(internalFrameListener);
183 }
184
185 LazyActionMap.installLazyActionMap(frame, BasicInternalFrameUI.class,
186 "InternalFrame.actionMap");
187 }
188
189 static void loadActionMap(LazyActionMap map) {
190 map.put(new UIAction("showSystemMenu") {
191 public void actionPerformed(ActionEvent evt) {
192 JInternalFrame iFrame = (JInternalFrame)evt.getSource();
193 if (iFrame.getUI() instanceof BasicInternalFrameUI) {
194 JComponent comp = ((BasicInternalFrameUI)
195 iFrame.getUI()).getNorthPane();
196 if (comp instanceof BasicInternalFrameTitlePane) {
197 ((BasicInternalFrameTitlePane)comp).
198 showSystemMenu();
199 }
200 }
201 }
202
203 public boolean isEnabled(Object sender){
204 if (sender instanceof JInternalFrame) {
205 JInternalFrame iFrame = (JInternalFrame)sender;
206 if (iFrame.getUI() instanceof BasicInternalFrameUI) {
207 return ((BasicInternalFrameUI)iFrame.getUI()).
208 isKeyBindingActive();
209 }
210 }
211 return false;
212 }
213 });
214
215 // Set the ActionMap's parent to the Auditory Feedback Action Map
216 BasicLookAndFeel.installAudioActionMap(map);
217 }
218
219 /**
220 * Installs the components.
221 */
222 protected void installComponents(){
223 setNorthPane(createNorthPane(frame));
224 setSouthPane(createSouthPane(frame));
225 setEastPane(createEastPane(frame));
226 setWestPane(createWestPane(frame));
227 }
228
229 /**
230 * Installs the listeners.
231 * @since 1.3
232 */
233 protected void installListeners() {
234 borderListener = createBorderListener(frame);
235 propertyChangeListener = createPropertyChangeListener();
236 frame.addPropertyChangeListener(propertyChangeListener);
237 installMouseHandlers(frame);
238 glassPaneDispatcher = createGlassPaneDispatcher();
239 if (glassPaneDispatcher != null) {
240 frame.getGlassPane().addMouseListener(glassPaneDispatcher);
241 frame.getGlassPane().addMouseMotionListener(glassPaneDispatcher);
242 }
243 componentListener = createComponentListener();
244 if (frame.getParent() != null) {
245 parentBounds = frame.getParent().getBounds();
246 }
247 if ((frame.getParent() != null) && !componentListenerAdded) {
248 frame.getParent().addComponentListener(componentListener);
249 componentListenerAdded = true;
250 }
276
277 InputMap getInputMap(int condition) {
278 if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
279 return createInputMap(condition);
280 }
281 return null;
282 }
283
284 InputMap createInputMap(int condition) {
285 if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
286 Object[] bindings = (Object[])DefaultLookup.get(
287 frame, this, "InternalFrame.windowBindings");
288
289 if (bindings != null) {
290 return LookAndFeel.makeComponentInputMap(frame, bindings);
291 }
292 }
293 return null;
294 }
295
296 /**
297 * Uninstall the defaults.
298 */
299 protected void uninstallDefaults() {
300 Icon frameIcon = frame.getFrameIcon();
301 if (frameIcon instanceof UIResource) {
302 frame.setFrameIcon(null);
303 }
304 internalFrameLayout = null;
305 frame.setLayout(null);
306 LookAndFeel.uninstallBorder(frame);
307 }
308
309 /**
310 * Uninstall the components.
311 */
312 protected void uninstallComponents(){
313 setNorthPane(null);
314 setSouthPane(null);
315 setEastPane(null);
316 setWestPane(null);
317 if(titlePane != null) {
318 titlePane.uninstallDefaults();
319 }
320 titlePane = null;
321 }
322
323 /**
324 * Uninstall the listeners.
325 * @since 1.3
326 */
327 protected void uninstallListeners() {
328 if ((frame.getParent() != null) && componentListenerAdded) {
329 frame.getParent().removeComponentListener(componentListener);
330 componentListenerAdded = false;
331 }
332 componentListener = null;
333 if (glassPaneDispatcher != null) {
334 frame.getGlassPane().removeMouseListener(glassPaneDispatcher);
335 frame.getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
336 glassPaneDispatcher = null;
337 }
338 deinstallMouseHandlers(frame);
339 frame.removePropertyChangeListener(propertyChangeListener);
340 propertyChangeListener = null;
341 borderListener = null;
342 }
343
344 /**
345 * Uninstall the keyboard actions.
346 */
347 protected void uninstallKeyboardActions(){
348 if (internalFrameListener != null) {
349 frame.removeInternalFrameListener(internalFrameListener);
350 }
351 internalFrameListener = null;
352
353 SwingUtilities.replaceUIInputMap(frame, JComponent.
354 WHEN_IN_FOCUSED_WINDOW, null);
355 SwingUtilities.replaceUIActionMap(frame, null);
356
357 }
358
359 void updateFrameCursor() {
360 if (resizing) {
361 return;
362 }
363 Cursor s = frame.getLastCursor();
364 if (s == null) {
365 s = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
366 }
367 frame.setCursor(s);
368 }
369
370 /**
371 * Creates the layout manager.
372 * @return the layout manager
373 */
374 protected LayoutManager createLayoutManager(){
375 return getHandler();
376 }
377
378 /**
379 * Creates the property change listener.
380 * @return the property change listener
381 */
382 protected PropertyChangeListener createPropertyChangeListener(){
383 return getHandler();
384 }
385
386 /**
387 * Returns the preferred size.
388 * @param x the component
389 * @return the preferred size
390 */
391 public Dimension getPreferredSize(JComponent x) {
392 if(frame == x)
393 return frame.getLayout().preferredLayoutSize(x);
394 return new Dimension(100, 100);
395 }
396
397 /**
398 * Returns the minimum size.
399 * @param x the component
400 * @return the minimum size
401 */
402 public Dimension getMinimumSize(JComponent x) {
403 if(frame == x) {
404 return frame.getLayout().minimumLayoutSize(x);
405 }
406 return new Dimension(0, 0);
407 }
408
409 /**
410 * Returns the maximum size.
411 * @param x the component
412 * @return the maximum size
413 */
414 public Dimension getMaximumSize(JComponent x) {
415 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
416 }
417
418
419
420 /**
421 * Installs necessary mouse handlers on <code>newPane</code>
422 * and adds it to the frame.
423 * Reverse process for the <code>currentPane</code>.
424 *
425 * @param currentPane this {@code Jcomponent} is the current pane being
426 * viewed that has mouse handlers installed
427 * @param newPane this {@code Jcomponent} is the pane which will be added
428 * and have mouse handlers installed
429 */
430 protected void replacePane(JComponent currentPane, JComponent newPane) {
431 if(currentPane != null) {
432 deinstallMouseHandlers(currentPane);
433 frame.remove(currentPane);
434 }
435 if(newPane != null) {
436 frame.add(newPane);
437 installMouseHandlers(newPane);
438 }
439 }
440
441 /**
442 * Deinstalls the mouse handlers.
443 * @param c the component
444 */
445 protected void deinstallMouseHandlers(JComponent c) {
446 c.removeMouseListener(borderListener);
447 c.removeMouseMotionListener(borderListener);
448 }
449
450 /**
451 * Installs the mouse handlers.
452 * @param c the component
453 */
454 protected void installMouseHandlers(JComponent c) {
455 c.addMouseListener(borderListener);
456 c.addMouseMotionListener(borderListener);
457 }
458
459 /**
460 * Creates the north pane.
461 * @param w the internal frame
462 * @return the north pane
463 */
464 protected JComponent createNorthPane(JInternalFrame w) {
465 titlePane = new BasicInternalFrameTitlePane(w);
466 return titlePane;
467 }
468
469
470 /**
471 * Creates the north pane.
472 * @param w the internal frame
473 * @return the north pane
474 */
475 protected JComponent createSouthPane(JInternalFrame w) {
476 return null;
477 }
478
479 /**
480 * Creates the west pane.
481 * @param w the internal frame
482 * @return the west pane
483 */
484 protected JComponent createWestPane(JInternalFrame w) {
485 return null;
486 }
487
488 /**
489 * Creates the east pane.
490 * @param w the internal frame
491 * @return the east pane
492 */
493 protected JComponent createEastPane(JInternalFrame w) {
494 return null;
495 }
496
497 /**
498 * Creates the border listener.
499 * @param w the internal frame
500 * @return the border listener
501 */
502 protected MouseInputAdapter createBorderListener(JInternalFrame w) {
503 return new BorderListener();
504 }
505
506 /**
507 * Creates the internal frame listener.
508 */
509 protected void createInternalFrameListener(){
510 internalFrameListener = getHandler();
511 }
512
513 /**
514 * Returns whether or no the key binding is registered.
515 * @return whether or no the key binding is registered
516 */
517 protected final boolean isKeyBindingRegistered(){
518 return keyBindingRegistered;
519 }
520
521 /**
522 * Sets the key binding registration.
523 * @param b new value for key binding registration
524 */
525 protected final void setKeyBindingRegistered(boolean b){
526 keyBindingRegistered = b;
527 }
528
529 /**
530 * Returns whether or no the key binding is active.
531 * @return whether or no the key binding is active
532 */
533 public final boolean isKeyBindingActive(){
534 return keyBindingActive;
535 }
536
537 /**
538 * Sets the key binding activity.
539 * @param b new value for key binding activity
540 */
541 protected final void setKeyBindingActive(boolean b){
542 keyBindingActive = b;
543 }
544
545
546 /**
547 * Setup the menu open key.
548 */
549 protected void setupMenuOpenKey(){
550 // PENDING(hania): Why are these WHEN_IN_FOCUSED_WINDOWs? Shouldn't
551 // they be WHEN_ANCESTOR_OF_FOCUSED_COMPONENT?
552 // Also, no longer registering on the desktopicon, the previous
553 // action did nothing.
554 InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
555 SwingUtilities.replaceUIInputMap(frame,
556 JComponent.WHEN_IN_FOCUSED_WINDOW, map);
557 //ActionMap actionMap = getActionMap();
558 //SwingUtilities.replaceUIActionMap(frame, actionMap);
559 }
560
561 /**
562 * Setup the menu close key.
563 */
564 protected void setupMenuCloseKey(){
565 }
566
567 /**
568 * Returns the north pane.
569 * @return the north pane
570 */
571 public JComponent getNorthPane() {
572 return northPane;
573 }
574
575 /**
576 * Set the north pane.
577 * @param c the new north pane
578 */
579 public void setNorthPane(JComponent c) {
580 if (northPane != null &&
581 northPane instanceof BasicInternalFrameTitlePane) {
582 ((BasicInternalFrameTitlePane)northPane).uninstallListeners();
583 }
584 replacePane(northPane, c);
585 northPane = c;
586 if (c instanceof BasicInternalFrameTitlePane) {
587 titlePane = (BasicInternalFrameTitlePane)c;
588 }
589 }
590
591 /**
592 * Returns the south pane.
593 * @return the south pane
594 */
595 public JComponent getSouthPane() {
596 return southPane;
597 }
598
599 /**
600 * Set the south pane.
601 * @param c the new south pane
602 */
603 public void setSouthPane(JComponent c) {
604 southPane = c;
605 }
606
607 /**
608 * Returns the west pane.
609 * @return the west pane
610 */
611 public JComponent getWestPane() {
612 return westPane;
613 }
614
615 /**
616 * Set the west pane.
617 * @param c the new west pane
618 */
619 public void setWestPane(JComponent c) {
620 westPane = c;
621 }
622
623 /**
624 * Returns the east pane.
625 * @return the east pane
626 */
627 public JComponent getEastPane() {
628 return eastPane;
629 }
630
631 /**
632 * Set the east pane.
633 * @param c the new east pane
634 */
635 public void setEastPane(JComponent c) {
636 eastPane = c;
637 }
638
639 /**
640 * Internal frame property change listener.
641 */
642 public class InternalFramePropertyChangeListener implements
643 PropertyChangeListener {
644 // NOTE: This class exists only for backward compatibility. All
645 // its functionality has been moved into Handler. If you need to add
646 // new functionality add it to the Handler, but make sure this
647 // class calls into the Handler.
648 /**
649 * Detects changes in state from the JInternalFrame and handles
650 * actions.
651 */
652 public void propertyChange(PropertyChangeEvent evt) {
653 getHandler().propertyChange(evt);
654 }
655 }
656
657 /**
658 * Internal frame layout.
659 */
660 public class InternalFrameLayout implements LayoutManager {
661 // NOTE: This class exists only for backward compatibility. All
662 // its functionality has been moved into Handler. If you need to add
663 // new functionality add it to the Handler, but make sure this
664 // class calls into the Handler.
665 /**
666 * {@inheritDoc}
667 */
668 public void addLayoutComponent(String name, Component c) {
669 getHandler().addLayoutComponent(name, c);
670 }
671
672 /**
673 * {@inheritDoc}
674 */
675 public void removeLayoutComponent(Component c) {
676 getHandler().removeLayoutComponent(c);
677 }
678
679 /**
680 * {@inheritDoc}
681 */
682 public Dimension preferredLayoutSize(Container c) {
683 return getHandler().preferredLayoutSize(c);
684 }
685
686 /**
687 * {@inheritDoc}
688 */
689 public Dimension minimumLayoutSize(Container c) {
690 return getHandler().minimumLayoutSize(c);
691 }
692
693 /**
694 * {@inheritDoc}
695 */
696 public void layoutContainer(Container c) {
697 getHandler().layoutContainer(c);
698 }
699 }
700
701 /// DesktopManager methods
702 /**
703 * Returns the proper DesktopManager. Calls getDesktopPane() to
704 * find the JDesktop component and returns the desktopManager from
705 * it. If this fails, it will return a default DesktopManager that
706 * should work in arbitrary parents.
707 * @return the proper DesktopManager
708 */
709 protected DesktopManager getDesktopManager() {
710 if(frame.getDesktopPane() != null
711 && frame.getDesktopPane().getDesktopManager() != null)
712 return frame.getDesktopPane().getDesktopManager();
713 if(sharedDesktopManager == null)
714 sharedDesktopManager = createDesktopManager();
715 return sharedDesktopManager;
716 }
717
718 /**
719 * Creates the desktop manager.
720 * @return the desktop manager
721 */
722 protected DesktopManager createDesktopManager(){
723 return new DefaultDesktopManager();
724 }
725
726 /**
727 * This method is called when the user wants to close the frame.
728 * The <code>playCloseSound</code> Action is fired.
729 * This action is delegated to the desktopManager.
730 *
731 * @param f the {@code JInternalFrame} being viewed
732 */
733 protected void closeFrame(JInternalFrame f) {
734 // Internal Frame Auditory Cue Activation
735 BasicLookAndFeel.playSound(frame,"InternalFrame.closeSound");
736 // delegate to desktop manager
737 getDesktopManager().closeFrame(f);
738 }
739
740 /**
741 * This method is called when the user wants to maximize the frame.
818 */
819 protected void deactivateFrame(JInternalFrame f) {
820 getDesktopManager().deactivateFrame(f);
821 }
822
823 /////////////////////////////////////////////////////////////////////////
824 /// Border Listener Class
825 /////////////////////////////////////////////////////////////////////////
826 /**
827 * Listens for border adjustments.
828 */
829 protected class BorderListener extends MouseInputAdapter implements SwingConstants
830 {
831 // _x & _y are the mousePressed location in absolute coordinate system
832 int _x, _y;
833 // __x & __y are the mousePressed location in source view's coordinate system
834 int __x, __y;
835 Rectangle startingBounds;
836 int resizeDir;
837
838 /** resize none */
839 protected final int RESIZE_NONE = 0;
840 private boolean discardRelease = false;
841
842 int resizeCornerSize = 16;
843
844 public void mouseClicked(MouseEvent e) {
845 if(e.getClickCount() > 1 && e.getSource() == getNorthPane()) {
846 if(frame.isIconifiable() && frame.isIcon()) {
847 try { frame.setIcon(false); } catch (PropertyVetoException e2) { }
848 } else if(frame.isMaximizable()) {
849 if(!frame.isMaximum())
850 try { frame.setMaximum(true); } catch (PropertyVetoException e2) { }
851 else
852 try { frame.setMaximum(false); } catch (PropertyVetoException e3) { }
853 }
854 }
855 }
856
857 // Factor out finishMouseReleased() from mouseReleased(), so that
858 // it can be called by cancelResize() without passing it a null
1279 frame.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
1280 }
1281 else
1282 updateFrameCursor();
1283 return;
1284 }
1285
1286 updateFrameCursor();
1287 }
1288
1289 public void mouseEntered(MouseEvent e) {
1290 updateFrameCursor();
1291 }
1292
1293 public void mouseExited(MouseEvent e) {
1294 updateFrameCursor();
1295 }
1296
1297 } /// End BorderListener Class
1298
1299 /**
1300 * Component handler.
1301 */
1302 protected class ComponentHandler implements ComponentListener {
1303 // NOTE: This class exists only for backward compatibility. All
1304 // its functionality has been moved into Handler. If you need to add
1305 // new functionality add it to the Handler, but make sure this
1306 // class calls into the Handler.
1307 /** Invoked when a JInternalFrame's parent's size changes. */
1308 public void componentResized(ComponentEvent e) {
1309 getHandler().componentResized(e);
1310 }
1311
1312 /**
1313 * {@inheritDoc}
1314 */
1315 public void componentMoved(ComponentEvent e) {
1316 getHandler().componentMoved(e);
1317 }
1318 /**
1319 * {@inheritDoc}
1320 */
1321 public void componentShown(ComponentEvent e) {
1322 getHandler().componentShown(e);
1323 }
1324 /**
1325 * {@inheritDoc}
1326 */
1327 public void componentHidden(ComponentEvent e) {
1328 getHandler().componentHidden(e);
1329 }
1330 }
1331
1332 /**
1333 * Creates a component listener.
1334 * @return a component listener
1335 */
1336 protected ComponentListener createComponentListener() {
1337 return getHandler();
1338 }
1339
1340
1341 /**
1342 * Glass pane dispatcher.
1343 */
1344 protected class GlassPaneDispatcher implements MouseInputListener {
1345 // NOTE: This class exists only for backward compatibility. All
1346 // its functionality has been moved into Handler. If you need to add
1347 // new functionality add it to the Handler, but make sure this
1348 // class calls into the Handler.
1349 /**
1350 * {@inheritDoc}
1351 */
1352 public void mousePressed(MouseEvent e) {
1353 getHandler().mousePressed(e);
1354 }
1355
1356 /**
1357 * {@inheritDoc}
1358 */
1359 public void mouseEntered(MouseEvent e) {
1360 getHandler().mouseEntered(e);
1361 }
1362
1363 /**
1364 * {@inheritDoc}
1365 */
1366 public void mouseMoved(MouseEvent e) {
1367 getHandler().mouseMoved(e);
1368 }
1369
1370 /**
1371 * {@inheritDoc}
1372 */
1373 public void mouseExited(MouseEvent e) {
1374 getHandler().mouseExited(e);
1375 }
1376
1377 /**
1378 * {@inheritDoc}
1379 */
1380 public void mouseClicked(MouseEvent e) {
1381 getHandler().mouseClicked(e);
1382 }
1383
1384 /**
1385 * {@inheritDoc}
1386 */
1387 public void mouseReleased(MouseEvent e) {
1388 getHandler().mouseReleased(e);
1389 }
1390
1391 /**
1392 * {@inheritDoc}
1393 */
1394 public void mouseDragged(MouseEvent e) {
1395 getHandler().mouseDragged(e);
1396 }
1397 }
1398
1399 /**
1400 * Creates a {@code GlassPaneDispatcher}.
1401 * @return a {@code GlassPaneDispatcher}
1402 */
1403 protected MouseInputListener createGlassPaneDispatcher() {
1404 return null;
1405 }
1406
1407 /**
1408 * Basic internal frame listener.
1409 */
1410 protected class BasicInternalFrameListener implements InternalFrameListener
1411 {
1412 // NOTE: This class exists only for backward compatibility. All
1413 // its functionality has been moved into Handler. If you need to add
1414 // new functionality add it to the Handler, but make sure this
1415 // class calls into the Handler.
1416 /**
1417 * {@inheritDoc}
1418 */
1419 public void internalFrameClosing(InternalFrameEvent e) {
1420 getHandler().internalFrameClosing(e);
1421 }
1422
1423 /**
1424 * {@inheritDoc}
1425 */
1426 public void internalFrameClosed(InternalFrameEvent e) {
1427 getHandler().internalFrameClosed(e);
1428 }
1429
1430 /**
1431 * {@inheritDoc}
1432 */
1433 public void internalFrameOpened(InternalFrameEvent e) {
1434 getHandler().internalFrameOpened(e);
1435 }
1436
1437 /**
1438 * {@inheritDoc}
1439 */
1440 public void internalFrameIconified(InternalFrameEvent e) {
1441 getHandler().internalFrameIconified(e);
1442 }
1443
1444 /**
1445 * {@inheritDoc}
1446 */
1447 public void internalFrameDeiconified(InternalFrameEvent e) {
1448 getHandler().internalFrameDeiconified(e);
1449 }
1450
1451 /**
1452 * {@inheritDoc}
1453 */
1454 public void internalFrameActivated(InternalFrameEvent e) {
1455 getHandler().internalFrameActivated(e);
1456 }
1457
1458 /**
1459 * {@inheritDoc}
1460 */
1461 public void internalFrameDeactivated(InternalFrameEvent e) {
1462 getHandler().internalFrameDeactivated(e);
1463 }
1464 }
1465
1466 private class Handler implements ComponentListener, InternalFrameListener,
1467 LayoutManager, MouseInputListener, PropertyChangeListener,
1468 WindowFocusListener, SwingConstants {
1469
1470 public void windowGainedFocus(WindowEvent e) {
1471 }
1472
1473 public void windowLostFocus(WindowEvent e) {
1474 // Cancel a resize which may be in progress, when a
1475 // WINDOW_LOST_FOCUS event occurs, which may be
1476 // caused by an Alt-Tab or a modal dialog popup.
1477 cancelResize();
1478 }
1479
1480 // ComponentHandler methods
|