- /*
- * @(#)MetalInternalFrameTitlePane.java 1.57 04/03/17
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package javax.swing.plaf.metal;
-
- import com.sun.java.swing.SwingUtilities2;
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
- import javax.swing.border.*;
- import javax.swing.event.InternalFrameEvent;
- import java.util.EventListener;
- import java.beans.PropertyChangeListener;
- import java.beans.PropertyChangeEvent;
- import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
-
-
- /**
- * Class that manages a JLF title bar
- * @version 1.57 03/17/04
- * @author Steve Wilson
- * @author Brian Beck
- * @since 1.3
- */
-
- public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane {
-
- protected boolean isPalette = false;
- protected Icon paletteCloseIcon;
- protected int paletteTitleHeight;
-
- private static final Border handyEmptyBorder = new EmptyBorder(0,0,0,0);
-
- /**
- * Key used to lookup Color from UIManager. If this is null,
- * <code>getWindowTitleBackground</code> is used.
- */
- private String selectedBackgroundKey;
- /**
- * Key used to lookup Color from UIManager. If this is null,
- * <code>getWindowTitleForeground</code> is used.
- */
- private String selectedForegroundKey;
- /**
- * Key used to lookup shadow color from UIManager. If this is null,
- * <code>getPrimaryControlDarkShadow</code> is used.
- */
- private String selectedShadowKey;
- /**
- * Boolean indicating the state of the <code>JInternalFrame</code>s
- * closable property at <code>updateUI</code> time.
- */
- private boolean wasClosable;
-
- int buttonsWidth = 0;
-
- MetalBumps activeBumps
- = new MetalBumps( 0, 0,
- MetalLookAndFeel.getPrimaryControlHighlight(),
- MetalLookAndFeel.getPrimaryControlDarkShadow(),
- (UIManager.get("InternalFrame.activeTitleGradient") != null) ? null :
- MetalLookAndFeel.getPrimaryControl() );
- MetalBumps inactiveBumps
- = new MetalBumps( 0, 0,
- MetalLookAndFeel.getControlHighlight(),
- MetalLookAndFeel.getControlDarkShadow(),
- (UIManager.get("InternalFrame.inactiveTitleGradient") != null) ? null :
- MetalLookAndFeel.getControl() );
- MetalBumps paletteBumps;
-
- private Color activeBumpsHighlight = MetalLookAndFeel.
- getPrimaryControlHighlight();
- private Color activeBumpsShadow = MetalLookAndFeel.
- getPrimaryControlDarkShadow();
-
- public MetalInternalFrameTitlePane(JInternalFrame f) {
- super( f );
- }
-
- public void addNotify() {
- super.addNotify();
- // This is done here instead of in installDefaults as I was worried
- // that the BasicInternalFrameUI might not be fully initialized, and
- // that if this resets the closable state the BasicInternalFrameUI
- // Listeners that get notified might be in an odd/uninitialized state.
- updateOptionPaneState();
- }
-
- protected void installDefaults() {
- super.installDefaults();
- setFont( UIManager.getFont("InternalFrame.titleFont") );
- paletteTitleHeight
- = UIManager.getInt("InternalFrame.paletteTitleHeight");
- paletteCloseIcon = UIManager.getIcon("InternalFrame.paletteCloseIcon");
- wasClosable = frame.isClosable();
- selectedForegroundKey = selectedBackgroundKey = null;
- if (MetalLookAndFeel.usingOcean()) {
- setOpaque(true);
- }
- }
-
- protected void uninstallDefaults() {
- super.uninstallDefaults();
- if (wasClosable != frame.isClosable()) {
- frame.setClosable(wasClosable);
- }
- }
-
- protected void createButtons() {
- super.createButtons();
-
- Boolean paintActive = frame.isSelected() ? Boolean.TRUE:Boolean.FALSE;
- iconButton.putClientProperty("paintActive", paintActive);
- iconButton.setBorder(handyEmptyBorder);
-
- maxButton.putClientProperty("paintActive", paintActive);
- maxButton.setBorder(handyEmptyBorder);
-
- closeButton.putClientProperty("paintActive", paintActive);
- closeButton.setBorder(handyEmptyBorder);
-
- // The palette close icon isn't opaque while the regular close icon is.
- // This makes sure palette close buttons have the right background.
- closeButton.setBackground(MetalLookAndFeel.getPrimaryControlShadow());
-
- if (MetalLookAndFeel.usingOcean()) {
- iconButton.setContentAreaFilled(false);
- maxButton.setContentAreaFilled(false);
- closeButton.setContentAreaFilled(false);
- }
- }
-
- /**
- * Override the parent's method to do nothing. Metal frames do not
- * have system menus.
- */
- protected void assembleSystemMenu() {}
-
- /**
- * Override the parent's method to do nothing. Metal frames do not
- * have system menus.
- */
- protected void addSystemMenuItems(JMenu systemMenu) {}
-
- /**
- * Override the parent's method to do nothing. Metal frames do not
- * have system menus.
- */
- protected void showSystemMenu() {}
-
- /**
- * Override the parent's method avoid creating a menu bar. Metal frames
- * do not have system menus.
- */
- protected void addSubComponents() {
- add(iconButton);
- add(maxButton);
- add(closeButton);
- }
-
- protected PropertyChangeListener createPropertyChangeListener() {
- return new MetalPropertyChangeHandler();
- }
-
- protected LayoutManager createLayout() {
- return new MetalTitlePaneLayout();
- }
-
- class MetalPropertyChangeHandler
- extends BasicInternalFrameTitlePane.PropertyChangeHandler
- {
- public void propertyChange(PropertyChangeEvent evt) {
- String prop = (String)evt.getPropertyName();
- if( prop.equals(JInternalFrame.IS_SELECTED_PROPERTY) ) {
- Boolean b = (Boolean)evt.getNewValue();
- iconButton.putClientProperty("paintActive", b);
- closeButton.putClientProperty("paintActive", b);
- maxButton.putClientProperty("paintActive", b);
- }
- else if ("JInternalFrame.messageType".equals(prop)) {
- updateOptionPaneState();
- frame.repaint();
- }
- super.propertyChange(evt);
- }
- }
-
- class MetalTitlePaneLayout extends TitlePaneLayout {
- public void addLayoutComponent(String name, Component c) {}
- public void removeLayoutComponent(Component c) {}
- public Dimension preferredLayoutSize(Container c) {
- return minimumLayoutSize(c);
- }
-
- public Dimension minimumLayoutSize(Container c) {
- // Compute width.
- int width = 30;
- if (frame.isClosable()) {
- width += 21;
- }
- if (frame.isMaximizable()) {
- width += 16 + (frame.isClosable() ? 10 : 4);
- }
- if (frame.isIconifiable()) {
- width += 16 + (frame.isMaximizable() ? 2 :
- (frame.isClosable() ? 10 : 4));
- }
- FontMetrics fm = frame.getFontMetrics(getFont());
- String frameTitle = frame.getTitle();
- int title_w = frameTitle != null ? SwingUtilities2.stringWidth(
- frame, fm, frameTitle) : 0;
- int title_length = frameTitle != null ? frameTitle.length() : 0;
-
- if (title_length > 2) {
- int subtitle_w = SwingUtilities2.stringWidth(frame, fm,
- frame.getTitle().substring(0, 2) + "...");
- width += (title_w < subtitle_w) ? title_w : subtitle_w;
- }
- else {
- width += title_w;
- }
-
- // Compute height.
- int height = 0;
- if (isPalette) {
- height = paletteTitleHeight;
- } else {
- int fontHeight = fm.getHeight();
- fontHeight += 7;
- Icon icon = frame.getFrameIcon();
- int iconHeight = 0;
- if (icon != null) {
- // SystemMenuBar forces the icon to be 16x16 or less.
- iconHeight = Math.min(icon.getIconHeight(), 16);
- }
- iconHeight += 5;
- height = Math.max(fontHeight, iconHeight);
- }
-
- return new Dimension(width, height);
- }
-
- public void layoutContainer(Container c) {
- boolean leftToRight = MetalUtils.isLeftToRight(frame);
-
- int w = getWidth();
- int x = leftToRight ? w : 0;
- int y = 2;
- int spacing;
-
- // assumes all buttons have the same dimensions
- // these dimensions include the borders
- int buttonHeight = closeButton.getIcon().getIconHeight();
- int buttonWidth = closeButton.getIcon().getIconWidth();
-
- if(frame.isClosable()) {
- if (isPalette) {
- spacing = 3;
- x += leftToRight ? -spacing -(buttonWidth+2) : spacing;
- closeButton.setBounds(x, y, buttonWidth+2, getHeight()-4);
- if( !leftToRight ) x += (buttonWidth+2);
- } else {
- spacing = 4;
- x += leftToRight ? -spacing -buttonWidth : spacing;
- closeButton.setBounds(x, y, buttonWidth, buttonHeight);
- if( !leftToRight ) x += buttonWidth;
- }
- }
-
- if(frame.isMaximizable() && !isPalette ) {
- spacing = frame.isClosable() ? 10 : 4;
- x += leftToRight ? -spacing -buttonWidth : spacing;
- maxButton.setBounds(x, y, buttonWidth, buttonHeight);
- if( !leftToRight ) x += buttonWidth;
- }
-
- if(frame.isIconifiable() && !isPalette ) {
- spacing = frame.isMaximizable() ? 2
- : (frame.isClosable() ? 10 : 4);
- x += leftToRight ? -spacing -buttonWidth : spacing;
- iconButton.setBounds(x, y, buttonWidth, buttonHeight);
- if( !leftToRight ) x += buttonWidth;
- }
-
- buttonsWidth = leftToRight ? w - x : x;
- }
- }
-
- public void paintPalette(Graphics g) {
- boolean leftToRight = MetalUtils.isLeftToRight(frame);
-
- int width = getWidth();
- int height = getHeight();
-
- if (paletteBumps == null) {
- paletteBumps
- = new MetalBumps(0, 0,
- MetalLookAndFeel.getPrimaryControlHighlight(),
- MetalLookAndFeel.getPrimaryControlInfo(),
- MetalLookAndFeel.getPrimaryControlShadow() );
- }
-
- Color background = MetalLookAndFeel.getPrimaryControlShadow();
- Color darkShadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
-
- g.setColor(background);
- g.fillRect(0, 0, width, height);
-
- g.setColor( darkShadow );
- g.drawLine ( 0, height - 1, width, height -1);
-
- int xOffset = leftToRight ? 4 : buttonsWidth + 4;
- int bumpLength = width - buttonsWidth -2*4;
- int bumpHeight = getHeight() - 4;
- paletteBumps.setBumpArea( bumpLength, bumpHeight );
- paletteBumps.paintIcon( this, g, xOffset, 2);
- }
-
- public void paintComponent(Graphics g) {
- if(isPalette) {
- paintPalette(g);
- return;
- }
-
- boolean leftToRight = MetalUtils.isLeftToRight(frame);
- boolean isSelected = frame.isSelected();
-
- int width = getWidth();
- int height = getHeight();
-
- Color background = null;
- Color foreground = null;
- Color shadow = null;
-
- MetalBumps bumps;
- String gradientKey;
-
- if (isSelected) {
- if (!MetalLookAndFeel.usingOcean()) {
- closeButton.setContentAreaFilled(true);
- maxButton.setContentAreaFilled(true);
- iconButton.setContentAreaFilled(true);
- }
- if (selectedBackgroundKey != null) {
- background = UIManager.getColor(selectedBackgroundKey);
- }
- if (background == null) {
- background = MetalLookAndFeel.getWindowTitleBackground();
- }
- if (selectedForegroundKey != null) {
- foreground = UIManager.getColor(selectedForegroundKey);
- }
- if (selectedShadowKey != null) {
- shadow = UIManager.getColor(selectedShadowKey);
- }
- if (shadow == null) {
- shadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
- }
- if (foreground == null) {
- foreground = MetalLookAndFeel.getWindowTitleForeground();
- }
- activeBumps.setBumpColors(activeBumpsHighlight, activeBumpsShadow,
- UIManager.get("InternalFrame.activeTitleGradient") !=
- null ? null : background);
- bumps = activeBumps;
- gradientKey = "InternalFrame.activeTitleGradient";
- } else {
- if (!MetalLookAndFeel.usingOcean()) {
- closeButton.setContentAreaFilled(false);
- maxButton.setContentAreaFilled(false);
- iconButton.setContentAreaFilled(false);
- }
- background = MetalLookAndFeel.getWindowTitleInactiveBackground();
- foreground = MetalLookAndFeel.getWindowTitleInactiveForeground();
- shadow = MetalLookAndFeel.getControlDarkShadow();
- bumps = inactiveBumps;
- gradientKey = "InternalFrame.inactiveTitleGradient";
- }
-
- if (!MetalUtils.drawGradient(this, g, gradientKey, 0, 0, width,
- height, true)) {
- g.setColor(background);
- g.fillRect(0, 0, width, height);
- }
-
- g.setColor( shadow );
- g.drawLine ( 0, height - 1, width, height -1);
- g.drawLine ( 0, 0, 0 ,0);
- g.drawLine ( width - 1, 0 , width -1, 0);
-
-
- int titleLength = 0;
- int xOffset = leftToRight ? 5 : width - 5;
- String frameTitle = frame.getTitle();
-
- Icon icon = frame.getFrameIcon();
- if ( icon != null ) {
- if( !leftToRight )
- xOffset -= icon.getIconWidth();
- int iconY = ((height / 2) - (icon.getIconHeight() /2));
- icon.paintIcon(frame, g, xOffset, iconY);
- xOffset += leftToRight ? icon.getIconWidth() + 5 : -5;
- }
-
- if(frameTitle != null) {
- Font f = getFont();
- g.setFont(f);
- FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g, f);
- int fHeight = fm.getHeight();
-
- g.setColor(foreground);
-
- int yOffset = ( (height - fm.getHeight() ) / 2 ) + fm.getAscent();
-
- Rectangle rect = new Rectangle(0, 0, 0, 0);
- if (frame.isIconifiable()) { rect = iconButton.getBounds(); }
- else if (frame.isMaximizable()) { rect = maxButton.getBounds(); }
- else if (frame.isClosable()) { rect = closeButton.getBounds(); }
- int titleW;
-
- if( leftToRight ) {
- if (rect.x == 0) {
- rect.x = frame.getWidth()-frame.getInsets().right-2;
- }
- titleW = rect.x - xOffset - 4;
- frameTitle = getTitle(frameTitle, fm, titleW);
- } else {
- titleW = xOffset - rect.x - rect.width - 4;
- frameTitle = getTitle(frameTitle, fm, titleW);
- xOffset -= SwingUtilities2.stringWidth(frame, fm, frameTitle);
- }
-
- titleLength = SwingUtilities2.stringWidth(frame, fm, frameTitle);
- SwingUtilities2.drawString(frame, g, frameTitle, xOffset, yOffset);
- xOffset += leftToRight ? titleLength + 5 : -5;
- }
-
- int bumpXOffset;
- int bumpLength;
- if( leftToRight ) {
- bumpLength = width - buttonsWidth - xOffset - 5;
- bumpXOffset = xOffset;
- } else {
- bumpLength = xOffset - buttonsWidth - 5;
- bumpXOffset = buttonsWidth + 5;
- }
- int bumpYOffset = 3;
- int bumpHeight = getHeight() - (2 * bumpYOffset);
- bumps.setBumpArea( bumpLength, bumpHeight );
- bumps.paintIcon(this, g, bumpXOffset, bumpYOffset);
- }
-
- public void setPalette(boolean b) {
- isPalette = b;
-
- if (isPalette) {
- closeButton.setIcon(paletteCloseIcon);
- if( frame.isMaximizable() )
- remove(maxButton);
- if( frame.isIconifiable() )
- remove(iconButton);
- } else {
- closeButton.setIcon(closeIcon);
- if( frame.isMaximizable() )
- add(maxButton);
- if( frame.isIconifiable() )
- add(iconButton);
- }
- revalidate();
- repaint();
- }
-
- /**
- * Updates any state dependant upon the JInternalFrame being shown in
- * a <code>JOptionPane</code>.
- */
- private void updateOptionPaneState() {
- int type = -2;
- boolean closable = wasClosable;
- Object obj = frame.getClientProperty("JInternalFrame.messageType");
-
- if (obj == null) {
- // Don't change the closable state unless in an JOptionPane.
- return;
- }
- if (obj instanceof Integer) {
- type = ((Integer) obj).intValue();
- }
- switch (type) {
- case JOptionPane.ERROR_MESSAGE:
- selectedBackgroundKey =
- "OptionPane.errorDialog.titlePane.background";
- selectedForegroundKey =
- "OptionPane.errorDialog.titlePane.foreground";
- selectedShadowKey = "OptionPane.errorDialog.titlePane.shadow";
- closable = false;
- break;
- case JOptionPane.QUESTION_MESSAGE:
- selectedBackgroundKey =
- "OptionPane.questionDialog.titlePane.background";
- selectedForegroundKey =
- "OptionPane.questionDialog.titlePane.foreground";
- selectedShadowKey =
- "OptionPane.questionDialog.titlePane.shadow";
- closable = false;
- break;
- case JOptionPane.WARNING_MESSAGE:
- selectedBackgroundKey =
- "OptionPane.warningDialog.titlePane.background";
- selectedForegroundKey =
- "OptionPane.warningDialog.titlePane.foreground";
- selectedShadowKey = "OptionPane.warningDialog.titlePane.shadow";
- closable = false;
- break;
- case JOptionPane.INFORMATION_MESSAGE:
- case JOptionPane.PLAIN_MESSAGE:
- selectedBackgroundKey = selectedForegroundKey = selectedShadowKey =
- null;
- closable = false;
- break;
- default:
- selectedBackgroundKey = selectedForegroundKey = selectedShadowKey =
- null;
- break;
- }
- if (closable != frame.isClosable()) {
- frame.setClosable(closable);
- }
- }
- }