0N/A/*
2362N/A * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage javax.swing.plaf.synth;
0N/A
0N/Aimport java.awt.*;
0N/Aimport java.awt.event.*;
0N/Aimport javax.swing.*;
0N/Aimport javax.swing.plaf.*;
0N/Aimport javax.swing.plaf.basic.BasicInternalFrameTitlePane;
0N/Aimport java.beans.PropertyChangeListener;
0N/Aimport java.beans.PropertyChangeEvent;
0N/Aimport java.beans.PropertyVetoException;
0N/Aimport sun.swing.SwingUtilities2;
0N/A
0N/A/**
0N/A * The class that manages a synth title bar
0N/A *
0N/A * @author David Kloba
0N/A * @author Joshua Outwater
0N/A * @author Steve Wilson
0N/A */
0N/Aclass SynthInternalFrameTitlePane extends BasicInternalFrameTitlePane
0N/A implements SynthUI, PropertyChangeListener {
0N/A
0N/A protected JPopupMenu systemPopupMenu;
0N/A protected JButton menuButton;
0N/A
0N/A private SynthStyle style;
0N/A private int titleSpacing;
0N/A private int buttonSpacing;
0N/A // Alignment for the title, one of SwingConstants.(LEADING|TRAILING|CENTER)
0N/A private int titleAlignment;
0N/A
0N/A public SynthInternalFrameTitlePane(JInternalFrame f) {
0N/A super(f);
0N/A }
0N/A
0N/A public String getUIClassID() {
0N/A return "InternalFrameTitlePaneUI";
0N/A }
0N/A
0N/A public SynthContext getContext(JComponent c) {
0N/A return getContext(c, getComponentState(c));
0N/A }
0N/A
0N/A public SynthContext getContext(JComponent c, int state) {
0N/A return SynthContext.getContext(SynthContext.class, c,
0N/A SynthLookAndFeel.getRegion(c), style, state);
0N/A }
0N/A
0N/A private Region getRegion(JComponent c) {
0N/A return SynthLookAndFeel.getRegion(c);
0N/A }
0N/A
0N/A private int getComponentState(JComponent c) {
0N/A if (frame != null) {
0N/A if (frame.isSelected()) {
0N/A return SELECTED;
0N/A }
0N/A }
0N/A return SynthLookAndFeel.getComponentState(c);
0N/A }
0N/A
0N/A protected void addSubComponents() {
0N/A menuButton.setName("InternalFrameTitlePane.menuButton");
0N/A iconButton.setName("InternalFrameTitlePane.iconifyButton");
0N/A maxButton.setName("InternalFrameTitlePane.maximizeButton");
0N/A closeButton.setName("InternalFrameTitlePane.closeButton");
0N/A
0N/A add(menuButton);
0N/A add(iconButton);
0N/A add(maxButton);
0N/A add(closeButton);
0N/A }
0N/A
0N/A protected void installListeners() {
0N/A super.installListeners();
0N/A frame.addPropertyChangeListener(this);
0N/A addPropertyChangeListener(this);
0N/A }
0N/A
0N/A protected void uninstallListeners() {
0N/A frame.removePropertyChangeListener(this);
0N/A removePropertyChangeListener(this);
0N/A super.uninstallListeners();
0N/A }
0N/A
0N/A private void updateStyle(JComponent c) {
0N/A SynthContext context = getContext(this, ENABLED);
0N/A SynthStyle oldStyle = style;
0N/A style = SynthLookAndFeel.updateStyle(context, this);
0N/A if (style != oldStyle) {
0N/A maxIcon =
0N/A style.getIcon(context,"InternalFrameTitlePane.maximizeIcon");
0N/A minIcon =
0N/A style.getIcon(context,"InternalFrameTitlePane.minimizeIcon");
0N/A iconIcon =
0N/A style.getIcon(context,"InternalFrameTitlePane.iconifyIcon");
0N/A closeIcon =
0N/A style.getIcon(context,"InternalFrameTitlePane.closeIcon");
0N/A titleSpacing = style.getInt(context,
0N/A "InternalFrameTitlePane.titleSpacing", 2);
0N/A buttonSpacing = style.getInt(context,
0N/A "InternalFrameTitlePane.buttonSpacing", 2);
0N/A String alignString = (String)style.get(context,
0N/A "InternalFrameTitlePane.titleAlignment");
0N/A titleAlignment = SwingConstants.LEADING;
0N/A if (alignString != null) {
0N/A alignString = alignString.toUpperCase();
0N/A if (alignString.equals("TRAILING")) {
0N/A titleAlignment = SwingConstants.TRAILING;
0N/A }
0N/A else if (alignString.equals("CENTER")) {
0N/A titleAlignment = SwingConstants.CENTER;
0N/A }
0N/A }
0N/A }
0N/A context.dispose();
0N/A }
0N/A
0N/A protected void installDefaults() {
0N/A super.installDefaults();
0N/A updateStyle(this);
0N/A }
0N/A
0N/A protected void uninstallDefaults() {
0N/A SynthContext context = getContext(this, ENABLED);
0N/A style.uninstallDefaults(context);
0N/A context.dispose();
0N/A style = null;
0N/A JInternalFrame.JDesktopIcon di = frame.getDesktopIcon();
0N/A if(di != null && di.getComponentPopupMenu() == systemPopupMenu) {
0N/A // Release link to systemMenu from the JInternalFrame
0N/A di.setComponentPopupMenu(null);
0N/A }
0N/A super.uninstallDefaults();
0N/A }
0N/A
0N/A private static class JPopupMenuUIResource extends JPopupMenu implements
0N/A UIResource { }
0N/A
0N/A protected void assembleSystemMenu() {
0N/A systemPopupMenu = new JPopupMenuUIResource();
0N/A addSystemMenuItems(systemPopupMenu);
0N/A enableActions();
0N/A menuButton = createNoFocusButton();
0N/A updateMenuIcon();
0N/A menuButton.addMouseListener(new MouseAdapter() {
0N/A public void mousePressed(MouseEvent e) {
0N/A try {
0N/A frame.setSelected(true);
0N/A } catch(PropertyVetoException pve) {
0N/A }
0N/A showSystemMenu();
0N/A }
0N/A });
0N/A JPopupMenu p = frame.getComponentPopupMenu();
0N/A if (p == null || p instanceof UIResource) {
0N/A frame.setComponentPopupMenu(systemPopupMenu);
0N/A }
0N/A if (frame.getDesktopIcon() != null) {
0N/A p = frame.getDesktopIcon().getComponentPopupMenu();
0N/A if (p == null || p instanceof UIResource) {
0N/A frame.getDesktopIcon().setComponentPopupMenu(systemPopupMenu);
0N/A }
0N/A }
0N/A setInheritsPopupMenu(true);
0N/A }
0N/A
0N/A protected void addSystemMenuItems(JPopupMenu menu) {
0N/A // PENDING: this should all be localizable!
614N/A JMenuItem mi = menu.add(restoreAction);
0N/A mi.setMnemonic('R');
614N/A mi = menu.add(moveAction);
0N/A mi.setMnemonic('M');
614N/A mi = menu.add(sizeAction);
0N/A mi.setMnemonic('S');
614N/A mi = menu.add(iconifyAction);
0N/A mi.setMnemonic('n');
614N/A mi = menu.add(maximizeAction);
0N/A mi.setMnemonic('x');
0N/A menu.add(new JSeparator());
614N/A mi = menu.add(closeAction);
0N/A mi.setMnemonic('C');
0N/A }
0N/A
0N/A protected void showSystemMenu() {
0N/A Insets insets = frame.getInsets();
0N/A if (!frame.isIcon()) {
621N/A systemPopupMenu.show(frame, menuButton.getX(), getY() + getHeight());
0N/A } else {
0N/A systemPopupMenu.show(menuButton,
0N/A getX() - insets.left - insets.right,
0N/A getY() - systemPopupMenu.getPreferredSize().height -
0N/A insets.bottom - insets.top);
0N/A }
0N/A }
0N/A
0N/A // SynthInternalFrameTitlePane has no UI, we'll invoke paint on it.
0N/A public void paintComponent(Graphics g) {
0N/A SynthContext context = getContext(this);
0N/A SynthLookAndFeel.update(context, g);
0N/A context.getPainter().paintInternalFrameTitlePaneBackground(context,
0N/A g, 0, 0, getWidth(), getHeight());
0N/A paint(context, g);
0N/A context.dispose();
0N/A }
0N/A
0N/A protected void paint(SynthContext context, Graphics g) {
0N/A String title = frame.getTitle();
0N/A
0N/A if (title != null) {
0N/A SynthStyle style = context.getStyle();
0N/A
0N/A g.setColor(style.getColor(context, ColorType.TEXT_FOREGROUND));
0N/A g.setFont(style.getFont(context));
0N/A
0N/A // Center text vertically.
0N/A FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g);
0N/A int baseline = (getHeight() + fm.getAscent() - fm.getLeading() -
0N/A fm.getDescent()) / 2;
0N/A JButton lastButton = null;
0N/A if (frame.isIconifiable()) {
0N/A lastButton = iconButton;
0N/A }
0N/A else if (frame.isMaximizable()) {
0N/A lastButton = maxButton;
0N/A }
0N/A else if (frame.isClosable()) {
0N/A lastButton = closeButton;
0N/A }
0N/A int maxX;
0N/A int minX;
0N/A boolean ltr = SynthLookAndFeel.isLeftToRight(frame);
0N/A int titleAlignment = this.titleAlignment;
0N/A if (ltr) {
0N/A if (lastButton != null) {
0N/A maxX = lastButton.getX() - titleSpacing;
0N/A }
0N/A else {
0N/A maxX = frame.getWidth() - frame.getInsets().right -
0N/A titleSpacing;
0N/A }
0N/A minX = menuButton.getX() + menuButton.getWidth() +
0N/A titleSpacing;
0N/A }
0N/A else {
0N/A if (lastButton != null) {
0N/A minX = lastButton.getX() + lastButton.getWidth() +
0N/A titleSpacing;
0N/A }
0N/A else {
0N/A minX = frame.getInsets().left + titleSpacing;
0N/A }
0N/A maxX = menuButton.getX() - titleSpacing;
0N/A if (titleAlignment == SwingConstants.LEADING) {
0N/A titleAlignment = SwingConstants.TRAILING;
0N/A }
0N/A else if (titleAlignment == SwingConstants.TRAILING) {
0N/A titleAlignment = SwingConstants.LEADING;
0N/A }
0N/A }
0N/A String clippedTitle = getTitle(title, fm, maxX - minX);
0N/A if (clippedTitle == title) {
0N/A // String fit, align as necessary.
0N/A if (titleAlignment == SwingConstants.TRAILING) {
0N/A minX = maxX - style.getGraphicsUtils(context).
0N/A computeStringWidth(context, g.getFont(), fm, title);
0N/A }
0N/A else if (titleAlignment == SwingConstants.CENTER) {
0N/A int width = style.getGraphicsUtils(context).
0N/A computeStringWidth(context, g.getFont(), fm, title);
0N/A minX = Math.max(minX, (getWidth() - width) / 2);
0N/A minX = Math.min(maxX - width, minX);
0N/A }
0N/A }
0N/A style.getGraphicsUtils(context).paintText(
0N/A context, g, clippedTitle, minX, baseline - fm.getAscent(), -1);
0N/A }
0N/A }
0N/A
0N/A public void paintBorder(SynthContext context, Graphics g, int x,
0N/A int y, int w, int h) {
0N/A context.getPainter().paintInternalFrameTitlePaneBorder(context,
0N/A g, x, y, w, h);
0N/A }
0N/A
0N/A protected LayoutManager createLayout() {
0N/A SynthContext context = getContext(this);
0N/A LayoutManager lm =
0N/A (LayoutManager)style.get(context, "InternalFrameTitlePane.titlePaneLayout");
0N/A context.dispose();
0N/A return (lm != null) ? lm : new SynthTitlePaneLayout();
0N/A }
0N/A
0N/A public void propertyChange(PropertyChangeEvent evt) {
0N/A if (evt.getSource() == this) {
0N/A if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
0N/A updateStyle(this);
0N/A }
0N/A }
0N/A else {
0N/A // Changes for the internal frame
0N/A if (evt.getPropertyName() == JInternalFrame.FRAME_ICON_PROPERTY) {
0N/A updateMenuIcon();
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Resets the menuButton icon to match that of the frame.
0N/A */
0N/A private void updateMenuIcon() {
0N/A Icon frameIcon = frame.getFrameIcon();
0N/A SynthContext context = getContext(this);
0N/A if (frameIcon != null) {
0N/A Dimension maxSize = (Dimension)context.getStyle().get(context,
0N/A "InternalFrameTitlePane.maxFrameIconSize");
0N/A int maxWidth = 16;
0N/A int maxHeight = 16;
0N/A if (maxSize != null) {
0N/A maxWidth = maxSize.width;
0N/A maxHeight = maxSize.height;
0N/A }
0N/A if ((frameIcon.getIconWidth() > maxWidth ||
0N/A frameIcon.getIconHeight() > maxHeight) &&
0N/A (frameIcon instanceof ImageIcon)) {
0N/A frameIcon = new ImageIcon(((ImageIcon)frameIcon).
0N/A getImage().getScaledInstance(maxWidth, maxHeight,
0N/A Image.SCALE_SMOOTH));
0N/A }
0N/A }
0N/A context.dispose();
0N/A menuButton.setIcon(frameIcon);
0N/A }
0N/A
0N/A
0N/A class SynthTitlePaneLayout implements LayoutManager {
0N/A public void addLayoutComponent(String name, Component c) {}
0N/A public void removeLayoutComponent(Component c) {}
0N/A public Dimension preferredLayoutSize(Container c) {
0N/A return minimumLayoutSize(c);
0N/A }
0N/A
0N/A public Dimension minimumLayoutSize(Container c) {
0N/A SynthContext context = getContext(
0N/A SynthInternalFrameTitlePane.this);
0N/A int width = 0;
0N/A int height = 0;
0N/A
0N/A int buttonCount = 0;
0N/A Dimension pref;
0N/A
0N/A if (frame.isClosable()) {
0N/A pref = closeButton.getPreferredSize();
0N/A width += pref.width;
0N/A height = Math.max(pref.height, height);
0N/A buttonCount++;
0N/A }
0N/A if (frame.isMaximizable()) {
0N/A pref = maxButton.getPreferredSize();
0N/A width += pref.width;
0N/A height = Math.max(pref.height, height);
0N/A buttonCount++;
0N/A }
0N/A if (frame.isIconifiable()) {
0N/A pref = iconButton.getPreferredSize();
0N/A width += pref.width;
0N/A height = Math.max(pref.height, height);
0N/A buttonCount++;
0N/A }
0N/A pref = menuButton.getPreferredSize();
0N/A width += pref.width;
0N/A height = Math.max(pref.height, height);
0N/A
0N/A width += Math.max(0, (buttonCount - 1) * buttonSpacing);
0N/A
0N/A FontMetrics fm = SynthInternalFrameTitlePane.this.getFontMetrics(
0N/A getFont());
0N/A SynthGraphicsUtils graphicsUtils = context.getStyle().
0N/A getGraphicsUtils(context);
0N/A String frameTitle = frame.getTitle();
0N/A int title_w = frameTitle != null ? graphicsUtils.
0N/A computeStringWidth(context, fm.getFont(),
0N/A fm, frameTitle) : 0;
0N/A int title_length = frameTitle != null ? frameTitle.length() : 0;
0N/A
0N/A // Leave room for three characters in the title.
0N/A if (title_length > 3) {
0N/A int subtitle_w = graphicsUtils.computeStringWidth(context,
0N/A fm.getFont(), fm, frameTitle.substring(0, 3) + "...");
0N/A width += (title_w < subtitle_w) ? title_w : subtitle_w;
0N/A } else {
0N/A width += title_w;
0N/A }
0N/A
0N/A height = Math.max(fm.getHeight() + 2, height);
0N/A
0N/A width += titleSpacing + titleSpacing;
0N/A
0N/A Insets insets = getInsets();
0N/A height += insets.top + insets.bottom;
0N/A width += insets.left + insets.right;
0N/A context.dispose();
0N/A return new Dimension(width, height);
0N/A }
0N/A
0N/A private int center(Component c, Insets insets, int x,
0N/A boolean trailing) {
0N/A Dimension pref = c.getPreferredSize();
0N/A if (trailing) {
0N/A x -= pref.width;
0N/A }
0N/A c.setBounds(x, insets.top +
0N/A (getHeight() - insets.top - insets.bottom -
0N/A pref.height) / 2, pref.width, pref.height);
0N/A if (pref.width > 0) {
0N/A if (trailing) {
0N/A return x - buttonSpacing;
0N/A }
0N/A return x + pref.width + buttonSpacing;
0N/A }
0N/A return x;
0N/A }
0N/A
0N/A public void layoutContainer(Container c) {
0N/A Insets insets = c.getInsets();
0N/A Dimension pref;
0N/A
0N/A if (SynthLookAndFeel.isLeftToRight(frame)) {
0N/A center(menuButton, insets, insets.left, false);
0N/A int x = getWidth() - insets.right;
0N/A if (frame.isClosable()) {
0N/A x = center(closeButton, insets, x, true);
0N/A }
0N/A if (frame.isMaximizable()) {
0N/A x = center(maxButton, insets, x, true);
0N/A }
0N/A if (frame.isIconifiable()) {
0N/A x = center(iconButton, insets, x, true);
0N/A }
0N/A }
0N/A else {
0N/A center(menuButton, insets, getWidth() - insets.right,
0N/A true);
0N/A int x = insets.left;
0N/A if (frame.isClosable()) {
0N/A x = center(closeButton, insets, x, false);
0N/A }
0N/A if (frame.isMaximizable()) {
0N/A x = center(maxButton, insets, x, false);
0N/A }
0N/A if (frame.isIconifiable()) {
0N/A x = center(iconButton, insets, x, false);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A private JButton createNoFocusButton() {
0N/A JButton button = new JButton();
0N/A button.setFocusable(false);
0N/A button.setMargin(new Insets(0,0,0,0));
0N/A return button;
0N/A }
0N/A}