001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Vadim L. Bogdanov
020: * @version $Revision$
021: */package javax.swing.plaf.metal;
022:
023: import java.awt.Frame;
024: import java.awt.Insets;
025: import java.awt.Toolkit;
026: import java.awt.Window;
027:
028: import java.awt.event.ActionEvent;
029: import java.awt.event.WindowEvent;
030: import java.awt.event.WindowAdapter;
031: import java.beans.PropertyChangeEvent;
032: import java.beans.PropertyChangeListener;
033:
034: import javax.swing.AbstractAction;
035: import javax.swing.ImageIcon;
036: import javax.swing.JFrame;
037: import javax.swing.JMenu;
038: import javax.swing.JRootPane;
039: import javax.swing.SwingUtilities;
040: import javax.swing.UIManager;
041:
042: import org.apache.harmony.x.swing.StringConstants;
043: import org.apache.harmony.x.swing.TitlePaneInternals;
044: import org.apache.harmony.x.swing.Utilities;
045:
046: /**
047: * This class implements the metal title pane for top level containers.
048: *
049: */
050: final class MetalRootPaneTitlePane extends MetalInternalFrameTitlePane {
051:
052: private class WindowStateHandler extends WindowAdapter {
053: public void windowActivated(final WindowEvent e) {
054: repaintRootPaneDecorations();
055: }
056:
057: public void windowDeactivated(final WindowEvent e) {
058: repaintRootPaneDecorations();
059: }
060:
061: public void windowStateChanged(final WindowEvent e) {
062: setButtonIcons();
063: enableActions();
064: }
065:
066: private void repaintRootPaneDecorations() {
067: repaint();
068:
069: Insets insets = rootPane.getInsets();
070: rootPane.repaint(0, 0, rootPane.getWidth(), insets.top);
071: rootPane.repaint(0, insets.top, insets.left, rootPane
072: .getHeight()
073: - insets.bottom - insets.top);
074: rootPane.repaint(0, rootPane.getHeight() - insets.bottom,
075: rootPane.getWidth(), insets.bottom);
076: rootPane.repaint(rootPane.getWidth() - insets.right,
077: insets.top, insets.right, rootPane.getHeight()
078: - insets.bottom - insets.top);
079: }
080: }
081:
082: private class PropertyChangeHandler implements
083: PropertyChangeListener {
084: public void propertyChange(final PropertyChangeEvent e) {
085: if ("title".equals(e.getPropertyName())) {
086: revalidate();
087: repaint();
088: } else if (StringConstants.ICON_IMAGE_PROPERTY.equals(e
089: .getPropertyName())) {
090: ImageIcon icon = frame.getIconImage() == null ? null
091: : new ImageIcon(frame.getIconImage());
092: internals.setFrameIcon(icon);
093: revalidate();
094: repaint();
095: }
096: }
097: }
098:
099: private class IconifyAction extends AbstractAction {
100: private IconifyAction() {
101: putValue(SMALL_ICON, iconIcon);
102: }
103:
104: public void actionPerformed(final ActionEvent e) {
105: if (frame != null) {
106: frame.setExtendedState(frame.getExtendedState()
107: | JFrame.ICONIFIED);
108: }
109: // if (frame.isIconifiable()) {
110: // try {
111: // // removed in 1.5
112: // //if (frame.isMaximum()) {
113: // // frame.setMaximum(false);
114: // //}
115: // frame.setIcon(!frame.isIcon());
116: // } catch (PropertyVetoException v) {
117: // }
118: // }
119: }
120: }
121:
122: private class CloseAction extends AbstractAction {
123: private CloseAction() {
124: putValue(SMALL_ICON, closeIcon);
125: }
126:
127: public void actionPerformed(final ActionEvent e) {
128: window.dispatchEvent(new WindowEvent(window,
129: WindowEvent.WINDOW_CLOSING));
130: }
131: }
132:
133: private class MaximizeAction extends AbstractAction {
134: private MaximizeAction() {
135: putValue(SMALL_ICON, maxIcon);
136: }
137:
138: public void actionPerformed(final ActionEvent e) {
139: if (Utilities.isMaximumFrame(window)) {
140: frame.setExtendedState(JFrame.NORMAL);
141: } else {
142: frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
143: }
144: }
145: }
146:
147: private class RestoreAction extends AbstractAction {
148: private RestoreAction() {
149: putValue(SMALL_ICON, minIcon);
150: }
151:
152: public void actionPerformed(final ActionEvent e) {
153: if (frame != null) {
154: frame.setExtendedState(JFrame.NORMAL);
155: }
156: }
157: }
158:
159: private JRootPane rootPane;
160: private WindowAdapter windowListener;
161:
162: /**
163: * The window that contains the <code>rootPane</code>.
164: */
165: private Window window;
166:
167: /**
168: * If the window is actually JFrame, it is also stored in this field.
169: */
170: private JFrame frame;
171:
172: private boolean isIconifiable;
173: private boolean isClosable;
174: private boolean isMaximizable;
175:
176: // system menu items text
177: private String closeButtonText;
178: private String maxButtonText;
179: private String minButtonText;
180: private String restoreButtonText;
181:
182: // mnemonics
183: private int closeButtonMnemonic;
184: private int minButtonMnemonic;
185: private int maxButtonMnemonic;
186: private int restoreButtonMnemonic;
187:
188: public MetalRootPaneTitlePane(final JRootPane root) {
189: super (null);
190: rootPane = root;
191:
192: window = SwingUtilities.getWindowAncestor(root);
193: if (window instanceof JFrame) {
194: frame = (JFrame) window;
195: }
196: installInternals();
197:
198: installTitlePane();
199: }
200:
201: protected void installTitlePane() {
202: loadWindowProperties();
203: super .installTitlePane();
204: }
205:
206: void uninstallTitlePane() {
207: uninstallListeners();
208: uninstallDefaults();
209: }
210:
211: protected void installDefaults() {
212: // window menu labels
213: closeButtonText = UIManager
214: .getString("MetalTitlePane.closeTitle");
215: maxButtonText = UIManager
216: .getString("MetalTitlePane.maximizeTitle");
217: minButtonText = UIManager
218: .getString("MetalTitlePane.iconifyTitle");
219: restoreButtonText = UIManager
220: .getString("MetalTitlePane.restoreTitle");
221:
222: // mnemonics
223: closeButtonMnemonic = UIManager
224: .getInt("MetalTitlePane.closeMnemonic");
225: minButtonMnemonic = UIManager
226: .getInt("MetalTitlePane.iconifyMnemonic");
227: maxButtonMnemonic = UIManager
228: .getInt("MetalTitlePane.maximizeMnemonic");
229: restoreButtonMnemonic = UIManager
230: .getInt("MetalTitlePane.restoreMnemonic");
231:
232: // icons
233: closeIcon = UIManager.getIcon("InternalFrame.closeIcon");
234: maxIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
235: minIcon = UIManager.getIcon("InternalFrame.minimizeIcon");
236: iconIcon = UIManager.getIcon("InternalFrame.iconifyIcon");
237: internals.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
238:
239: // colors
240: installColors();
241:
242: // font
243: setFont(UIManager.getFont("InternalFrame.titleFont"));
244: }
245:
246: private void installColors() {
247: switch (rootPane.getWindowDecorationStyle()) {
248: case JRootPane.ERROR_DIALOG:
249: selectedTitleColor = UIManager
250: .getColor("OptionPane.errorDialog.titlePane.background");
251: selectedTextColor = UIManager
252: .getColor("OptionPane.errorDialog.titlePane.foreground");
253: selectedShadowColor = UIManager
254: .getColor("OptionPane.errorDialog.titlePane.shadow");
255: break;
256:
257: case JRootPane.QUESTION_DIALOG:
258: case JRootPane.COLOR_CHOOSER_DIALOG:
259: case JRootPane.FILE_CHOOSER_DIALOG:
260: selectedTitleColor = UIManager
261: .getColor("OptionPane.questionDialog.titlePane.background");
262: selectedTextColor = UIManager
263: .getColor("OptionPane.questionDialog.titlePane.foreground");
264: selectedShadowColor = UIManager
265: .getColor("OptionPane.questionDialog.titlePane.shadow");
266: break;
267:
268: case JRootPane.WARNING_DIALOG:
269: selectedTitleColor = UIManager
270: .getColor("OptionPane.warningDialog.titlePane.background");
271: selectedTextColor = UIManager
272: .getColor("OptionPane.warningDialog.titlePane.foreground");
273: selectedShadowColor = UIManager
274: .getColor("OptionPane.warningDialog.titlePane.shadow");
275: break;
276:
277: default:
278: selectedTitleColor = UIManager
279: .getColor("InternalFrame.activeTitleBackground");
280: selectedTextColor = UIManager
281: .getColor("InternalFrame.activeTitleForeground");
282: selectedShadowColor = MetalLookAndFeel
283: .getPrimaryControlDarkShadow();
284: }
285:
286: notSelectedTitleColor = UIManager
287: .getColor("InternalFrame.inactiveTitleBackground");
288: notSelectedTextColor = UIManager
289: .getColor("InternalFrame.inactiveTitleForeground");
290: notSelectedShadowColor = MetalLookAndFeel
291: .getControlDarkShadow();
292: }
293:
294: void updateTitlePaneProperties() {
295: installColors();
296: loadWindowProperties();
297: addSubComponents();
298: installListeners();
299: }
300:
301: protected void uninstallDefaults() {
302: // no need to uninstall anything because
303: // the title pane is replaced while changing L&F
304: super .uninstallDefaults();
305: }
306:
307: protected PropertyChangeListener createPropertyChangeListener() {
308: return new PropertyChangeHandler();
309: }
310:
311: protected void installListeners() {
312: if (propertyChangeListener == null) {
313: propertyChangeListener = createPropertyChangeListener();
314: }
315:
316: if (windowListener == null) {
317: windowListener = createWindowStateListener();
318: }
319:
320: if (window != null) {
321: window.addPropertyChangeListener(propertyChangeListener);
322: window.addWindowListener(windowListener);
323: window.addWindowStateListener(windowListener);
324: }
325: }
326:
327: protected void uninstallListeners() {
328: window.removePropertyChangeListener(propertyChangeListener);
329: window.removeWindowListener(windowListener);
330: window.removeWindowStateListener(windowListener);
331: }
332:
333: private void loadWindowProperties() {
334: if (rootPane.getWindowDecorationStyle() == JRootPane.FRAME) {
335: Toolkit toolkit = Toolkit.getDefaultToolkit();
336: isIconifiable = toolkit
337: .isFrameStateSupported(Frame.ICONIFIED);
338: isClosable = true;
339: isMaximizable = toolkit
340: .isFrameStateSupported(Frame.MAXIMIZED_BOTH);
341: internals.hasMenuBar = true;
342: } else {
343: isIconifiable = false;
344: isClosable = true;
345: isMaximizable = false;
346: internals.hasMenuBar = false;
347: }
348: }
349:
350: private void installInternals() {
351: internals.setWindow(window);
352: }
353:
354: protected void setButtonIcons() {
355: closeButton.setAction(closeAction);
356: iconButton.setAction(iconifyAction);
357:
358: if (Utilities.isMaximumFrame(window)) {
359: maxButton.setAction(restoreAction);
360: } else {
361: maxButton.setAction(maximizeAction);
362: }
363: }
364:
365: private WindowStateHandler createWindowStateListener() {
366: return new WindowStateHandler();
367: }
368:
369: protected void assembleSystemMenu() {
370: windowMenu = createSystemMenu();
371: internals.setWindowMenu(windowMenu);
372: addSystemMenuItems(windowMenu);
373:
374: menuBar = createSystemMenuBar();
375: menuBar.add(windowMenu);
376: }
377:
378: protected void addSystemMenuItems(final JMenu menu) {
379: menu.add(TitlePaneInternals.createMenuItem(restoreAction,
380: restoreButtonText, restoreButtonMnemonic));
381: menu.add(TitlePaneInternals.createMenuItem(iconifyAction,
382: minButtonText, minButtonMnemonic));
383: menu.add(TitlePaneInternals.createMenuItem(maximizeAction,
384: maxButtonText, maxButtonMnemonic));
385:
386: menu.addSeparator();
387: menu.add(TitlePaneInternals.createMenuItem(closeAction,
388: closeButtonText, closeButtonMnemonic));
389: }
390:
391: protected void addSubComponents() {
392: if (internals.hasMenuBar && !this .isAncestorOf(menuBar)) {
393: add(menuBar);
394: } else if (!internals.hasMenuBar && this .isAncestorOf(menuBar)) {
395: remove(menuBar);
396: }
397:
398: if (isIconifiable && !this .isAncestorOf(iconButton)) {
399: add(iconButton);
400: } else if (!isIconifiable && this .isAncestorOf(iconButton)) {
401: remove(iconButton);
402: }
403:
404: if (isMaximizable && !this .isAncestorOf(maxButton)) {
405: add(maxButton);
406: } else if (!isMaximizable && this .isAncestorOf(maxButton)) {
407: remove(maxButton);
408: }
409:
410: if (isClosable && !this .isAncestorOf(closeButton)) {
411: add(closeButton);
412: } else if (!isClosable && this .isAncestorOf(closeButton)) {
413: remove(closeButton);
414: }
415: }
416:
417: protected void createActions() {
418: closeAction = new CloseAction();
419: iconifyAction = new IconifyAction();
420: maximizeAction = new MaximizeAction();
421: restoreAction = new RestoreAction();
422: }
423:
424: protected void enableActions() {
425: restoreAction.setEnabled(Utilities.isMaximumFrame(window));
426: maximizeAction.setEnabled(!Utilities.isMaximumFrame(window));
427: }
428: }
|