| /* BasicDesktopIconUI.java -- |
| Copyright (C) 2004, 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.basic; |
| |
| import java.awt.BorderLayout; |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Dimension; |
| import java.awt.Graphics; |
| import java.awt.Insets; |
| import java.awt.Rectangle; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.MouseEvent; |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import java.beans.PropertyVetoException; |
| |
| import javax.swing.Icon; |
| import javax.swing.JButton; |
| import javax.swing.JComponent; |
| import javax.swing.JDesktopPane; |
| import javax.swing.JInternalFrame; |
| import javax.swing.JInternalFrame.JDesktopIcon; |
| import javax.swing.SwingConstants; |
| import javax.swing.border.Border; |
| import javax.swing.event.MouseInputAdapter; |
| import javax.swing.event.MouseInputListener; |
| import javax.swing.plaf.ComponentUI; |
| import javax.swing.plaf.DesktopIconUI; |
| |
| /** |
| * This class acts as the UI delegate for JDesktopIcons for the Basic look and feel. |
| */ |
| public class BasicDesktopIconUI extends DesktopIconUI |
| { |
| /** |
| * This helper class handles mouse events that occur on the JDesktopIcon. |
| */ |
| public class MouseInputHandler extends MouseInputAdapter |
| { |
| /** The x offset from the MouseEvent coordinates to the top left corner. */ |
| private transient int xOffset; |
| |
| /** The y offset fromt he MouseEvent coordinates to the top left corner. */ |
| private transient int yOffset; |
| |
| /** A cached value of the JDesktopPane that parents this JDesktopIcon. */ |
| private transient JDesktopPane pane; |
| |
| /** |
| * This method is called when the mouse is dragged in the JDesktopIcon. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mouseDragged(MouseEvent e) |
| { |
| Rectangle b = desktopIcon.getBounds(); |
| |
| moveAndRepaint(desktopIcon, b.x + e.getX() - xOffset, |
| b.y + e.getY() - yOffset, b.width, b.height); |
| } |
| |
| /** |
| * This method is called when the mouse is moved in the JDesktopIcon. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mouseMoved(MouseEvent e) |
| { |
| // Nothing to do. |
| } |
| |
| /** |
| * This method is called when the mouse is pressed in the JDesktopIcon. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mousePressed(MouseEvent e) |
| { |
| xOffset = e.getX(); |
| yOffset = e.getY(); |
| pane = frame.getDesktopPane(); |
| if (pane != null) |
| pane.getDesktopManager().beginDraggingFrame(desktopIcon); |
| } |
| |
| /** |
| * This method is called when the mouse is released in the JDesktopIcon. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mouseReleased(MouseEvent e) |
| { |
| if (pane != null) |
| pane.getDesktopManager().endDraggingFrame(desktopIcon); |
| xOffset = 0; |
| yOffset = 0; |
| } |
| |
| /** |
| * This method moves and repaints the JDesktopIcon to the given bounds. |
| * |
| * @param f The JComponent to move and repaint. |
| * @param newX The new x coordinate. |
| * @param newY The new y coordinate. |
| * @param newWidth The new width. |
| * @param newHeight The new height. |
| */ |
| public void moveAndRepaint(JComponent f, int newX, int newY, int newWidth, |
| int newHeight) |
| { |
| if (pane != null) |
| pane.getDesktopManager().dragFrame(f, newX, newY); |
| else |
| desktopIcon.setBounds(newX, newY, newWidth, newHeight); |
| } |
| } |
| |
| /** |
| * This class acts as the border for the JDesktopIcon. |
| */ |
| private class DesktopIconBorder implements Border |
| { |
| /** The left inset value. */ |
| int left = 10; |
| |
| /** The top inset value. */ |
| int top = 4; |
| |
| /** The right inset value. */ |
| int right = top; |
| |
| /** The bottom inset value. */ |
| int bottom = top; |
| |
| /** |
| * This method returns the insets of the border. |
| * |
| * @param c The Component to find border insets for. |
| * |
| * @return The border insets. |
| */ |
| public Insets getBorderInsets(Component c) |
| { |
| return new Insets(top, left, bottom, right); |
| } |
| |
| /** |
| * This method returns whether the border is opaque. |
| * |
| * @return Whether the border is opaque. |
| */ |
| public boolean isBorderOpaque() |
| { |
| return true; |
| } |
| |
| /** |
| * This method paints the border. |
| * |
| * @param c The Component the border is in. |
| * @param g The Graphics object to paint with. |
| * @param x The x coordinate of the Component. |
| * @param y The y coordinate of the Component. |
| * @param width The width of the Component. |
| * @param height The height of the Component. |
| */ |
| public void paintBorder(Component c, Graphics g, int x, int y, int width, |
| int height) |
| { |
| g.translate(x, y); |
| Color saved = g.getColor(); |
| |
| g.setColor(Color.LIGHT_GRAY); |
| |
| g.fillRect(0, 0, left, height); |
| g.fillRect(0, 0, width, top); |
| g.fillRect(0, height - bottom, width, bottom); |
| g.fillRect(width - right, 0, right, height); |
| |
| g.setColor(Color.BLACK); |
| g.drawRect(0, 0, width - 1, height - 1); |
| |
| int fHeight = height / 4; |
| int hLeft = left / 2; |
| |
| g.setColor(Color.BLACK); |
| g.fillRect(hLeft, fHeight, 2, 2); |
| g.fillRect(hLeft, fHeight * 2, 2, 2); |
| g.fillRect(hLeft, fHeight * 3, 2, 2); |
| |
| g.setColor(saved); |
| g.translate(-x, -y); |
| } |
| } |
| |
| /** The static width and height of the iconSize. */ |
| private static final int iconSize = 16; |
| |
| /** |
| * This class represents the default frame icon when none |
| * is supplied by the JInternalFrame. |
| */ |
| static class InternalFrameDefaultMenuIcon implements Icon |
| { |
| /** |
| * This returns the icon height. |
| * |
| * @return The icon height. |
| */ |
| public int getIconHeight() |
| { |
| return iconSize; |
| } |
| |
| /** |
| * This returns the icon width. |
| * |
| * @return The icon width. |
| */ |
| public int getIconWidth() |
| { |
| return iconSize; |
| } |
| |
| /** |
| * This method paints the icon. |
| * |
| * @param c The Component this icon belongs to. |
| * @param g The Graphics object to paint with. |
| * @param x The x coordinate to paint at. |
| * @param y The y coordinate to paint at. |
| */ |
| public void paintIcon(Component c, Graphics g, int x, int y) |
| { |
| g.translate(x, y); |
| Color saved = g.getColor(); |
| |
| g.setColor(Color.BLUE); |
| g.fillRect(0, 0, iconSize, (int) ((double) iconSize / 3) + 1); |
| |
| g.setColor(Color.WHITE); |
| g.fillRect(0, (int) ((double) iconSize / 3), iconSize, iconSize * 5 / 6); |
| |
| g.setColor(Color.GRAY); |
| g.drawRect(0, 0, iconSize, iconSize); |
| |
| g.setColor(saved); |
| g.translate(-x, -y); |
| } |
| } |
| |
| /** The default JDesktopIcon width. */ |
| private static final int iconWidth = 160; |
| |
| /** The default JDesktopIcon height */ |
| private static final int iconHeight = 35; |
| |
| /** The JDesktopIcon this UI delegate represents. */ |
| protected JDesktopIcon desktopIcon; |
| |
| /** The JInternalFrame associated with the JDesktopIcon. */ |
| protected JInternalFrame frame; |
| |
| /** The MouseListener responsible for reacting to MouseEvents on the JDesktopIcon. */ |
| private transient MouseInputListener mouseHandler; |
| |
| /** The Button in the JDesktopIcon responsible for deiconifying it. |
| * This is package-private to avoid an accessor method. */ |
| transient BoundButton button; |
| |
| /** The PropertyChangeListener listening to the JDesktopIcon. */ |
| private transient PropertyChangeListener propertyHandler; |
| |
| /** The default icon used when no frame icon is given by the JInternalFrame. */ |
| static Icon defaultIcon = new InternalFrameDefaultMenuIcon(); |
| |
| /** |
| * This is a helper class that is used in JDesktopIcon and gives the Button a predetermined size. |
| */ |
| private class BoundButton extends JButton |
| { |
| /** |
| * Creates a new BoundButton object. |
| * |
| * @param title The title of the button. |
| */ |
| public BoundButton(String title) |
| { |
| super(title); |
| } |
| |
| /** |
| * This method returns a standard size (based on the defaults of the JDesktopIcon) and the insets. |
| * |
| * @return The preferred size of the JDesktopIcon. |
| */ |
| public Dimension getPreferredSize() |
| { |
| Insets insets = desktopIcon.getInsets(); |
| return new Dimension(iconWidth - insets.left - insets.right, |
| iconHeight - insets.top - insets.bottom); |
| } |
| |
| /** |
| * This method returns the minimum size of the button. |
| * |
| * @return The minimum size of the button. |
| */ |
| public Dimension getMinimumSize() |
| { |
| return getPreferredSize(); |
| } |
| |
| /** |
| * This method returns the maximum size of the button. |
| * |
| * @return The maximum size of the button. |
| */ |
| public Dimension getMaximumSize() |
| { |
| return getPreferredSize(); |
| } |
| } |
| |
| /** |
| * Creates a new BasicDesktopIconUI object. |
| */ |
| public BasicDesktopIconUI() |
| { |
| // Nothing to do here. |
| } |
| |
| /** |
| * This method creates a new BasicDesktopIconUI for the given JComponent. |
| * |
| * @param c The JComponent to create a UI for. |
| * |
| * @return A new BasicDesktopIconUI. |
| */ |
| public static ComponentUI createUI(JComponent c) |
| { |
| return new BasicDesktopIconUI(); |
| } |
| |
| /** |
| * This method installs the UI for the given JComponent. |
| * |
| * @param c The JComponent to install this UI for. |
| */ |
| public void installUI(JComponent c) |
| { |
| if (c instanceof JDesktopIcon) |
| { |
| desktopIcon = (JDesktopIcon) c; |
| desktopIcon.setLayout(new BorderLayout()); |
| frame = desktopIcon.getInternalFrame(); |
| |
| installDefaults(); |
| installComponents(); |
| installListeners(); |
| |
| desktopIcon.setOpaque(true); |
| } |
| } |
| |
| /** |
| * This method uninstalls the UI for the given JComponent. |
| * |
| * @param c The JComponent to uninstall this UI for. |
| */ |
| public void uninstallUI(JComponent c) |
| { |
| desktopIcon.setOpaque(false); |
| |
| uninstallListeners(); |
| uninstallComponents(); |
| uninstallDefaults(); |
| |
| frame = null; |
| desktopIcon.setLayout(null); |
| desktopIcon = null; |
| } |
| |
| /** |
| * This method installs the necessary sub components for the JDesktopIcon. |
| */ |
| protected void installComponents() |
| { |
| // Try to create a button based on what the frame's |
| // state is currently |
| button = new BoundButton(frame.getTitle()); |
| button.setHorizontalAlignment(SwingConstants.LEFT); |
| button.setHorizontalTextPosition(SwingConstants.TRAILING); |
| |
| Icon use = frame.getFrameIcon(); |
| if (use == null) |
| use = defaultIcon; |
| button.setIcon(use); |
| |
| desktopIcon.add(button, SwingConstants.CENTER); |
| } |
| |
| /** |
| * This method uninstalls the sub components for the JDesktopIcon. |
| */ |
| protected void uninstallComponents() |
| { |
| desktopIcon.remove(button); |
| |
| button = null; |
| } |
| |
| /** |
| * This method installs the listeners needed by this UI. |
| */ |
| protected void installListeners() |
| { |
| mouseHandler = createMouseInputListener(); |
| |
| desktopIcon.addMouseMotionListener(mouseHandler); |
| desktopIcon.addMouseListener(mouseHandler); |
| |
| propertyHandler = new PropertyChangeListener() |
| { |
| public void propertyChange(PropertyChangeEvent e) |
| { |
| if (e.getPropertyName().equals(JInternalFrame.TITLE_PROPERTY)) |
| button.setText(desktopIcon.getInternalFrame().getTitle()); |
| else if (e.getPropertyName().equals(JInternalFrame.FRAME_ICON_PROPERTY)) |
| { |
| Icon use = desktopIcon.getInternalFrame().getFrameIcon(); |
| if (use == null) |
| use = defaultIcon; |
| button.setIcon(use); |
| } |
| desktopIcon.revalidate(); |
| desktopIcon.repaint(); |
| } |
| }; |
| frame.addPropertyChangeListener(propertyHandler); |
| |
| button.addActionListener(new ActionListener() |
| { |
| public void actionPerformed(ActionEvent e) |
| { |
| deiconize(); |
| } |
| }); |
| } |
| |
| /** |
| * This method uninstalls the listeners needed by the UI. |
| */ |
| protected void uninstallListeners() |
| { |
| // button is nulled so no need to remove it. |
| |
| frame.removePropertyChangeListener(propertyHandler); |
| propertyHandler = null; |
| |
| desktopIcon.removeMouseMotionListener(mouseHandler); |
| desktopIcon.removeMouseListener(mouseHandler); |
| } |
| |
| /** |
| * This method installs the defaults for the JDesktopIcon. |
| */ |
| protected void installDefaults() |
| { |
| // FIXME: Move border to defaults. |
| desktopIcon.setBorder(new DesktopIconBorder()); |
| } |
| |
| /** |
| * This method uninstalls the defaults for the JDesktopIcon. |
| */ |
| protected void uninstallDefaults() |
| { |
| desktopIcon.setBorder(null); |
| } |
| |
| /** |
| * This method creates a new MouseInputListener for the JDesktopIcon. |
| * |
| * @return A new MouseInputListener. |
| */ |
| protected MouseInputListener createMouseInputListener() |
| { |
| return new MouseInputHandler(); |
| } |
| |
| /** |
| * This method returns the preferred size for the given JComponent. |
| * |
| * @param c The JComponent to find a preferred size for. |
| * |
| * @return The preferred size. |
| */ |
| public Dimension getPreferredSize(JComponent c) |
| { |
| return new Dimension(iconWidth, iconHeight); |
| } |
| |
| /** |
| * This method returns the minimum size for the given JComponent. |
| * |
| * @param c The JComponent to find a minimum size for. |
| * |
| * @return The minimum size. |
| */ |
| public Dimension getMinimumSize(JComponent c) |
| { |
| return getPreferredSize(c); |
| } |
| |
| /** |
| * This method returns the maximum size for the given JComponent. |
| * |
| * @param c The JComponent to find a maximum size for. |
| * |
| * @return The maximum size. |
| */ |
| public Dimension getMaximumSize(JComponent c) |
| { |
| return getPreferredSize(c); |
| } |
| |
| /** |
| * This method returns the insets of the given JComponent. |
| * |
| * @param c The JComponent to find insets for. |
| * |
| * @return The insets of the given JComponent. |
| */ |
| public Insets getInsets(JComponent c) |
| { |
| return c.getInsets(); |
| } |
| |
| /** |
| * This method deiconizes the JInternalFrame associated with the JDesktopIcon. |
| */ |
| public void deiconize() |
| { |
| try |
| { |
| frame.setIcon(false); |
| } |
| catch (PropertyVetoException pve) |
| { |
| // We do nothing if the attempt has been vetoed. |
| } |
| } |
| } |