/*
* Copyright (c) 2009 Kathryn Huxtable and Kenneth Orr.
*
* This file is part of the SeaGlass Pluggable Look and Feel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Id: SeaGlassInternalFrameTitlePane.java 1595 2011-08-09 20:33:48Z rosstauscher@gmx.de $
*/
package com.seaglasslookandfeel.component;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import javax.accessibility.AccessibleContext;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.UIManager;
import javax.swing.event.InternalFrameEvent;
import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.synth.ColorType;
import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthGraphicsUtils;
import javax.swing.plaf.synth.SynthStyle;
import sun.swing.SwingUtilities2;
import com.seaglasslookandfeel.SeaGlassContext;
import com.seaglasslookandfeel.SeaGlassLookAndFeel;
import com.seaglasslookandfeel.ui.SeaglassUI;
/**
* Manage a title bar for an internal frame.
*
* <p>Copied from SynthInternalFrameTitlePane, which is package local.</p>
*
* @see javax.swing.plaf.synth.SynthInternalFrameTitlePane
*/
public class SeaGlassInternalFrameTitlePane extends JComponent implements SeaglassUI, PropertyChangeListener {
private static final long serialVersionUID = 6852740789566412690L;
private static final String CLOSE_CMD = UIManager.getString("InternalFrameTitlePane.closeButtonText");
private static final String ICONIFY_CMD = UIManager.getString("InternalFrameTitlePane.minimizeButtonText");
private static final String RESTORE_CMD = UIManager.getString("InternalFrameTitlePane.restoreButtonText");
private static final String MAXIMIZE_CMD = UIManager.getString("InternalFrameTitlePane.maximizeButtonText");
private static final String MOVE_CMD = UIManager.getString("InternalFrameTitlePane.moveButtonText");
private static final String SIZE_CMD = UIManager.getString("InternalFrameTitlePane.sizeButtonText");
// Basic
private JButton iconButton;
private JButton maxButton;
private JButton closeButton;
private JMenu windowMenu;
private JInternalFrame frame;
private Action closeAction;
private Action maximizeAction;
private Action iconifyAction;
private Action restoreAction;
private Action moveAction;
private Action sizeAction;
private String closeButtonToolTip;
private String iconButtonToolTip;
private String restoreButtonToolTip;
private String maxButtonToolTip;
// Synth
private JPopupMenu systemPopupMenu;
private JButton menuButton;
private SynthStyle style;
private int titleSpacing;
/**
* Creates a new SeaGlassInternalFrameTitlePane object.
*
* @param f the internal frame containing the title pane.
*/
public SeaGlassInternalFrameTitlePane(JInternalFrame f) {
frame = f;
installTitlePane();
}
/**
* @see javax.swing.JComponent#getUIClassID()
*/
public String getUIClassID() {
return "InternalFrameTitlePaneUI";
}
/**
* @see SeaglassUI#getContext(javax.swing.JComponent)
*/
public SeaGlassContext getContext(JComponent c) {
return getContext(c, getComponentState(c));
}
/**
* Get a SynthContext for the title pane.
*
* @param c the title pane.
* @param state the state.
*
* @return the SynthContext describing the component.
*/
public SeaGlassContext getContext(JComponent c, int state) {
return SeaGlassContext.getContext(SeaGlassContext.class, c, SeaGlassLookAndFeel.getRegion(c), style, state);
}
/**
* Get the state for the component.
*
* @param c the component.
*
* @return the state for the component.
*/
private int getComponentState(JComponent c) {
if (frame != null) {
if (frame.isSelected()) {
return SELECTED;
}
}
return SeaGlassLookAndFeel.getComponentState(c);
}
/**
* Install the UI and listeners for the title pane.
*/
private void installTitlePane() {
installDefaults();
installListeners();
createActions();
enableActions();
createActionMap();
setLayout(createLayout());
assembleSystemMenu();
createButtons();
addSubComponents();
}
/**
* Add the button subcomponents to the title pane.
*/
private void addSubComponents() {
menuButton.setName("InternalFrameTitlePane.menuButton");
iconButton.setName("InternalFrameTitlePane.iconifyButton");
maxButton.setName("InternalFrameTitlePane.maximizeButton");
closeButton.setName("InternalFrameTitlePane.closeButton");
add(menuButton);
add(iconButton);
add(maxButton);
add(closeButton);
}
/**
* Create the actions for the buttons.
*/
private void createActions() {
maximizeAction = new MaximizeAction();
iconifyAction = new IconifyAction();
closeAction = new CloseAction();
restoreAction = new RestoreAction();
moveAction = new MoveAction();
sizeAction = new SizeAction();
}
/**
* Create the action map for the system menu.
*
* @return the action map.
*/
ActionMap createActionMap() {
ActionMap map = new ActionMapUIResource();
map.put("showSystemMenu", new ShowSystemMenuAction(true));
map.put("hideSystemMenu", new ShowSystemMenuAction(false));
return map;
}
/**
* Install the listeners on the title pane.
*/
protected void installListeners() {
frame.addPropertyChangeListener(this);
addPropertyChangeListener(this);
}
/**
* Uninstall the listeners from the title pane.
*/
protected void uninstallListeners() {
frame.removePropertyChangeListener(this);
removePropertyChangeListener(this);
}
/**
* Install defaults, update the Synth Style.
*/
private void installDefaults() {
// Basic
setFont(UIManager.getFont("InternalFrame.titleFont"));
closeButtonToolTip = UIManager.getString("InternalFrame.closeButtonToolTip");
iconButtonToolTip = UIManager.getString("InternalFrame.iconButtonToolTip");
restoreButtonToolTip = UIManager.getString("InternalFrame.restoreButtonToolTip");
maxButtonToolTip = UIManager.getString("InternalFrame.maxButtonToolTip");
// Synth
updateStyle(this);
}
/**
* Uninstall the defaults.
*/
public void uninstallDefaults() {
SeaGlassContext context = getContext(this, ENABLED);
style.uninstallDefaults(context);
context.dispose();
style = null;
JInternalFrame.JDesktopIcon di = frame.getDesktopIcon();
if (di != null && di.getComponentPopupMenu() == systemPopupMenu) {
// Release link to systemMenu from the JInternalFrame
di.setComponentPopupMenu(null);
}
}
/**
* Update the Synth Style.
*
* @param c the component.
*/
private void updateStyle(JComponent c) {
SeaGlassContext context = getContext(this, ENABLED);
SynthStyle oldStyle = style;
style = SeaGlassLookAndFeel.updateStyle(context, this);
if (style != oldStyle) {
titleSpacing = style.getInt(context, "InternalFrameTitlePane.titleSpacing", 2);
}
context.dispose();
}
/**
* Create the buttons and add action listeners.
*/
private void createButtons() {
iconButton = new NoFocusButton("InternalFrameTitlePane.iconifyButtonAccessibleName");
iconButton.addActionListener(iconifyAction);
if (iconButtonToolTip != null && iconButtonToolTip.length() != 0) {
iconButton.setToolTipText(iconButtonToolTip);
}
maxButton = new NoFocusButton("InternalFrameTitlePane.maximizeButtonAccessibleName");
maxButton.addActionListener(maximizeAction);
closeButton = new NoFocusButton("InternalFrameTitlePane.closeButtonAccessibleName");
closeButton.addActionListener(closeAction);
if (closeButtonToolTip != null && closeButtonToolTip.length() != 0) {
closeButton.setToolTipText(closeButtonToolTip);
}
setButtonTooltips();
}
/**
* Set the buttons' tooltip text.
*/
private void setButtonTooltips() {
if (frame.isIcon()) {
if (restoreButtonToolTip != null && restoreButtonToolTip.length() != 0) {
iconButton.setToolTipText(restoreButtonToolTip);
}
if (maxButtonToolTip != null && maxButtonToolTip.length() != 0) {
maxButton.setToolTipText(maxButtonToolTip);
}
} else if (frame.isMaximum()) {
if (iconButtonToolTip != null && iconButtonToolTip.length() != 0) {
iconButton.setToolTipText(iconButtonToolTip);
}
if (restoreButtonToolTip != null && restoreButtonToolTip.length() != 0) {
maxButton.setToolTipText(restoreButtonToolTip);
}
} else {
if (iconButtonToolTip != null && iconButtonToolTip.length() != 0) {
iconButton.setToolTipText(iconButtonToolTip);
}
if (maxButtonToolTip != null && maxButtonToolTip.length() != 0) {
maxButton.setToolTipText(maxButtonToolTip);
}
}
}
/**
* Create the system menu.
*/
private void assembleSystemMenu() {
systemPopupMenu = new JPopupMenuUIResource();
addSystemMenuItems(systemPopupMenu);
enableActions();
menuButton = new NoFocusButton("InternalFrameTitlePane.menuButtonAccessibleName");
updateMenuIcon();
menuButton.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
try {
frame.setSelected(true);
} catch (PropertyVetoException pve) {
}
showSystemMenu();
}
});
JPopupMenu p = frame.getComponentPopupMenu();
if (p == null || p instanceof UIResource) {
frame.setComponentPopupMenu(systemPopupMenu);
}
if (frame.getDesktopIcon() != null) {
p = frame.getDesktopIcon().getComponentPopupMenu();
if (p == null || p instanceof UIResource) {
frame.getDesktopIcon().setComponentPopupMenu(systemPopupMenu);
}
}
setInheritsPopupMenu(true);
}
/**
* Add the items to the system menu.
*
* @param menu the system menu popup.
*/
private void addSystemMenuItems(JPopupMenu menu) {
// PENDING: this should all be localizable!
JMenuItem mi = (JMenuItem) menu.add(restoreAction);
mi.setMnemonic('R');
mi = (JMenuItem) menu.add(moveAction);
mi.setMnemonic('M');
mi = (JMenuItem) menu.add(sizeAction);
mi.setMnemonic('S');
mi = (JMenuItem) menu.add(iconifyAction);
mi.setMnemonic('n');
mi = (JMenuItem) menu.add(maximizeAction);
mi.setMnemonic('x');
menu.add(new JSeparator());
mi = (JMenuItem) menu.add(closeAction);
mi.setMnemonic('C');
}
/**
* Show the system menu.
*/
private void showSystemMenu() {
Insets insets = frame.getInsets();
if (!frame.isIcon()) {
systemPopupMenu.show(frame, insets.left, getY() + getHeight());
} else {
systemPopupMenu.show(menuButton, getX() - insets.left - insets.right,
getY() - systemPopupMenu.getPreferredSize().height - insets.bottom - insets.top);
}
}
// SeaGlassInternalFrameTitlePane has no UI, we'll invoke paint on it.
/**
* @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
*/
public void paintComponent(Graphics g) {
SeaGlassContext context = getContext(this);
SeaGlassLookAndFeel.update(context, g);
context.getPainter().paintInternalFrameTitlePaneBackground(context, g, 0, 0, getWidth(), getHeight());
paint(context, g);
context.dispose();
}
/**
* Paint the title pane.
*
* @param context the SynthContext to get the component from.
* @param g the Graphics context to paint with.
*/
private void paint(SeaGlassContext context, Graphics g) {
String title = frame.getTitle();
if (title != null) {
SynthStyle style = context.getStyle();
Color color = style.getColor(context, ColorType.TEXT_FOREGROUND);
// TODO style.getColor returns improper color for state? Why?
if ((context.getComponentState() & 512) != 0) {
Object obj = style.get(context, "[WindowFocused].textForeground");
if (obj != null && obj instanceof Color) {
color = (Color) obj;
}
// FIXME The state *still* doesn't get the color right!!!
color = Color.WHITE;
}
g.setColor(color);
g.setFont(style.getFont(context));
// Center text vertically.
FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g);
int baseline = (getHeight() + fm.getAscent() - fm.getLeading() - fm.getDescent()) / 2;
JButton lastButton = null;
if (frame.isIconifiable()) {
lastButton = iconButton;
} else if (frame.isMaximizable()) {
lastButton = maxButton;
} else if (frame.isClosable()) {
lastButton = closeButton;
}
int maxX;
int minX;
boolean ltr = SeaGlassLookAndFeel.isLeftToRight(frame);
if (ltr) {
if (lastButton != null) {
maxX = lastButton.getX() - titleSpacing;
} else {
maxX = frame.getWidth() - frame.getInsets().right - titleSpacing;
}
minX = menuButton.getX() + menuButton.getWidth() + titleSpacing;
} else {
if (lastButton != null) {
minX = lastButton.getX() + lastButton.getWidth() + titleSpacing;
} else {
minX = frame.getInsets().left + titleSpacing;
}
maxX = menuButton.getX() - titleSpacing;
}
String clippedTitle = getTitle(title, fm, maxX - minX);
if (clippedTitle == title) {
int width = style.getGraphicsUtils(context).computeStringWidth(context, g.getFont(), fm, title);
minX = Math.max(minX, (getWidth() - width) / 2);
minX = Math.min(maxX - width, minX);
}
style.getGraphicsUtils(context).paintText(context, g, clippedTitle, minX, baseline - fm.getAscent(), -1);
}
}
/**
* Get the title text, clipped if necessary.
*
* @param text the title text.
* @param fm the font metrics to compute size with.
* @param availTextWidth the available space to display the title in.
*
* @return the text, clipped to fit the available space.
*/
private String getTitle(String text, FontMetrics fm, int availTextWidth) {
return SwingUtilities2.clipStringIfNecessary(frame, fm, text, availTextWidth);
}
/**
* @see SeaglassUI#paintBorder(javax.swing.plaf.synth.SynthContext,
* java.awt.Graphics, int, int, int, int)
*/
public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) {
((SeaGlassContext) context).getPainter().paintInternalFrameTitlePaneBorder(context, g, x, y, w, h);
}
/**
* Create the layout manager for the title pane.
*
* @return the layout manager.
*/
private LayoutManager createLayout() {
SeaGlassContext context = getContext(this);
LayoutManager lm = (LayoutManager) style.get(context, "InternalFrameTitlePane.titlePaneLayout");
context.dispose();
return (lm != null) ? lm : new SeaGlassTitlePaneLayout();
}
/**
* @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getSource() == this) {
if (SeaGlassLookAndFeel.shouldUpdateStyle(evt)) {
updateStyle(this);
}
} else {
// Changes for the internal frame
if (evt.getPropertyName() == JInternalFrame.FRAME_ICON_PROPERTY) {
updateMenuIcon();
}
}
// Basic (from Handler inner class)
String prop = (String) evt.getPropertyName();
if (prop == JInternalFrame.IS_SELECTED_PROPERTY) {
repaint();
return;
}
if (prop == JInternalFrame.IS_ICON_PROPERTY || prop == JInternalFrame.IS_MAXIMUM_PROPERTY) {
setButtonTooltips();
enableActions();
return;
}
if ("closable" == prop) {
if ((Boolean) evt.getNewValue() == Boolean.TRUE) {
add(closeButton);
} else {
remove(closeButton);
}
} else if ("maximizable" == prop) {
if ((Boolean) evt.getNewValue() == Boolean.TRUE) {
add(maxButton);
} else {
remove(maxButton);
}
} else if ("iconable" == prop) {
if ((Boolean) evt.getNewValue() == Boolean.TRUE) {
add(iconButton);
} else {
remove(iconButton);
}
}
enableActions();
revalidate();
repaint();
}
/**
* Resets the menuButton icon to match that of the frame.
*/
private void updateMenuIcon() {
Icon frameIcon = frame.getFrameIcon();
SeaGlassContext context = getContext(this);
if (frameIcon != null) {
Dimension maxSize = (Dimension) context.getStyle().get(context, "InternalFrameTitlePane.maxFrameIconSize");
int maxWidth = 16;
int maxHeight = 16;
if (maxSize != null) {
maxWidth = maxSize.width;
maxHeight = maxSize.height;
}
if ((frameIcon.getIconWidth() > maxWidth || frameIcon.getIconHeight() > maxHeight) && (frameIcon instanceof ImageIcon)) {
frameIcon = new ImageIcon(((ImageIcon) frameIcon).getImage().getScaledInstance(maxWidth, maxHeight, Image.SCALE_SMOOTH));
}
}
context.dispose();
menuButton.setIcon(frameIcon);
}
/**
* Post a WINDOW_CLOSING-like event to the frame, so that it can be treated
* like a regular Frame.
*
* @param frame the internal frame to be closed.
*/
protected void postClosingEvent(JInternalFrame frame) {
InternalFrameEvent e = new InternalFrameEvent(frame, InternalFrameEvent.INTERNAL_FRAME_CLOSING);
// Try posting event, unless there's a SecurityManager.
if (JInternalFrame.class.getClassLoader() == null) {
try {
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e);
return;
} catch (SecurityException se) {
// Use dispatchEvent instead.
}
}
frame.dispatchEvent(e);
}
/**
* Set the enable/disabled state for the buttons.
*/
private void enableActions() {
restoreAction.setEnabled(frame.isMaximum() || frame.isIcon());
maximizeAction.setEnabled((frame.isMaximizable() && !frame.isMaximum() && !frame.isIcon())
|| (frame.isMaximizable() && frame.isIcon()));
iconifyAction.setEnabled(frame.isIconifiable() && !frame.isIcon());
closeAction.setEnabled(frame.isClosable());
sizeAction.setEnabled(false);
moveAction.setEnabled(false);
}
/**
* A special UIResource used for the system menu.
*/
private static class JPopupMenuUIResource extends JPopupMenu implements UIResource {
private static final long serialVersionUID = 4511298062453723303L;
}
/**
* The layout manager for the title pane.
*/
class SeaGlassTitlePaneLayout implements LayoutManager {
/**
* @see java.awt.LayoutManager#addLayoutComponent(java.lang.String, java.awt.Component)
*/
public void addLayoutComponent(String name, Component c) {
}
/**
* @see java.awt.LayoutManager#removeLayoutComponent(java.awt.Component)
*/
public void removeLayoutComponent(Component c) {
}
/**
* @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container)
*/
public Dimension preferredLayoutSize(Container c) {
return minimumLayoutSize(c);
}
/**
* @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
*/
public Dimension minimumLayoutSize(Container c) {
SeaGlassContext context = getContext(SeaGlassInternalFrameTitlePane.this);
int width = 8;
int height = 0;
int buttonCount = 0;
Dimension pref;
if (frame.isClosable()) {
pref = closeButton.getPreferredSize();
width += pref.width;
height = Math.max(pref.height, height);
buttonCount++;
}
if (frame.isMaximizable()) {
pref = maxButton.getPreferredSize();
width += pref.width;
height = Math.max(pref.height, height);
buttonCount++;
}
if (frame.isIconifiable()) {
pref = iconButton.getPreferredSize();
width += pref.width;
height = Math.max(pref.height, height);
buttonCount++;
}
pref = menuButton.getPreferredSize();
width += pref.width;
height = Math.max(pref.height, height);
FontMetrics fm = SeaGlassInternalFrameTitlePane.this.getFontMetrics(getFont());
SynthGraphicsUtils graphicsUtils = context.getStyle().getGraphicsUtils(context);
String frameTitle = frame.getTitle();
int title_w = frameTitle != null ? graphicsUtils.computeStringWidth(context, fm.getFont(), fm, frameTitle)
: 0;
int title_length = frameTitle != null ? frameTitle.length() : 0;
// Leave room for three characters in the title.
if (title_length > 3) {
int subtitle_w = graphicsUtils.computeStringWidth(context, fm.getFont(), fm, frameTitle.substring(0, 3) + "...");
width += (title_w < subtitle_w) ? title_w : subtitle_w;
} else {
width += title_w;
}
height = Math.max(fm.getHeight() + 2, height);
width += titleSpacing + titleSpacing;
Insets insets = getInsets();
height += insets.top + insets.bottom;
width += insets.left + insets.right;
context.dispose();
return new Dimension(width, height);
}
/**
* Determine the position of a button.
*
* @param c the button.
* @param insets the title pane insets.
* @param x the x position of the button.
* @param trailing Are we at the right edge?
*
* @return the modified x position for the button.
*/
private int center(Component c, Insets insets, int x, boolean trailing) {
Dimension pref = c.getPreferredSize();
int width = pref.width;
if (c instanceof JButton && ((JButton) c).getIcon() != null) {
width = ((JButton) c).getIcon().getIconWidth();
}
if (trailing) {
x -= width;
}
int y = 0;
if (c == menuButton) {
// y = insets.top + (getHeight() - insets.top - insets.bottom -
// pref.height) / 2;
}
c.setBounds(x, y, pref.width, pref.height);
if (pref.width > 0) {
if (!trailing) {
return x + width;
}
}
return x;
}
/**
* @see java.awt.LayoutManager#layoutContainer(java.awt.Container)
*/
public void layoutContainer(Container c) {
Insets insets = c.getInsets();
if (SeaGlassLookAndFeel.isLeftToRight(frame)) {
center(menuButton, insets, insets.left + 4, false);
int x = getWidth() - insets.right - 4;
if (frame.isClosable()) {
x = center(closeButton, insets, x, true);
}
if (frame.isMaximizable()) {
x = center(maxButton, insets, x, true);
}
if (frame.isIconifiable()) {
x = center(iconButton, insets, x, true);
}
} else {
center(menuButton, insets, getWidth() - insets.right - 4, true);
int x = insets.left + 4;
if (frame.isClosable()) {
x = center(closeButton, insets, x, false);
}
if (frame.isMaximizable()) {
x = center(maxButton, insets, x, false);
}
if (frame.isIconifiable()) {
x = center(iconButton, insets, x, false);
}
}
}
}
/**
* Handles closing internal frame.
*/
private class CloseAction extends AbstractAction {
private static final long serialVersionUID = 1214165629626107441L;
/**
* Creates a new CloseAction object.
*/
public CloseAction() {
super(CLOSE_CMD);
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent e) {
if (frame.isClosable()) {
frame.doDefaultCloseAction();
}
}
}
/**
* Handles maximizing/restoring internal frame.
*/
private class MaximizeAction extends AbstractAction {
private static final long serialVersionUID = 6286449065315966825L;
/**
* Creates a new MaximizeAction object.
*/
public MaximizeAction() {
super(MAXIMIZE_CMD);
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent evt) {
if (frame.isMaximizable()) {
if (frame.isMaximum() && frame.isIcon()) {
try {
frame.setIcon(false);
} catch (PropertyVetoException e) {
}
} else if (!frame.isMaximum()) {
try {
frame.setMaximum(true);
} catch (PropertyVetoException e) {
}
} else {
try {
frame.setMaximum(false);
} catch (PropertyVetoException e) {
}
}
}
}
}
/**
* Handles iconifying/uniconifying internal frame.
*/
private class IconifyAction extends AbstractAction {
private static final long serialVersionUID = 4337075125371606258L;
/**
* Creates a new IconifyAction object.
*/
public IconifyAction() {
super(ICONIFY_CMD);
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent e) {
if (frame.isIconifiable()) {
if (!frame.isIcon()) {
try {
frame.setIcon(true);
} catch (PropertyVetoException e1) {
}
} else {
try {
frame.setIcon(false);
} catch (PropertyVetoException e1) {
}
}
}
}
}
/**
* Restores internal frame to regular state.
*/
private class RestoreAction extends AbstractAction {
private static final long serialVersionUID = -961768442993544104L;
/**
* Creates a new RestoreAction object.
*/
public RestoreAction() {
super(RESTORE_CMD);
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent evt) {
if (frame.isMaximizable() && frame.isMaximum() && frame.isIcon()) {
try {
frame.setIcon(false);
} catch (PropertyVetoException e) {
}
} else if (frame.isMaximizable() && frame.isMaximum()) {
try {
frame.setMaximum(false);
} catch (PropertyVetoException e) {
}
} else if (frame.isIconifiable() && frame.isIcon()) {
try {
frame.setIcon(false);
} catch (PropertyVetoException e) {
}
}
}
}
/**
* Handles moving internal frame.
*/
private class MoveAction extends AbstractAction {
private static final long serialVersionUID = 7940900832761279111L;
/**
* Creates a new MoveAction object.
*/
public MoveAction() {
super(MOVE_CMD);
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent e) {
// This action is currently undefined
}
}
/**
* Handles showing and hiding the system menu.
*/
private class ShowSystemMenuAction extends AbstractAction {
private static final long serialVersionUID = 4020962135221310152L;
private boolean show; // whether to show the menu
/**
* Creates a new ShowSystemMenuAction object.
*
* @param show the ShowSystemMenuAction object.
*/
public ShowSystemMenuAction(boolean show) {
this.show = show;
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent e) {
if (show) {
windowMenu.doClick();
} else {
windowMenu.setVisible(false);
}
}
}
/**
* Handles resizing internal frame.
*/
private class SizeAction extends AbstractAction {
private static final long serialVersionUID = -1079290485715681580L;
/**
* Creates a new SizeAction object.
*/
public SizeAction() {
super(SIZE_CMD);
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent e) {
// This action is currently undefined
}
}
/**
* Window decoration button class.
*/
private class NoFocusButton extends JButton {
private static final long serialVersionUID = 797986964401472674L;
private String uiKey;
/**
* Creates a new NoFocusButton object.
*
* @param uiKey the UI key for the button properties.
*/
public NoFocusButton(String uiKey) {
setFocusPainted(false);
setMargin(new Insets(0, 0, 0, 0));
setFocusable(false);
this.uiKey = uiKey;
}
/**
* @see java.awt.Component#isFocusTraversable()
*/
public boolean isFocusTraversable() {
return false;
}
/**
* @see javax.swing.JComponent#requestFocus()
*/
public void requestFocus() {
}
/**
* @see javax.swing.JButton#getAccessibleContext()
*/
public AccessibleContext getAccessibleContext() {
AccessibleContext ac = super.getAccessibleContext();
if (uiKey != null) {
ac.setAccessibleName(UIManager.getString(uiKey));
uiKey = null;
}
return ac;
}
}
}