titlepane.java
来自「用于java swing的皮肤软件」· Java 代码 · 共 1,126 行 · 第 1/2 页
JAVA
1,126 行
package com.digitprop.tonic;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import java.util.Locale;
/** Manages the Look and Feel of a window title bar.
*
* @author Markus Fischer
*
* <p>This software is under the <a href="http://www.gnu.org/copyleft/lesser.html" target="_blank">GNU Lesser General Public License</a>
*/
/*
* ------------------------------------------------------------------------
* Copyright (C) 2004 Markus Fischer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* You can contact the author at:
* Markus Fischer
* www.digitprop.com
* info@digitprop.com
* ------------------------------------------------------------------------
*/
class TitlePane extends JComponent
{
private static final Border handyEmptyBorder = new EmptyBorder(0, 0, 0, 0);
private static final int IMAGE_HEIGHT = 16;
private static final int IMAGE_WIDTH = 16;
/** PropertyChangeListener added to the JRootPane. */
private PropertyChangeListener propertyChangeListener;
/** JMenuBar, typically renders the system menu items. */
private JMenuBar menuBar;
/** Action used to close the Window. */
private Action closeAction;
/** Action used to iconify the Frame. */
private Action iconifyAction;
/** Action to restore the Frame size. */
private Action restoreAction;
/** Action to restore the Frame size. */
private Action maximizeAction;
/** Button used to maximize or restore the Frame. */
private JButton toggleButton;
/** Button used to maximize or restore the Frame. */
private JButton iconifyButton;
/** Button used to maximize or restore the Frame. */
private JButton closeButton;
/** Icon used for toggleButton when window is normal size. */
private Icon maximizeIcon;
/** Icon used for toggleButton when window is maximized. */
private Icon minimizeIcon;
/** Listens for changes in the state of the Window listener to
* update the state of the widgets.
*/
private WindowListener windowListener;
/** Window we're currently in. */
private Window window;
/** JRootPane rendering for. */
private JRootPane rootPane;
/** Room remaining in title for bumps. */
private int buttonsWidth;
/** Buffered Frame.state property. As state isn't bound, this is
* kept to determine when to avoid updating widgets.
*/
private int state;
/** The RootPaneUI instance that created us. */
private RootPaneUI rootPaneUI;
// Colors
private Color inactiveBackground=UIManager.getColor("inactiveCaption");
private Color inactiveForeground=UIManager.getColor("inactiveCaptionText");
private Color inactiveShadow = UIManager.getColor("inactiveCaptionBorder");
private Color activeBumpsHighlight=TonicLookAndFeel.getPrimaryControlHighlight();
private Color activeBumpsShadow=TonicLookAndFeel.getPrimaryControlDarkShadow();
private Color activeBackground=null;
private Color activeForeground=null;
private Color activeShadow=null;
public TitlePane(JRootPane root, RootPaneUI ui)
{
this.rootPane = root;
rootPaneUI = ui;
state = -1;
installSubcomponents();
determineColors();
installDefaults();
setLayout(createLayout());
}
/**
* Uninstalls the necessary state.
*/
private void uninstall()
{
uninstallListeners();
window = null;
removeAll();
}
/**
* Installs the necessary listeners.
*/
private void installListeners()
{
if (window != null)
{
windowListener = createWindowListener();
window.addWindowListener(windowListener);
propertyChangeListener = createWindowPropertyChangeListener();
window.addPropertyChangeListener(propertyChangeListener);
}
}
/**
* Uninstalls the necessary listeners.
*/
private void uninstallListeners()
{
if (window != null)
{
window.removeWindowListener(windowListener);
window.removePropertyChangeListener(propertyChangeListener);
}
}
/**
* Returns the <code>WindowListener</code> to add to the <code>Window</code>.
*/
private WindowListener createWindowListener()
{
return new WindowHandler();
}
/**
* Returns the <code>PropertyChangeListener</code> to install on the
* <code>Window</code>.
*/
private PropertyChangeListener createWindowPropertyChangeListener()
{
return new PropertyChangeHandler();
}
/**
* Returns the <code>JRootPane</code> this was created for.
*/
public JRootPane getRootPane()
{
return rootPane;
}
/**
* Returns the decoration style of the <code>JRootPane</code>.
*/
private int getWindowDecorationStyle()
{
return getRootPane().getWindowDecorationStyle();
}
public void addNotify()
{
super.addNotify();
uninstallListeners();
window = SwingUtilities.getWindowAncestor(this);
if (window != null)
{
if (window instanceof Frame)
{
setState(((Frame) window).getExtendedState());
}
else
{
setState(0);
}
setActive(window.isActive());
installListeners();
}
}
public void removeNotify()
{
super.removeNotify();
uninstallListeners();
window = null;
}
/**
* Adds any sub-Components contained in the <code>MetalTitlePane</code>.
*/
private void installSubcomponents()
{
if (getWindowDecorationStyle() == JRootPane.FRAME)
{
createActions();
menuBar = createMenuBar();
add(menuBar);
createButtons();
add(iconifyButton);
add(toggleButton);
add(closeButton);
}
}
/**
* Determines the Colors to draw with.
*/
private void determineColors()
{
switch (getWindowDecorationStyle())
{
case JRootPane.FRAME :
activeBackground = UIManager.getColor("activeCaption");
activeForeground = UIManager.getColor("activeCaptionText");
activeShadow = UIManager.getColor("activeCaptionBorder");
break;
case JRootPane.ERROR_DIALOG :
activeBackground =
UIManager.getColor(
"OptionPane.errorDialog.titlePane.background");
activeForeground =
UIManager.getColor(
"OptionPane.errorDialog.titlePane.foreground");
activeShadow =
UIManager.getColor(
"OptionPane.errorDialog.titlePane.shadow");
break;
case JRootPane.QUESTION_DIALOG :
case JRootPane.COLOR_CHOOSER_DIALOG :
case JRootPane.FILE_CHOOSER_DIALOG :
activeBackground =
UIManager.getColor(
"OptionPane.questionDialog.titlePane.background");
activeForeground =
UIManager.getColor(
"OptionPane.questionDialog.titlePane.foreground");
activeShadow =
UIManager.getColor(
"OptionPane.questionDialog.titlePane.shadow");
break;
case JRootPane.WARNING_DIALOG :
activeBackground =
UIManager.getColor(
"OptionPane.warningDialog.titlePane.background");
activeForeground =
UIManager.getColor(
"OptionPane.warningDialog.titlePane.foreground");
activeShadow =
UIManager.getColor(
"OptionPane.warningDialog.titlePane.shadow");
break;
case JRootPane.PLAIN_DIALOG :
case JRootPane.INFORMATION_DIALOG :
default :
activeBackground = UIManager.getColor("activeCaption");
activeForeground = UIManager.getColor("activeCaptionText");
activeShadow = UIManager.getColor("activeCaptionBorder");
break;
}
}
/**
* Installs the fonts and necessary properties on the MetalTitlePane.
*/
private void installDefaults()
{
setFont(UIManager.getFont("InternalFrame.titleFont", getLocale()));
}
/**
* Uninstalls any previously installed UI values.
*/
private void uninstallDefaults()
{
}
/**
* Returns the <code>JMenuBar</code> displaying the appropriate system
* menu items.
*/
protected JMenuBar createMenuBar()
{
menuBar = new SystemMenuBar();
menuBar.setOpaque(false);
menuBar.setFocusable(false);
menuBar.setBorderPainted(true);
menuBar.add(createMenu());
return menuBar;
}
/**
* Closes the Window.
*/
private void close()
{
Window window = getWindow();
if (window != null)
{
window.dispatchEvent(
new WindowEvent(window, WindowEvent.WINDOW_CLOSING));
}
}
/**
* Iconifies the Frame.
*/
private void iconify()
{
Frame frame = getFrame();
if (frame != null)
{
frame.setExtendedState(state | Frame.ICONIFIED);
}
}
/**
* Maximizes the Frame.
*/
private void maximize()
{
Frame frame = getFrame();
if (frame != null)
{
frame.setExtendedState(state | Frame.MAXIMIZED_BOTH);
}
}
/**
* Restores the Frame size.
*/
private void restore()
{
Frame frame = getFrame();
if (frame == null)
{
return;
}
if ((state & Frame.ICONIFIED) != 0)
{
frame.setExtendedState(state & ~Frame.ICONIFIED);
}
else
{
frame.setExtendedState(state & ~Frame.MAXIMIZED_BOTH);
}
}
/**
* Create the <code>Action</code> s that get associated with the buttons
* and menu items.
*/
private void createActions()
{
closeAction = new CloseAction();
iconifyAction = new IconifyAction();
restoreAction = new RestoreAction();
maximizeAction = new MaximizeAction();
}
/**
* Returns the <code>JMenu</code> displaying the appropriate menu items
* for manipulating the Frame.
*/
private JMenu createMenu()
{
JMenu menu = new JMenu("");
if (getWindowDecorationStyle() == JRootPane.FRAME)
{
addMenuItems(menu);
}
return menu;
}
/**
* Adds the necessary <code>JMenuItem</code> s to the passed in menu.
*/
private void addMenuItems(JMenu menu)
{
Locale locale = getRootPane().getLocale();
JMenuItem mi = menu.add(restoreAction);
int mnemonic = TonicUtils.getInt("MetalTitlePane.restoreMnemonic", -1);
if (mnemonic != -1)
{
mi.setMnemonic(mnemonic);
}
mi = menu.add(iconifyAction);
mnemonic = TonicUtils.getInt("MetalTitlePane.iconifyMnemonic", -1);
if (mnemonic != -1)
{
mi.setMnemonic(mnemonic);
}
if (Toolkit
.getDefaultToolkit()
.isFrameStateSupported(Frame.MAXIMIZED_BOTH))
{
mi = menu.add(maximizeAction);
mnemonic = TonicUtils.getInt("MetalTitlePane.maximizeMnemonic", -1);
if (mnemonic != -1)
{
mi.setMnemonic(mnemonic);
}
}
menu.add(new JSeparator());
mi = menu.add(closeAction);
mnemonic = TonicUtils.getInt("MetalTitlePane.closeMnemonic", -1);
if (mnemonic != -1)
{
mi.setMnemonic(mnemonic);
}
}
/**
* Returns a <code>JButton</code> appropriate for placement on the
* TitlePane.
*/
private JButton createTitleButton()
{
JButton button = new JButton();
button.setFocusPainted(false);
button.setFocusable(false);
button.setOpaque(false);
return button;
}
/**
* Creates the Buttons that will be placed on the TitlePane.
*/
private void createButtons()
{
maximizeIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
minimizeIcon = UIManager.getIcon("InternalFrame.minimizeIcon");
closeButton = createTitleButton();
closeButton.setAction(closeAction);
closeButton.setText(null);
closeButton.putClientProperty("paintActive", Boolean.TRUE);
closeButton.setBorder(handyEmptyBorder);
closeButton.getAccessibleContext().setAccessibleName("Close");
closeButton.setIcon(UIManager.getIcon("InternalFrame.closeIcon"));
closeButton.setBackground(Color.WHITE);
iconifyButton = createTitleButton();
iconifyButton.setAction(iconifyAction);
iconifyButton.setText(null);
iconifyButton.putClientProperty("paintActive", Boolean.TRUE);
iconifyButton.setBorder(handyEmptyBorder);
iconifyButton.getAccessibleContext().setAccessibleName("Iconify");
iconifyButton.setIcon(UIManager.getIcon("InternalFrame.iconifyIcon"));
iconifyButton.setBackground(Color.WHITE);
toggleButton = createTitleButton();
toggleButton.setAction(restoreAction);
toggleButton.putClientProperty("paintActive", Boolean.TRUE);
toggleButton.setBorder(handyEmptyBorder);
toggleButton.getAccessibleContext().setAccessibleName("Maximize");
toggleButton.setIcon(maximizeIcon);
toggleButton.setBackground(Color.WHITE);
}
/**
* Returns the <code>LayoutManager</code> that should be installed on the
* <code>MetalTitlePane</code>.
*/
private LayoutManager createLayout()
{
return new TitlePaneLayout();
}
/**
* Updates state dependant upon the Window's active state.
*/
private void setActive(boolean isActive)
{
if (getWindowDecorationStyle() == JRootPane.FRAME)
{
Boolean activeB = isActive ? Boolean.TRUE : Boolean.FALSE;
iconifyButton.putClientProperty("paintActive", activeB);
closeButton.putClientProperty("paintActive", activeB);
toggleButton.putClientProperty("paintActive", activeB);
}
// Repaint the whole thing as the Borders that are used have
// different colors for active vs inactive
getRootPane().repaint();
}
/**
* Sets the state of the Window.
*/
private void setState(int state)
{
setState(state, false);
}
/**
* Sets the state of the window. If <code>updateRegardless</code> is true
* and the state has not changed, this will update anyway.
*/
private void setState(int state, boolean updateRegardless)
{
Window w = getWindow();
if (w != null && getWindowDecorationStyle() == JRootPane.FRAME)
{
if (this.state == state && !updateRegardless)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?