ch.randelshofer.quaqua.QuaquaTitlePane Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Quaqua Show documentation
Show all versions of Quaqua Show documentation
A Mavenisation of the Quaqua Mac OSX Swing Look and Feel (Java library)
Quaqua Look and Feel (C) 2003-2010, Werner Randelshofer.
Mavenisation by Matt Gumbley, DevZendo.org - for problems with
Mavenisation, see Matt; for issues with Quaqua, see the Quaqua home page.
For full license details, see http://randelshofer.ch/quaqua/license.html
The newest version!
/*
* @(#)QuaquaTitlePane.java
* Copyright (c) 2006-2010 Werner Randelshofer, Immensee, Switzerland.
* All rights reserved.
*
* You may not use, copy or modify this file, except in compliance with the
* license agreement you entered into with Werner Randelshofer.
* For details see accompanying license terms.
*/
package ch.randelshofer.quaqua;
import ch.randelshofer.quaqua.color.TextureColor;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import java.awt.geom.*;
/**
* QuaquaTitlePane.
*
* @author Werner Randelshofer
* @version $Id: QuaquaTitlePane.java 361 2010-11-21 11:19:20Z wrandelshofer $
*/
public class QuaquaTitlePane 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 Window.
*/
private PropertyChangeListener windowPropertyListener;
/**
* PropertyChangeListener added to the JRootPane.
*/
private PropertyChangeListener rootPropertyListener;
/**
* 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;
/**
* QuaquaRootPaneUI that created us.
*/
private QuaquaRootPaneUI rootPaneUI;
// Colors
private Color inactiveBackground = UIManager.getColor("inactiveCaption");
private Color inactiveForeground = UIManager.getColor("inactiveCaptionText");
private Color inactiveShadow = new Color(0xb3b3b3);
private Color activeBackground = null;
private Color activeForeground = null;
private Color activeShadow = null;
/* Components used for "arming" the window buttons.
*/
private JComponent armer1, armer2;
public QuaquaTitlePane(JRootPane root, QuaquaRootPaneUI ui) {
this.rootPane = root;
rootPaneUI = ui;
state = -1;
rootPropertyListener = createRootPropertyChangeListener();
rootPane.addPropertyChangeListener(rootPropertyListener);
installSubcomponents();
updateIconsAndTextures();
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);
windowPropertyListener = createWindowPropertyChangeListener();
window.addPropertyChangeListener(windowPropertyListener);
}
}
/**
* Uninstalls the necessary listeners.
*/
private void uninstallListeners() {
if (window != null) {
window.removeWindowListener(windowListener);
window.removePropertyChangeListener(windowPropertyListener);
}
}
/**
* Returns the WindowListener
to add to the
* Window
.
*/
private WindowListener createWindowListener() {
return new WindowHandler();
}
/**
* Returns the PropertyChangeListener
to install on
* the Window
.
*/
private PropertyChangeListener createWindowPropertyChangeListener() {
return new WindowPropertyHandler();
}
/**
* Returns the PropertyChangeListener
to install on
* the Window
.
*/
private PropertyChangeListener createRootPropertyChangeListener() {
return new RootPropertyHandler();
}
/**
* Returns the JRootPane
this was created for.
*/
@Override
public JRootPane getRootPane() {
return rootPane;
}
/**
* Returns the decoration style of the JRootPane
.
*/
private int getWindowDecorationStyle() {
return getRootPane().getWindowDecorationStyle();
}
@Override
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();
}
}
@Override
public void removeNotify() {
super.removeNotify();
uninstallListeners();
window = null;
}
/**
* Adds any sub-Components contained in the QuaquaTitlePane
.
*/
private void installSubcomponents() {
//if (getWindowDecorationStyle() == JRootPane.FRAME) {
createActions();
createButtons();
add(iconifyButton);
add(toggleButton);
add(closeButton);
//}
}
/**
* Installs the fonts and necessary properties on the QuaquaTitlePane.
*/
private void installDefaults() {
// We get the font from the root pane.
//setFont(UIManager.getFont("InternalFrame.titleFont", getLocale()));
// make title pane translucent
}
/**
* Uninstalls any previously installed UI values.
*/
private void uninstallDefaults() {
}
/**
* Closes the Window.
*/
private void close() {
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 Action
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 a JButton
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() {
closeButton = createTitleButton();
closeButton.setAction(closeAction);
closeButton.setText(null);
closeButton.putClientProperty("paintActive", Boolean.TRUE);
closeButton.setBorder(handyEmptyBorder);
closeButton.getAccessibleContext().setAccessibleName("Close");
iconifyButton = createTitleButton();
iconifyButton.setAction(iconifyAction);
iconifyButton.setText(null);
iconifyButton.putClientProperty("paintActive", Boolean.TRUE);
iconifyButton.setBorder(handyEmptyBorder);
iconifyButton.getAccessibleContext().setAccessibleName("Iconify");
toggleButton = createTitleButton();
toggleButton.setAction(restoreAction);
toggleButton.putClientProperty("paintActive", Boolean.TRUE);
toggleButton.setBorder(handyEmptyBorder);
toggleButton.getAccessibleContext().setAccessibleName("Maximize");
armer1 = new JPanel(null);
armer1.setOpaque(false);
armer2 = new JPanel(null);
armer2.setOpaque(false);
MouseListener buttonArmer = new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent evt) {
closeButton.putClientProperty("paintRollover", Boolean.TRUE);
iconifyButton.putClientProperty("paintRollover", Boolean.TRUE);
toggleButton.putClientProperty("paintRollover", Boolean.TRUE);
closeButton.repaint();
iconifyButton.repaint();
toggleButton.repaint();
}
@Override
public void mouseExited(MouseEvent e) {
closeButton.putClientProperty("paintRollover", Boolean.FALSE);
iconifyButton.putClientProperty("paintRollover", Boolean.FALSE);
toggleButton.putClientProperty("paintRollover", Boolean.FALSE);
closeButton.repaint();
iconifyButton.repaint();
toggleButton.repaint();
}
};
closeButton.addMouseListener(buttonArmer);
iconifyButton.addMouseListener(buttonArmer);
toggleButton.addMouseListener(buttonArmer);
armer1.addMouseListener(buttonArmer);
armer2.addMouseListener(buttonArmer);
}
/**
* Update all textures and icons for the new font used by the JRootPane.
*/
private void updateIconsAndTextures() {
int size = getFont().getSize();
boolean isVertical = isVertical();
Icon closeIcon, iconifyIcon;
String prefix = "InternalFrame.";
String suffix;
if (size <= 9) {
suffix = ".mini";
} else if (size <= 11) {
suffix = ".small";
} else {
suffix = "";
}
maximizeIcon = UIManager.getIcon(prefix + "maximizeIcon" + suffix);
minimizeIcon = UIManager.getIcon(prefix + "maximizeIcon" + suffix);
closeIcon = UIManager.getIcon(prefix + "closeIcon" + suffix);
iconifyIcon = UIManager.getIcon(prefix + "iconifyIcon" + suffix);
activeBackground = UIManager.getColor(prefix + ((isVertical) ? "vTitlePaneBackground" : "titlePaneBackground") + suffix);
activeForeground = UIManager.getColor(prefix + "titlePaneForeground" + suffix);
activeShadow = UIManager.getColor(prefix + "titlePaneShadow" + suffix);
closeButton.setIcon(closeIcon);
iconifyButton.setIcon(iconifyIcon);
toggleButton.setIcon(maximizeIcon);
}
/**
* Returns the LayoutManager
that should be installed on
* the QuaquaTitlePane
.
*/
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 updateRegardless
is
* true and the state has not changed, this will update anyway.
*/
private void setState(int state, boolean updateRegardless) {
// if (w != null && getWindowDecorationStyle() == JRootPane.FRAME) {
if (this.state == state && !updateRegardless) {
return;
}
Object value = rootPane.getClientProperty("Quaqua.RootPane.isPalette");
boolean isPalette = value != null && Boolean.TRUE.equals(value);
Frame frame = getFrame();
if (frame != null && !isPalette) {
if (((state & Frame.MAXIMIZED_BOTH) != 0) &&
(rootPane.getBorder() == null ||
(rootPane.getBorder() instanceof UIResource)) &&
frame.isShowing()) {
rootPane.setBorder(null);
} else if ((state & Frame.MAXIMIZED_BOTH) == 0) {
// This is a croak, if state becomes bound, this can
// be nuked.
rootPaneUI.installBorder(rootPane);
}
if (armer1.getParent() == null) {
add(armer1);
}
if (armer2.getParent() == null) {
add(armer2);
}
//if (frame.isResizable()) {
if ((state & Frame.MAXIMIZED_BOTH) != 0) {
updateToggleButton(restoreAction, minimizeIcon);
maximizeAction.setEnabled(false);
restoreAction.setEnabled(true);
} else {
updateToggleButton(maximizeAction, maximizeIcon);
maximizeAction.setEnabled(true);
restoreAction.setEnabled(false);
}
if (toggleButton.getParent() == null ||
iconifyButton.getParent() == null) {
add(toggleButton);
add(iconifyButton);
revalidate();
repaint();
}
toggleButton.setText(null);
toggleButton.setEnabled(frame.isResizable() && Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH));
/*
} else {
maximizeAction.setEnabled(false);
restoreAction.setEnabled(false);
if (toggleButton.getParent() != null) {
remove(toggleButton);
revalidate();
repaint();
}*/
//}
} else {
// Not contained in a Frame
maximizeAction.setEnabled(false);
restoreAction.setEnabled(false);
iconifyAction.setEnabled(false);
remove(armer1);
remove(armer2);
remove(toggleButton);
remove(iconifyButton);
revalidate();
repaint();
}
closeAction.setEnabled(true);
this.state = state;
//}
}
/**
* Updates the toggle button to contain the Icon icon
, and
* Action action
.
*/
private void updateToggleButton(Action action, Icon icon) {
toggleButton.setAction(action);
toggleButton.setIcon(icon);
toggleButton.setText(null);
toggleButton.setEnabled(
Toolkit.getDefaultToolkit().isFrameStateSupported(
Frame.MAXIMIZED_BOTH));
}
/**
* Returns the Frame rendering in. This will return null if the
* JRootPane
is not contained in a Frame
.
*/
private Frame getFrame() {
if (window instanceof Frame) {
return (Frame) window;
}
return null;
}
/**
* Returns the Dialog rendering in. This will return null if the
* JRootPane
is not contained in a Frame
.
*/
private Dialog getDialog() {
if (window instanceof Dialog) {
return (Dialog) window;
}
return null;
}
@Override
public Font getFont() {
return rootPane.getFont();
/*
Window window = getWindow();
return (window != null) ? window.getFont() : rootPane.getFont();
*/
}
/**
* Returns the Window
the JRootPane
is
* contained in. This will return null if there is no parent ancestor
* of the JRootPane
.
*/
private Window getWindow() {
return window;
}
/**
* Returns the String to display as the title.
*/
private String getTitle() {
Window w = getWindow();
if (w instanceof Frame) {
return ((Frame) w).getTitle();
} else if (w instanceof Dialog) {
return ((Dialog) w).getTitle();
}
return null;
}
/**
* Renders the TitlePane.
*/
@Override
public void paintComponent(Graphics gr) {
Graphics2D g = (Graphics2D) gr;
Object oldHints = QuaquaUtilities.beginGraphics(g);
// As state isn't bound, we need a convenience place to check
// if it has changed.
if (getFrame() != null) {
setState(getFrame().getExtendedState());
}
boolean isVertical = isVertical();
boolean isTextured = rootPane.getClientProperty("apple.awt.brushMetalLook") == Boolean.TRUE;
boolean leftToRight = (window == null) ? rootPane.getComponentOrientation().isLeftToRight() : window.getComponentOrientation().isLeftToRight();
Object value = rootPane.getClientProperty("Quaqua.RootPane.isPalette");
boolean isPalette = value != null && Boolean.TRUE.equals(value);
boolean isSelected = (window == null) ? false : window.isActive();
isSelected |= isPalette;
int width = getWidth();
int height = getHeight();
Color background;
Color foreground;
Color darkShadow;
Border titleBorder;
int fontSize = getFont().getSize();
String suffix = (fontSize <= 9) ? ".mini" : (fontSize <= 11) ? ".small" : "";
if (isVertical()) {
suffix = ".vertical" + suffix;
}
if (isTextured) {
background = UIManager.getColor("RootPane.background");
foreground = activeForeground;
darkShadow = null;
titleBorder = null;
} else {
if (isSelected) {
background = activeBackground;
foreground = activeForeground;
darkShadow = activeShadow;
titleBorder = ((Border[]) UIManager.get("Frame.titlePaneBorders" + suffix))[0];
} else {
background = inactiveBackground;
foreground = inactiveForeground;
darkShadow = inactiveShadow;
titleBorder = ((Border[]) UIManager.get("Frame.titlePaneBorders" + suffix))[1];
}
}
if (/*isPalette ||*/titleBorder == null) {
g.setPaint(TextureColor.getPaint(background, rootPane));
g.fillRect(0, 0, width, height);
if (darkShadow != null) {
g.setPaint(TextureColor.getPaint(darkShadow, rootPane));
if (isVertical) {
g.drawLine(width - 1, 0, width - 1, height);
} else {
g.drawLine(0, height - 1, width, height - 1);
}
}
} else {
// Make background fully transparent (0 alpha)
g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR));
g.fillRect(0, 0, getWidth(), getHeight());
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
titleBorder.paintBorder(this, g, 0, 0, width, height);
}
int xOffset = leftToRight ? 5 : width - 5;
// if (getWindowDecorationStyle() == JRootPane.FRAME) {
xOffset += leftToRight ? IMAGE_WIDTH + 5 : -IMAGE_WIDTH - 5;
// }
String theTitle = getTitle();
if (theTitle != null) {
FontMetrics fm = g.getFontMetrics();
int yOffset = ((height - fm.getHeight()) / 2) + fm.getAscent();
Rectangle rect = new Rectangle(0, 0, 0, 0);
if (iconifyButton != null && iconifyButton.getParent() != null) {
rect = iconifyButton.getBounds();
}
Rectangle toggleRect = new Rectangle(0, 0, 0, 0);
if (toggleButton != null && toggleButton.getParent() != null) {
toggleRect = toggleButton.getBounds();
}
Rectangle closeRect = new Rectangle(0, 0, 0, 0);
if (closeButton != null && closeButton.getParent() != null) {
closeRect = closeButton.getBounds();
}
int titleW;
if (isVertical) {
titleW = height - Math.max(toggleRect.y + toggleRect.height, closeRect.y + closeRect.height);
theTitle = clippedText(theTitle, fm, titleW);
xOffset = ((width - fm.getHeight()) / 2) + fm.getAscent();
int titleLength = SwingUtilities.computeStringWidth(fm, theTitle);
AffineTransform at = g.getTransform();
int y = Math.max(Math.max(closeRect.y + closeRect.height, toggleRect.y + toggleRect.height) + 5, (getHeight() - titleLength) / 2) + titleLength;
g.rotate((float) (Math.PI / -2d), xOffset, y);
if (UIManager.getColor("Frame.titlePaneEmbossForeground") != null) {
g.setPaint(UIManager.getColor("Frame.titlePaneEmbossForeground"));
g.drawString(theTitle, xOffset, y + 1);
}
g.setPaint(TextureColor.getPaint(foreground, window));
g.drawString(theTitle, xOffset, y);
g.setTransform(at);
} else {
if (leftToRight) {
if (rect.x == 0) {
rect.x = window.getWidth() - window.getInsets().right - 2;
}
titleW = getWidth() - Math.max(toggleRect.x + toggleRect.width, closeRect.x + closeRect.width) - 10;
theTitle = clippedText(theTitle, fm, titleW);
} else {
titleW = getWidth() - Math.max(toggleRect.x + toggleRect.width, closeRect.x + closeRect.width) - 10;
theTitle = clippedText(theTitle, fm, titleW);
xOffset -= SwingUtilities.computeStringWidth(fm, theTitle);
}
int titleLength = SwingUtilities.computeStringWidth(fm, theTitle);
if (UIManager.getColor("Frame.titlePaneEmbossForeground") != null) {
g.setPaint(UIManager.getColor("Frame.titlePaneEmbossForeground"));
g.drawString(theTitle, Math.max(Math.max(closeRect.x + closeRect.width, toggleRect.x + toggleRect.width) + 5, (getWidth() - titleLength) / 2), yOffset + 1);
}
g.setPaint(TextureColor.getPaint(foreground, window));
g.drawString(theTitle, Math.max(Math.max(closeRect.x + closeRect.width, toggleRect.x + toggleRect.width) + 5, (getWidth() - titleLength) / 2), yOffset);
xOffset += leftToRight ? titleLength + 5 : -5;
}
}
/*
Composite savedComposite = g.getComposite();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
g.setColor(new Color(0x00ff00,true));
g.fill(new Polygon(new int[] {0,10,0}, new int[] {0,0,10}, 3));
g.setComposite(savedComposite);
*/
QuaquaUtilities.endGraphics(g, oldHints);
}
/**
* Convenience method to clip the passed in text to the specified
* size.
*/
private String clippedText(String text, FontMetrics fm,
int availTextWidth) {
if ((text == null) || (text.equals(""))) {
return "";
}
int textWidth = SwingUtilities.computeStringWidth(fm, text);
String clipString = "…";
if (textWidth > availTextWidth) {
int totalWidth = SwingUtilities.computeStringWidth(fm, clipString);
int nChars;
for (nChars = 0; nChars < text.length(); nChars++) {
totalWidth += fm.charWidth(text.charAt(nChars));
if (totalWidth > availTextWidth) {
break;
}
}
text = text.substring(0, nChars) + clipString;
}
return text;
}
private boolean isVertical() {
return rootPane.getClientProperty("Quaqua.RootPane.isVertical") == Boolean.TRUE;
}
/**
* Actions used to close
the Window
.
*/
private class CloseAction extends AbstractAction {
public CloseAction() {
super(UIManager.getString("QuaquaTitlePane.closeTitle",
getLocale()));
}
public void actionPerformed(ActionEvent e) {
close();
}
}
/**
* Actions used to iconfiy
the Frame
.
*/
private class IconifyAction extends AbstractAction {
public IconifyAction() {
super(UIManager.getString("QuaquaTitlePane.iconifyTitle",
getLocale()));
}
public void actionPerformed(ActionEvent e) {
iconify();
}
}
/**
* Actions used to restore
the Frame
.
*/
private class RestoreAction extends AbstractAction {
public RestoreAction() {
super(UIManager.getString("QuaquaTitlePane.restoreTitle", getLocale()));
}
public void actionPerformed(ActionEvent e) {
restore();
}
}
/**
* Actions used to restore
the Frame
.
*/
private class MaximizeAction extends AbstractAction {
public MaximizeAction() {
super(UIManager.getString("QuaquaTitlePane.maximizeTitle",
getLocale()));
}
public void actionPerformed(ActionEvent e) {
maximize();
}
}
/**
* Class responsible for drawing the system menu. Looks up the
* image to draw from the Frame associated with the
* JRootPane
.
*/
private class SystemMenuBar extends JMenuBar {
@Override
public void paint(Graphics gr) {
Graphics2D g = (Graphics2D) gr;
Frame frame = getFrame();
if (isOpaque()) {
g.setPaint(TextureColor.getPaint(getBackground(), this));
g.fillRect(0, 0, getWidth(), getHeight());
}
Image image = (frame != null) ? frame.getIconImage() : null;
if (image != null) {
g.drawImage(image, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
} else {
Icon icon = UIManager.getIcon("InternalFrame.icon");
if (icon != null) {
icon.paintIcon(this, g, 0, 0);
}
}
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
@Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
return new Dimension(Math.max(IMAGE_WIDTH, size.width),
Math.max(size.height, IMAGE_HEIGHT));
}
}
/**
* This inner class is marked "public" due to a compiler bug.
* This class should be treated as a "protected" inner class.
* Instantiate it only within subclasses of .
*/
private class TitlePaneLayout implements LayoutManager {
public void addLayoutComponent(String name, Component c) {
}
public void removeLayoutComponent(Component c) {
}
public Dimension preferredLayoutSize(Container c) {
int height = computeHeight();
return new Dimension(height, height);
}
public Dimension minimumLayoutSize(Container c) {
return preferredLayoutSize(c);
}
private int computeHeight() {
int fontSize = getFont().getSize();
if (fontSize <= 9) {
return 12;
} else if (fontSize <= 11) {
return 16;
} else {
return 22;
}
/*
FontMetrics fm
= Toolkit.getDefaultToolkit().getFontMetrics(getFont());
int fontHeight = fm.getHeight();
fontHeight += 2;
int iconHeight = 0;
// if (getWindowDecorationStyle() == JRootPane.FRAME) {
iconHeight = IMAGE_HEIGHT;
// }
int finalHeight = Math.max( fontHeight, iconHeight );
return finalHeight;
*/
}
public void layoutContainer(Container c) {
boolean isVertical = isVertical();
if (isVertical) {
layoutVerticalContainer(c);
} else {
layoutHorizontalContainer(c);
}
}
public void layoutHorizontalContainer(Container c) {
int fontSize = getFont().getSize();
boolean leftToRight;
if (window == null) {
leftToRight = !getRootPane().getComponentOrientation().isLeftToRight();
} else {
leftToRight = !window.getComponentOrientation().isLeftToRight();
}
int w = getWidth();
int x;
int y;
int spacing;
int buttonHeight;
int buttonWidth;
if (fontSize <= 9) {
y = 1;
} else if (fontSize <= 11) {
y = 1;
} else {
y = 4;
}
if (closeButton != null && closeButton.getIcon() != null) {
buttonHeight = closeButton.getIcon().getIconHeight();
buttonWidth = closeButton.getIcon().getIconWidth();
} else {
buttonHeight = IMAGE_HEIGHT;
buttonWidth = IMAGE_WIDTH;
}
// assumes all buttons have the same dimensions
// these dimensions include the borders
x = leftToRight ? w : 0;
spacing = 5;
x = leftToRight ? spacing : w - buttonWidth - spacing;
x = leftToRight ? w : 0;
spacing = (fontSize <= 11) ? 5 : 7;
x += leftToRight ? -spacing - buttonWidth : spacing;
if (closeButton != null) {
closeButton.setBounds(x, y, buttonWidth, buttonHeight);
}
if (!leftToRight) {
x += buttonWidth;
}
if (iconifyButton != null &&
iconifyButton.getParent() != null) {
spacing = 5;
armer1.setBounds(x, y, spacing, buttonHeight);
x += leftToRight ? -spacing - buttonWidth : spacing;
iconifyButton.setBounds(x, y, buttonWidth, buttonHeight);
if (!leftToRight) {
x += buttonWidth;
}
} else {
armer1.setBounds(0, 0, 0, 0);
}
if (Toolkit.getDefaultToolkit().isFrameStateSupported(
Frame.MAXIMIZED_BOTH)) {
if (toggleButton.getParent() != null) {
spacing = 5;
armer2.setBounds(x, y, spacing, buttonHeight);
x += leftToRight ? -spacing - buttonWidth : spacing;
toggleButton.setBounds(x, y, buttonWidth, buttonHeight);
if (!leftToRight) {
x += buttonWidth;
}
}
} else {
armer2.setBounds(0, 0, 0, 0);
}
buttonsWidth = leftToRight ? w - x : x;
}
}
public void layoutVerticalContainer(Container c) {
int x;
int y;
int spacing;
int buttonHeight;
int buttonWidth;
int fontSize = getFont().getSize();
if (fontSize <= 9) {
x = 2;
} else if (fontSize <= 11) {
x = 1;
} else {
x = 2;
}
if (closeButton != null && closeButton.getIcon() != null) {
buttonHeight = closeButton.getIcon().getIconHeight();
buttonWidth = closeButton.getIcon().getIconWidth();
} else {
buttonHeight = IMAGE_HEIGHT;
buttonWidth = IMAGE_WIDTH;
}
// assumes all buttons have the same dimensions
// these dimensions include the borders
spacing = 5;
y = spacing;
if (fontSize <= 9) {
y = 0;
} else if (fontSize <= 11) {
y = 0;
} else {
y = 4;
}
spacing = 2;
y += spacing;
if (closeButton != null) {
closeButton.setBounds(x, y, buttonWidth, buttonHeight);
}
y += buttonHeight;
if (iconifyButton != null &&
iconifyButton.getParent() != null) {
spacing = 5;
armer1.setBounds(x, y, buttonWidth, spacing);
y += spacing;
iconifyButton.setBounds(x, y, buttonWidth, buttonHeight);
y += buttonHeight;
} else {
armer1.setBounds(0, 0, 0, 0);
}
if (Toolkit.getDefaultToolkit().isFrameStateSupported(
Frame.MAXIMIZED_BOTH)) {
if (toggleButton.getParent() != null) {
spacing = 5;
armer2.setBounds(x, y, buttonWidth, spacing);
y += spacing;
toggleButton.setBounds(x, y, buttonWidth, buttonHeight);
y += buttonHeight;
}
} else {
armer2.setBounds(0, 0, 0, 0);
}
buttonsWidth = x + buttonWidth;
}
/**
* PropertyChangeListener installed on the JRootPane. Updates the necessary
* state as the state of the JRootPane changes.
*/
private class RootPropertyHandler implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent pce) {
String name = pce.getPropertyName();
if ("Quaqua.RootPane.isVertical".equals(name)) {
updateIconsAndTextures();
revalidate();
repaint();
} else if ("Window.documentModified".equals(name) || "windowModified".equals(name)) {
closeButton.setSelected(((Boolean) pce.getNewValue()).booleanValue());
} else if ("font".equals(name)) {
updateIconsAndTextures();
revalidate();
repaint();
}
}
}
/**
* PropertyChangeListener installed on the Window. Updates the necessary
* state as the state of the Window changes.
*/
private class WindowPropertyHandler implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent pce) {
String name = pce.getPropertyName();
// Frame.state isn't currently bound.
if ("resizable".equals(name) || "state".equals(name)) {
Frame frame = getFrame();
if (frame != null) {
setState(frame.getExtendedState(), true);
}
if ("resizable".equals(name)) {
getRootPane().repaint();
}
} else if ("title".equals(name)) {
repaint();
} else if ("Quaqua.RootPane.isVertical".equals(name)) {
updateIconsAndTextures();
revalidate();
repaint();
} else if ("componentOrientation".equals(name)) {
revalidate();
repaint();
} else if (name.equals("JComponent.sizeVariant")) {
QuaquaUtilities.applySizeVariant(rootPane);
}
}
}
/**
* WindowListener installed on the Window, updates the state as necessary.
*/
private class WindowHandler extends WindowAdapter {
@Override
public void windowActivated(WindowEvent ev) {
setActive(true);
}
@Override
public void windowDeactivated(WindowEvent ev) {
setActive(false);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy