| /* MetalInternalFrameTitlePane.java |
| Copyright (C) 2005 Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath 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 |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package javax.swing.plaf.metal; |
| |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Container; |
| import java.awt.Dimension; |
| import java.awt.Graphics; |
| import java.awt.Insets; |
| import java.awt.LayoutManager; |
| import java.awt.Rectangle; |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| |
| import javax.swing.Icon; |
| import javax.swing.JInternalFrame; |
| import javax.swing.JLabel; |
| import javax.swing.JMenu; |
| import javax.swing.SwingConstants; |
| import javax.swing.SwingUtilities; |
| import javax.swing.UIManager; |
| import javax.swing.plaf.basic.BasicInternalFrameTitlePane; |
| |
| |
| /** |
| * The title pane for a {@link JInternalFrame} (see |
| * {@link MetalInternalFrameUI#createNorthPane(JInternalFrame)}). This can |
| * be displayed in two styles: one for regular internal frames, and the other |
| * for "palette" style internal frames. |
| */ |
| public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane |
| { |
| |
| /** |
| * A property change handler that listens for changes to the |
| * <code>JInternalFrame.isPalette</code> property and updates the title |
| * pane as appropriate. |
| */ |
| class MetalInternalFrameTitlePanePropertyChangeHandler |
| extends PropertyChangeHandler |
| { |
| /** |
| * Creates a new handler. |
| */ |
| public MetalInternalFrameTitlePanePropertyChangeHandler() |
| { |
| super(); |
| } |
| |
| /** |
| * Handles <code>JInternalFrame.isPalette</code> property changes, with all |
| * other property changes being passed to the superclass. |
| * |
| * @param e the event. |
| */ |
| public void propertyChange(PropertyChangeEvent e) |
| { |
| String propName = e.getPropertyName(); |
| if (e.getPropertyName().equals(JInternalFrame.FRAME_ICON_PROPERTY)) |
| { |
| title.setIcon(frame.getFrameIcon()); |
| } |
| else if (propName.equals("JInternalFrame.isPalette")) |
| { |
| if (e.getNewValue().equals(Boolean.TRUE)) |
| setPalette(true); |
| else |
| setPalette(false); |
| } |
| else |
| super.propertyChange(e); |
| } |
| } |
| |
| /** |
| * A layout manager for the title pane. |
| * |
| * @see #createLayout() |
| */ |
| private class MetalTitlePaneLayout implements LayoutManager |
| { |
| /** |
| * Creates a new <code>TitlePaneLayout</code> object. |
| */ |
| public MetalTitlePaneLayout() |
| { |
| // Do nothing. |
| } |
| |
| /** |
| * Adds a Component to the Container. |
| * |
| * @param name The name to reference the added Component by. |
| * @param c The Component to add. |
| */ |
| public void addLayoutComponent(String name, Component c) |
| { |
| // Do nothing. |
| } |
| |
| /** |
| * This method is called to lay out the children of the Title Pane. |
| * |
| * @param c The Container to lay out. |
| */ |
| public void layoutContainer(Container c) |
| { |
| |
| Dimension size = c.getSize(); |
| Insets insets = c.getInsets(); |
| int width = size.width - insets.left - insets.right; |
| int height = size.height - insets.top - insets.bottom; |
| |
| |
| int loc = width - insets.right - 1; |
| int top = insets.top + 2; |
| int buttonHeight = height - 4; |
| if (closeButton.isVisible()) |
| { |
| int buttonWidth = closeIcon.getIconWidth(); |
| loc -= buttonWidth + 2; |
| closeButton.setBounds(loc, top, buttonWidth, buttonHeight); |
| loc -= 6; |
| } |
| |
| if (maxButton.isVisible()) |
| { |
| int buttonWidth = maxIcon.getIconWidth(); |
| loc -= buttonWidth + 4; |
| maxButton.setBounds(loc, top, buttonWidth, buttonHeight); |
| } |
| |
| if (iconButton.isVisible()) |
| { |
| int buttonWidth = minIcon.getIconWidth(); |
| loc -= buttonWidth + 4; |
| iconButton.setBounds(loc, top, buttonWidth, buttonHeight); |
| loc -= 2; |
| } |
| |
| Dimension titlePreferredSize = title.getPreferredSize(); |
| title.setBounds(insets.left + 5, insets.top, |
| Math.min(titlePreferredSize.width, loc - insets.left - 10), |
| height); |
| |
| } |
| |
| /** |
| * This method returns the minimum size of the given Container given the |
| * children that it has. |
| * |
| * @param c The Container to get a minimum size for. |
| * |
| * @return The minimum size of the Container. |
| */ |
| public Dimension minimumLayoutSize(Container c) |
| { |
| return preferredLayoutSize(c); |
| } |
| |
| /** |
| * Returns the preferred size of the given Container taking |
| * into account the children that it has. |
| * |
| * @param c The Container to lay out. |
| * |
| * @return The preferred size of the Container. |
| */ |
| public Dimension preferredLayoutSize(Container c) |
| { |
| if (isPalette) |
| return new Dimension(paletteTitleHeight, paletteTitleHeight); |
| else |
| return new Dimension(22, 22); |
| } |
| |
| /** |
| * Removes a Component from the Container. |
| * |
| * @param c The Component to remove. |
| */ |
| public void removeLayoutComponent(Component c) |
| { |
| // Nothing to do here. |
| } |
| } |
| |
| /** A flag indicating whether the title pane uses the palette style. */ |
| protected boolean isPalette; |
| |
| /** |
| * The icon used for the close button - this is fetched from the look and |
| * feel defaults using the key <code>InternalFrame.paletteCloseIcon</code>. |
| */ |
| protected Icon paletteCloseIcon; |
| |
| /** |
| * The height of the title pane when <code>isPalette</code> is |
| * <code>true</code>. This value is fetched from the look and feel defaults |
| * using the key <code>InternalFrame.paletteTitleHeight</code>. |
| */ |
| protected int paletteTitleHeight; |
| |
| /** The label used to display the title for the internal frame. */ |
| JLabel title; |
| |
| /** |
| * Creates a new title pane for the specified frame. |
| * |
| * @param f the internal frame. |
| */ |
| public MetalInternalFrameTitlePane(JInternalFrame f) |
| { |
| super(f); |
| isPalette = false; |
| } |
| |
| /** |
| * Fetches the colors used in the title pane. |
| */ |
| protected void installDefaults() |
| { |
| super.installDefaults(); |
| selectedTextColor = MetalLookAndFeel.getControlTextColor(); |
| selectedTitleColor = MetalLookAndFeel.getWindowTitleBackground(); |
| notSelectedTextColor = MetalLookAndFeel.getInactiveControlTextColor(); |
| notSelectedTitleColor = MetalLookAndFeel.getWindowTitleInactiveBackground(); |
| |
| paletteTitleHeight = UIManager.getInt("InternalFrame.paletteTitleHeight"); |
| paletteCloseIcon = UIManager.getIcon("InternalFrame.paletteCloseIcon"); |
| minIcon = MetalIconFactory.getInternalFrameAltMaximizeIcon(16); |
| |
| title = new JLabel(frame.getTitle(), |
| MetalIconFactory.getInternalFrameDefaultMenuIcon(), |
| SwingConstants.LEFT); |
| } |
| |
| /** |
| * Clears the colors used for the title pane. |
| */ |
| protected void uninstallDefaults() |
| { |
| super.uninstallDefaults(); |
| selectedTextColor = null; |
| selectedTitleColor = null; |
| notSelectedTextColor = null; |
| notSelectedTitleColor = null; |
| paletteCloseIcon = null; |
| minIcon = null; |
| title = null; |
| } |
| |
| /** |
| * Calls the super class to create the buttons, then calls |
| * <code>setBorderPainted(false)</code> and |
| * <code>setContentAreaFilled(false)</code> for each button. |
| */ |
| protected void createButtons() |
| { |
| super.createButtons(); |
| closeButton.setBorderPainted(false); |
| closeButton.setContentAreaFilled(false); |
| iconButton.setBorderPainted(false); |
| iconButton.setContentAreaFilled(false); |
| maxButton.setBorderPainted(false); |
| maxButton.setContentAreaFilled(false); |
| } |
| |
| /** |
| * Overridden to do nothing. |
| */ |
| protected void addSystemMenuItems(JMenu systemMenu) |
| { |
| // do nothing |
| } |
| |
| /** |
| * Overridden to do nothing. |
| */ |
| protected void showSystemMenu() |
| { |
| // do nothing |
| } |
| |
| /** |
| * Adds the sub components of the title pane. |
| */ |
| protected void addSubComponents() |
| { |
| // FIXME: this method is probably overridden to only add the required |
| // buttons |
| add(title); |
| add(closeButton); |
| add(iconButton); |
| add(maxButton); |
| } |
| |
| /** |
| * Creates a new instance of <code>MetalTitlePaneLayout</code> (not part of |
| * the public API). |
| * |
| * @return A new instance of <code>MetalTitlePaneLayout</code>. |
| */ |
| protected LayoutManager createLayout() |
| { |
| return new MetalTitlePaneLayout(); |
| } |
| |
| /** |
| * Draws the title pane in the palette style. |
| * |
| * @param g the graphics device. |
| * |
| * @see #paintComponent(Graphics) |
| */ |
| public void paintPalette(Graphics g) |
| { |
| Color savedColor = g.getColor(); |
| Rectangle b = SwingUtilities.getLocalBounds(this); |
| |
| if (UIManager.get("InternalFrame.activeTitleGradient") != null |
| && frame.isSelected()) |
| { |
| MetalUtils.paintGradient(g, b.x, b.y, b.width, b.height, |
| SwingConstants.VERTICAL, |
| "InternalFrame.activeTitleGradient"); |
| } |
| MetalUtils.fillMetalPattern(this, g, b.x + 4, b.y + 2, b.width |
| - paletteCloseIcon.getIconWidth() - 13, b.height - 5, |
| MetalLookAndFeel.getPrimaryControlHighlight(), |
| MetalLookAndFeel.getBlack()); |
| |
| // draw a line separating the title pane from the frame content |
| Dimension d = getSize(); |
| g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow()); |
| g.drawLine(0, d.height - 1, d.width - 1, d.height - 1); |
| |
| g.setColor(savedColor); |
| } |
| |
| /** |
| * Paints a representation of the current state of the internal frame. |
| * |
| * @param g the graphics device. |
| */ |
| public void paintComponent(Graphics g) |
| { |
| Color savedColor = g.getColor(); |
| if (isPalette) |
| paintPalette(g); |
| else |
| { |
| paintTitleBackground(g); |
| paintChildren(g); |
| Dimension d = getSize(); |
| if (frame.isSelected()) |
| g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow()); |
| else |
| g.setColor(MetalLookAndFeel.getControlDarkShadow()); |
| |
| // put a dot in each of the top corners |
| g.drawLine(0, 0, 0, 0); |
| g.drawLine(d.width - 1, 0, d.width - 1, 0); |
| |
| g.drawLine(0, d.height - 1, d.width - 1, d.height - 1); |
| |
| // draw the metal pattern |
| if (UIManager.get("InternalFrame.activeTitleGradient") != null |
| && frame.isSelected()) |
| { |
| MetalUtils.paintGradient(g, 0, 0, getWidth(), getHeight(), |
| SwingConstants.VERTICAL, |
| "InternalFrame.activeTitleGradient"); |
| } |
| |
| Rectangle b = title.getBounds(); |
| int startX = b.x + b.width + 5; |
| int endX = startX; |
| if (iconButton.isVisible()) |
| endX = Math.max(iconButton.getX(), endX); |
| else if (maxButton.isVisible()) |
| endX = Math.max(maxButton.getX(), endX); |
| else if (closeButton.isVisible()) |
| endX = Math.max(closeButton.getX(), endX); |
| endX -= 7; |
| if (endX > startX) |
| MetalUtils.fillMetalPattern(this, g, startX, 3, endX - startX, |
| getHeight() - 6, Color.white, Color.gray); |
| } |
| g.setColor(savedColor); |
| } |
| |
| /** |
| * Sets the flag that controls whether the title pane is drawn in the |
| * palette style or the regular style. |
| * |
| * @param b the new value of the flag. |
| */ |
| public void setPalette(boolean b) |
| { |
| isPalette = b; |
| title.setVisible(!isPalette); |
| iconButton.setVisible(!isPalette && frame.isIconifiable()); |
| maxButton.setVisible(!isPalette && frame.isMaximizable()); |
| if (isPalette) |
| closeButton.setIcon(paletteCloseIcon); |
| else |
| closeButton.setIcon(closeIcon); |
| } |
| |
| /** |
| * Creates and returns a property change handler for the title pane. |
| * |
| * @return The property change handler. |
| */ |
| protected PropertyChangeListener createPropertyChangeListener() |
| { |
| return new MetalInternalFrameTitlePanePropertyChangeHandler(); |
| } |
| } |
| |