All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jtattoo.plaf.BaseRootPaneUI Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved.
 *  
 * JTattoo is multiple licensed. If your are an open source developer you can use
 * it under the terms and conditions of the GNU General Public License version 2.0
 * or later as published by the Free Software Foundation.
 *  
 * see: gpl-2.0.txt
 * 
 * If you pay for a license you will become a registered user who could use the
 * software under the terms and conditions of the GNU Lesser General Public License
 * version 2.0 or later with classpath exception as published by the Free Software
 * Foundation.
 * 
 * see: lgpl-2.0.txt
 * see: classpath-exception.txt
 * 
 * Registered users could also use JTattoo under the terms and conditions of the 
 * Apache License, Version 2.0 as published by the Apache Software Foundation.
 *  
 * see: APACHE-LICENSE-2.0.txt
 */
package com.jtattoo.plaf;

import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicRootPaneUI;

/**
 * This source is a modified copy of javax.swing.plaf.metal.MetalRootPaneUI Provides the base look and feel
 * implementation of RootPaneUI.
 * 

* BaseRootPaneUI provides support for the windowDecorationStyle property of * JRootPane. BaseRootPaneUI does this by way of installing a custom * LayoutManager, a private Component to render the appropriate widgets, and a private * Border. The LayoutManager is always installed, regardless of the value of the * windowDecorationStyle property, but the Border and Component are only * installed/added if the windowDecorationStyle is other than JRootPane.NONE. *

* Warning: * Serialized objects of this class will not be compatible with future Swing releases. The current serialization support * is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, * support for long term storage of all JavaBeans TM * has been added to the java.beans package. Please see {@link java.beans.XMLEncoder}. * * @version 1.20 04/27/04 * @author Terry Kellerman * @author Michael Hagen * @since 1.4 */ public class BaseRootPaneUI extends BasicRootPaneUI { // Konstanten aus javax.swing.JRootPane damit Attribute aus Java 1.4 sich mit Java 1.3 uebersetzen lassen public static final int NONE = 0; public static final int FRAME = 1; public static final int PLAIN_DIALOG = 2; public static final int INFORMATION_DIALOG = 3; public static final int ERROR_DIALOG = 4; public static final int COLOR_CHOOSER_DIALOG = 5; public static final int FILE_CHOOSER_DIALOG = 6; public static final int QUESTION_DIALOG = 7; public static final int WARNING_DIALOG = 8; // Konstanten aus java.awt.Frame damit Attribute aus Java 1.4 sich mit Java 1.3 uebersetzen lassen public static final int MAXIMIZED_HORIZ = 2; public static final int MAXIMIZED_VERT = 4; public static final int MAXIMIZED_BOTH = MAXIMIZED_VERT | MAXIMIZED_HORIZ; private static final String[] borderKeys = new String[]{ null, "RootPane.frameBorder", "RootPane.plainDialogBorder", "RootPane.informationDialogBorder", "RootPane.errorDialogBorder", "RootPane.colorChooserDialogBorder", "RootPane.fileChooserDialogBorder", "RootPane.questionDialogBorder", "RootPane.warningDialogBorder" }; /** * The minimum/maximum size of a Window */ private static final Dimension MINIMUM_SIZE = new Dimension(120, 80); private static final Dimension MAXIMUM_SIZE = Toolkit.getDefaultToolkit().getScreenSize(); /** * The amount of space (in pixels) that the cursor is changed on. */ private static final int CORNER_DRAG_WIDTH = 16; /** * Region from edges that dragging is active from. */ private static final int BORDER_DRAG_THICKNESS = 5; /** * Window the JRootPane is in. */ private Window window; /** * JComponent providing window decorations. This will be null if not providing window decorations. */ private JComponent titlePane; /** * MouseInputListener that is added to the parent Window the JRootPane is * contained in. */ private MouseInputListener mouseInputListener; /** * WindowListener that is added to the parent Window the JRootPane is * contained in. */ private WindowListener windowListener; /** * WindowListener that is added to the parent Window the JRootPane is * contained in. */ private PropertyChangeListener propertyChangeListener; /** * The LayoutManager that is set on the JRootPane. */ private LayoutManager layoutManager; /** * LayoutManager of the JRootPane before we replaced it. */ private LayoutManager savedOldLayout; /** * JRootPane providing the look and feel for. */ private JRootPane root; private Cursor savedCursor = null; /** * Cursor used to track the cursor set by the user. This is initially * Cursor.DEFAULT_CURSOR. */ /** * Creates a UI for a JRootPane. * * @param c the JRootPane the RootPaneUI will be created for * @return the RootPaneUI implementation for the passed in JRootPane */ public static ComponentUI createUI(JComponent c) { return new BaseRootPaneUI(); } @Override public void installUI(JComponent c) { super.installUI(c); root = (JRootPane) c; if (root.getWindowDecorationStyle() != NONE) { installClientDecorations(root); } } @Override public void uninstallUI(JComponent c) { super.uninstallUI(c); uninstallClientDecorations(root); layoutManager = null; mouseInputListener = null; root = null; } @Override protected void installListeners(JRootPane root) { super.installListeners(root); if (root.getWindowDecorationStyle() == NONE) { propertyChangeListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if ("ancestor".equals(evt.getPropertyName())) { if (getRootPane() != null && getRootPane().getParent() instanceof Window) { window = (Window) getRootPane().getParent(); windowListener = new WindowAdapter() { @Override public void windowActivated(WindowEvent e) { if (getRootPane() != null) { getRootPane().repaint(); } } @Override public void windowDeactivated(WindowEvent e) { if (getRootPane() != null) { getRootPane().repaint(); } } }; window.addWindowListener(windowListener); } } } }; root.addPropertyChangeListener(propertyChangeListener); } } @Override protected void uninstallListeners(JRootPane root) { super.uninstallListeners(root); if (root.getWindowDecorationStyle() == NONE) { if (root.getParent() instanceof Window && windowListener != null) { window = (Window) root.getParent(); window.removeWindowListener(windowListener); } root.removePropertyChangeListener(propertyChangeListener); } } public void installBorder(JRootPane root) { int style = root.getWindowDecorationStyle(); if (style == NONE) { LookAndFeel.uninstallBorder(root); } else { LookAndFeel.installBorder(root, borderKeys[style]); } } /** * Removes any border that may have been installed. * * @param root The root pane */ public void uninstallBorder(JRootPane root) { LookAndFeel.uninstallBorder(root); } /** * Installs the necessary Listeners on the parent Window, if there is one. *

* This takes the parent so that cleanup can be done from removeNotify, at which point the parent * hasn't been reset yet. * * @param root The root pane * @param parent The parent of the JRootPane */ public void installWindowListeners(JRootPane root, Component parent) { if (parent instanceof Window) { window = (Window) parent; } else { window = SwingUtilities.getWindowAncestor(parent); } if (window != null) { if (mouseInputListener == null) { mouseInputListener = createWindowMouseInputListener(root); } window.addMouseListener(mouseInputListener); window.addMouseMotionListener(mouseInputListener); } } /** * Uninstalls the necessary Listeners on the Window the Listeners were last installed on. * * @param root The root pane */ public void uninstallWindowListeners(JRootPane root) { if (window != null) { window.removeMouseListener(mouseInputListener); window.removeMouseMotionListener(mouseInputListener); } } /** * Installs the appropriate LayoutManager on the JRootPane to render the window decorations. * * @param root The root pane */ public void installLayout(JRootPane root) { if (layoutManager == null) { layoutManager = createLayoutManager(); } savedOldLayout = root.getLayout(); root.setLayout(layoutManager); } public void uninstallLayout(JRootPane root) { if (savedOldLayout != null) { root.setLayout(savedOldLayout); savedOldLayout = null; } } public void installClientDecorations(JRootPane root) { installBorder(root); if (titlePane == null) { setTitlePane(root, createTitlePane(root)); } installWindowListeners(root, root.getParent()); installLayout(root); if (window != null) { //savedCursor = window.getCursor(); root.revalidate(); root.repaint(); } } public void uninstallClientDecorations(JRootPane root) { uninstallBorder(root); uninstallWindowListeners(root); setTitlePane(root, null); uninstallLayout(root); int style = root.getWindowDecorationStyle(); if (style == NONE) { root.repaint(); root.revalidate(); } // Reset the cursor, as we may have changed it to a resize cursor if (window != null && savedCursor != null) { window.setCursor(savedCursor); savedCursor = null; } window = null; } /** * Returns the JComponent to render the window decoration style. * * @param root The root pane * @return The title pane */ public JComponent createTitlePane(JRootPane root) { return new BaseTitlePane(root, this); } /** * Returns a MouseListener that will be added to the Window containing the * JRootPane. * * @param root The root pane * @return The mouse listener */ public MouseInputListener createWindowMouseInputListener(JRootPane root) { return new MouseInputHandler(); } /** * Returns a LayoutManager that will be set on the JRootPane. * * @return The layout manager */ public LayoutManager createLayoutManager() { return new BaseRootLayout(); } /** * Sets the window title pane -- the JComponent used to provide a plaf a way to override the native operating * system's window title pane with one whose look and feel are controlled by the plaf. The plaf creates and sets * this value; the default is null, implying a native operating system window title pane. * * @param root the JRootPane where to set the title pane * @param titlePane the JComponent to use for the window title pane. */ public void setTitlePane(JRootPane root, JComponent titlePane) { JComponent oldTitlePane = internalGetTitlePane(); if ((oldTitlePane == null && titlePane == null) || (oldTitlePane != null && oldTitlePane.equals(titlePane))) { return; } JLayeredPane layeredPane = root.getLayeredPane(); if (oldTitlePane != null) { oldTitlePane.setVisible(false); layeredPane.remove(oldTitlePane); } if (titlePane != null) { layeredPane.add(titlePane, JLayeredPane.FRAME_CONTENT_LAYER); titlePane.setVisible(true); } this.titlePane = titlePane; } /** * Returns the BaseTitlePane rendering the title pane. If this returns null, it implies there is no need * to render window decorations. * * @return the current window title pane, or null * @see #setTitlePane */ public BaseTitlePane getTitlePane() { if (titlePane instanceof BaseTitlePane) { return (BaseTitlePane)titlePane; } return null; } private JComponent internalGetTitlePane() { return titlePane; } public JRootPane getRootPane() { return root; } @Override public void propertyChange(PropertyChangeEvent e) { super.propertyChange(e); String propertyName = e.getPropertyName(); JRootPane rp = (JRootPane) e.getSource(); if ("windowDecorationStyle".equals(propertyName)) { int style = rp.getWindowDecorationStyle(); // This is potentially more than needs to be done, // but it rarely happens and makes the install/uninstall process // simpler. BaseTitlePane also assumes it will be recreated if // the decoration style changes. uninstallClientDecorations(rp); if (style != NONE) { installClientDecorations(rp); } } else if ("ancestor".equals(propertyName)) { uninstallWindowListeners(rp); if (rp.getWindowDecorationStyle() != NONE) { installWindowListeners(rp, rp.getParent()); } } } private boolean isDynamicLayout() { return AbstractLookAndFeel.getTheme().isDynamicLayout(); } //------------------------------------------------------------------------------ private static class BaseRootLayout implements LayoutManager2 { /** * Returns the amount of space the layout would like to have. * * @param the Container for which this layout manager is being used * @return a Dimension object containing the layout's preferred size */ @Override public Dimension preferredLayoutSize(Container parent) { Dimension cpd, mbd, tpd; int cpWidth = 0; int cpHeight = 0; int mbWidth = 0; int mbHeight = 0; int tpWidth = 0; Insets i = parent.getInsets(); JRootPane root = (JRootPane) parent; if (root.getContentPane() != null) { cpd = root.getContentPane().getPreferredSize(); } else { cpd = root.getSize(); } if (cpd != null) { cpWidth = cpd.width; cpHeight = cpd.height; } if (root.getJMenuBar() != null) { mbd = root.getJMenuBar().getPreferredSize(); if (mbd != null) { mbWidth = mbd.width; mbHeight = mbd.height; } } if (root.getWindowDecorationStyle() != NONE && (root.getUI() instanceof BaseRootPaneUI)) { JComponent titlePane = ((BaseRootPaneUI) root.getUI()).internalGetTitlePane(); if (titlePane != null) { tpd = titlePane.getPreferredSize(); if (tpd != null) { tpWidth = tpd.width; } } } return new Dimension(Math.max(Math.max(cpWidth, mbWidth), tpWidth) + i.left + i.right, cpHeight + mbHeight + tpWidth + i.top + i.bottom); } /** * Returns the minimum amount of space the layout needs. * * @param the Container for which this layout manager is being used * @return a Dimension object containing the layout's minimum size */ @Override public Dimension minimumLayoutSize(Container parent) { return MINIMUM_SIZE; } /** * Returns the maximum amount of space the layout can use. * * @param the Container for which this layout manager is being used * @return a Dimension object containing the layout's maximum size */ @Override public Dimension maximumLayoutSize(Container target) { return MAXIMUM_SIZE; } /** * Instructs the layout manager to perform the layout for the specified container. * * @param the Container for which this layout manager is being used */ @Override public void layoutContainer(Container parent) { JRootPane root = (JRootPane) parent; Rectangle b = root.getBounds(); Insets i = root.getInsets(); int nextY = 0; int w = b.width - i.right - i.left; int h = b.height - i.top - i.bottom; if (root.getLayeredPane() != null) { root.getLayeredPane().setBounds(i.left, i.top, w, h); } if (root.getGlassPane() != null) { if (root.getWindowDecorationStyle() != NONE && (root.getUI() instanceof BaseRootPaneUI)) { JComponent titlePane = ((BaseRootPaneUI) root.getUI()).internalGetTitlePane(); int titleHeight = 0; if (titlePane != null) { titleHeight = titlePane.getSize().height; } root.getGlassPane().setBounds(i.left, i.top + titleHeight, w, h - titleHeight); } else { root.getGlassPane().setBounds(i.left, i.top, w, h); } } // Note: This is laying out the children in the layeredPane, // technically, these are not our children. if (root.getWindowDecorationStyle() != NONE && (root.getUI() instanceof BaseRootPaneUI)) { JComponent titlePane = ((BaseRootPaneUI) root.getUI()).internalGetTitlePane(); if (titlePane != null) { Dimension tpd = titlePane.getPreferredSize(); if (tpd != null) { int tpHeight = tpd.height; titlePane.setBounds(0, 0, w, tpHeight); nextY += tpHeight; } } } if (root.getJMenuBar() != null) { Dimension mbd = root.getJMenuBar().getPreferredSize(); root.getJMenuBar().setBounds(0, nextY, w, mbd.height); nextY += mbd.height; } if (root.getContentPane() != null) { root.getContentPane().setBounds(0, nextY, w, h < nextY ? 0 : h - nextY); } } @Override public void addLayoutComponent(String name, Component comp) { } @Override public void removeLayoutComponent(Component comp) { } @Override public void addLayoutComponent(Component comp, Object constraints) { } @Override public float getLayoutAlignmentX(Container target) { return 0.0f; } @Override public float getLayoutAlignmentY(Container target) { return 0.0f; } @Override public void invalidateLayout(Container target) { } } /** * Maps from positions to cursor type. Refer to calculateCorner and calculatePosition for details of this. */ private static final int[] cursorMapping = new int[]{ Cursor.NW_RESIZE_CURSOR, Cursor.NW_RESIZE_CURSOR, Cursor.N_RESIZE_CURSOR, Cursor.NE_RESIZE_CURSOR, Cursor.NE_RESIZE_CURSOR, Cursor.NW_RESIZE_CURSOR, 0, 0, 0, Cursor.NE_RESIZE_CURSOR, Cursor.W_RESIZE_CURSOR, 0, 0, 0, Cursor.E_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR, 0, 0, 0, Cursor.SE_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR, Cursor.S_RESIZE_CURSOR, Cursor.SE_RESIZE_CURSOR, Cursor.SE_RESIZE_CURSOR }; //------------------------------------------------------------------------------ /** * MouseInputHandler is responsible for handling resize/moving of the Window. It sets the cursor directly on the * Window when then mouse moves over a hot spot. */ private class MouseInputHandler implements MouseInputListener { /** * Set to true if the drag operation is moving the window. */ private boolean isMovingWindow; /** * Set to true if the drag operation is resizing the window. */ private boolean isResizingWindow; /** * Used to determine the corner the resize is occuring from. */ private int dragCursor; /** * X location the mouse went down on for a drag operation. */ private int dragOffsetX; /** * Y location the mouse went down on for a drag operation. */ private int dragOffsetY; /** * Width of the window when the drag started. */ private int dragWidth; /** * Height of the window when the drag started. */ private int dragHeight; private Container savedContentPane = null; private ResizingPanel resizingPanel = null; @Override public void mousePressed(MouseEvent ev) { Window w = (Window) ev.getSource(); if (w instanceof Window) { JRootPane root = getRootPane(); if (root.getWindowDecorationStyle() == NONE) { return; } w.toFront(); Point dragWindowOffset = ev.getPoint(); Point convertedDragWindowOffset = SwingUtilities.convertPoint(w, dragWindowOffset, internalGetTitlePane()); Frame f = null; Dialog d = null; if (w instanceof Frame) { f = (Frame) w; } else if (w instanceof Dialog) { d = (Dialog) w; } int frameState = (f != null) ? f.getExtendedState() : 0; if (internalGetTitlePane() != null && internalGetTitlePane().contains(convertedDragWindowOffset)) { if ((f != null && ((frameState & BaseRootPaneUI.MAXIMIZED_BOTH) == 0) || (d != null)) && dragWindowOffset.y >= BORDER_DRAG_THICKNESS && dragWindowOffset.x >= BORDER_DRAG_THICKNESS && dragWindowOffset.x < w.getWidth() - BORDER_DRAG_THICKNESS) { isMovingWindow = true; dragOffsetX = dragWindowOffset.x; dragOffsetY = dragWindowOffset.y; if (window instanceof JFrame) { JFrame frame = (JFrame) window; for (PropertyChangeListener pcl : frame.getPropertyChangeListeners()) { pcl.propertyChange(new PropertyChangeEvent(window, "windowMoving", Boolean.FALSE, Boolean.FALSE)); } } if (window instanceof JDialog) { JDialog dialog = (JDialog) window; for (PropertyChangeListener pcl : dialog.getPropertyChangeListeners()) { pcl.propertyChange(new PropertyChangeEvent(window, "windowMoving", Boolean.FALSE, Boolean.FALSE)); } } } } else if (f != null && f.isResizable() && ((frameState & BaseRootPaneUI.MAXIMIZED_BOTH) == 0) || (d != null && d.isResizable())) { isResizingWindow = true; if (!isDynamicLayout()) { savedContentPane = getRootPane().getContentPane(); GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); BufferedImage bi = gc.createCompatibleImage(savedContentPane.getWidth(), savedContentPane.getHeight()); savedContentPane.paint(bi.getGraphics()); resizingPanel = new ResizingPanel(bi); getRootPane().setContentPane(resizingPanel); } dragOffsetX = dragWindowOffset.x; dragOffsetY = dragWindowOffset.y; dragWidth = w.getWidth(); dragHeight = w.getHeight(); dragCursor = getCursor(calculateCorner(w, dragWindowOffset.x, dragWindowOffset.y)); if (window instanceof JFrame) { JFrame frame = (JFrame) window; for (PropertyChangeListener pcl : frame.getPropertyChangeListeners()) { pcl.propertyChange(new PropertyChangeEvent(window, "windowResizing", Boolean.FALSE, Boolean.FALSE)); } } if (window instanceof JDialog) { JDialog dialog = (JDialog) window; for (PropertyChangeListener pcl : dialog.getPropertyChangeListeners()) { pcl.propertyChange(new PropertyChangeEvent(window, "windowResizing", Boolean.FALSE, Boolean.FALSE)); } } } } } @Override public void mouseReleased(MouseEvent ev) { if (ev.getSource() instanceof Window) { Window w = (Window) ev.getSource(); if (w != null) { if (!isDynamicLayout() && isResizingWindow) { getRootPane().setContentPane(savedContentPane); getRootPane().updateUI(); resizingPanel = null; } else if (dragCursor != 0 && !window.isValid()) { // Some Window systems validate as you resize, others won't, // thus the check for validity before repainting. w.validate(); getRootPane().repaint(); } if (window instanceof JFrame) { JFrame frame = (JFrame) window; for (PropertyChangeListener pcl : frame.getPropertyChangeListeners()) { if (isMovingWindow) { pcl.propertyChange(new PropertyChangeEvent(window, "windowMoved", Boolean.FALSE, Boolean.FALSE)); } else { pcl.propertyChange(new PropertyChangeEvent(window, "windowResized", Boolean.FALSE, Boolean.FALSE)); } } } if (window instanceof JDialog) { JDialog dialog = (JDialog) window; for (PropertyChangeListener pcl : dialog.getPropertyChangeListeners()) { if (isMovingWindow) { pcl.propertyChange(new PropertyChangeEvent(window, "windowMoved", Boolean.FALSE, Boolean.FALSE)); } else { pcl.propertyChange(new PropertyChangeEvent(window, "windowResized", Boolean.FALSE, Boolean.FALSE)); } } } } isMovingWindow = false; isResizingWindow = false; dragCursor = 0; } } @Override public void mouseMoved(MouseEvent ev) { if (ev.getSource() instanceof Window) { JRootPane root = getRootPane(); if (root.getWindowDecorationStyle() == NONE) { return; } Window w = (Window) ev.getSource(); Frame f = null; Dialog d = null; if (w instanceof Frame) { f = (Frame) w; } else if (w instanceof Dialog) { d = (Dialog) w; } // Update the cursor int cursor = getCursor(calculateCorner(w, ev.getX(), ev.getY())); if (!isMovingWindow && cursor != 0 && ((f != null && (f.isResizable() && (f.getExtendedState() & BaseRootPaneUI.MAXIMIZED_BOTH) == 0)) || (d != null && d.isResizable()))) { if (savedCursor == null) { savedCursor = w.getCursor(); } w.setCursor(Cursor.getPredefinedCursor(cursor)); } else if (savedCursor != null) { w.setCursor(savedCursor); savedCursor = null; } } } private void adjust(Rectangle bounds, Dimension min, int deltaX, int deltaY, int deltaWidth, int deltaHeight) { bounds.x += deltaX; bounds.y += deltaY; bounds.width += deltaWidth; bounds.height += deltaHeight; if (min != null) { if (bounds.width < min.width) { int correction = min.width - bounds.width; if (deltaX != 0) { bounds.x -= correction; } bounds.width = min.width; } if (bounds.height < min.height) { int correction = min.height - bounds.height; if (deltaY != 0) { bounds.y -= correction; } bounds.height = min.height; } } } private int getMinScreenY() { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice devices[] = ge.getScreenDevices(); GraphicsDevice gd = devices[0]; GraphicsConfiguration gc = gd.getDefaultConfiguration(); int minScreenY = gc.getBounds().y + Toolkit.getDefaultToolkit().getScreenInsets(gc).top; if (devices.length > 1) { for (int i = 1; i < devices.length; i++) { gd = devices[i]; gc = gd.getDefaultConfiguration(); minScreenY = Math.min(minScreenY, gc.getBounds().y + Toolkit.getDefaultToolkit().getScreenInsets(gc).top); } } return minScreenY; } @Override public void mouseDragged(MouseEvent ev) { if (ev.getSource() instanceof Window) { Window w = (Window) ev.getSource(); if (!w.isShowing()) { return; } if (w instanceof Frame) { Frame frame = (Frame) w; int frameState = frame.getExtendedState(); if ((frameState & BaseRootPaneUI.MAXIMIZED_BOTH) != 0) { if (internalGetTitlePane() instanceof TitlePane) { Point pt = ev.getPoint(); Point dragWindowOffset = ev.getPoint(); Point convertedDragWindowOffset = SwingUtilities.convertPoint(w, dragWindowOffset, internalGetTitlePane()); if (internalGetTitlePane().contains(convertedDragWindowOffset)) { int ow = w.getWidth(); ((TitlePane)internalGetTitlePane()).restore(); int nw = w.getWidth(); int nx = pt.x * nw / ow; int ny = pt.y; w.setLocation(nx, ny); dragOffsetX = nx; dragOffsetY = ny; isMovingWindow = true; for (PropertyChangeListener pcl : frame.getPropertyChangeListeners()) { pcl.propertyChange(new PropertyChangeEvent(window, "windowMoving", Boolean.FALSE, Boolean.FALSE)); } } } } } int minScreenY = getMinScreenY(); if (isMovingWindow) { Point location = ev.getLocationOnScreen(); location.x -= dragOffsetX; location.y = Math.max(minScreenY, location.y - dragOffsetY); w.setLocation(location); } else if (dragCursor != 0) { Point pt = ev.getPoint(); Rectangle bounds = w.getBounds(); Rectangle startBounds = new Rectangle(bounds); Dimension min = MINIMUM_SIZE; switch (dragCursor) { case Cursor.E_RESIZE_CURSOR: adjust(bounds, min, 0, 0, pt.x + (dragWidth - dragOffsetX) - bounds.width, 0); break; case Cursor.S_RESIZE_CURSOR: adjust(bounds, min, 0, 0, 0, pt.y + (dragHeight - dragOffsetY) - bounds.height); break; case Cursor.N_RESIZE_CURSOR: adjust(bounds, min, 0, pt.y - dragOffsetY, 0, -(pt.y - dragOffsetY)); break; case Cursor.W_RESIZE_CURSOR: adjust(bounds, min, pt.x - dragOffsetX, 0, -(pt.x - dragOffsetX), 0); break; case Cursor.NE_RESIZE_CURSOR: adjust(bounds, min, 0, pt.y - dragOffsetY, pt.x + (dragWidth - dragOffsetX) - bounds.width, -(pt.y - dragOffsetY)); break; case Cursor.SE_RESIZE_CURSOR: adjust(bounds, min, 0, 0, pt.x + (dragWidth - dragOffsetX) - bounds.width, pt.y + (dragHeight - dragOffsetY) - bounds.height); break; case Cursor.NW_RESIZE_CURSOR: adjust(bounds, min, pt.x - dragOffsetX, pt.y - dragOffsetY, -(pt.x - dragOffsetX), -(pt.y - dragOffsetY)); break; case Cursor.SW_RESIZE_CURSOR: adjust(bounds, min, pt.x - dragOffsetX, 0, -(pt.x - dragOffsetX), pt.y + (dragHeight - dragOffsetY) - bounds.height); break; default: break; } if (!bounds.equals(startBounds)) { if (bounds.y < minScreenY) { int delta = minScreenY - bounds.y; bounds.y = minScreenY; bounds.height -= delta; } w.setBounds(bounds); w.validate(); } } } } @Override public void mouseEntered(MouseEvent ev) { mouseMoved(ev); } @Override public void mouseExited(MouseEvent ev) { if (ev.getSource() instanceof Window && savedCursor != null) { Window w = (Window) ev.getSource(); w.setCursor(savedCursor); savedCursor = null; } } @Override public void mouseClicked(MouseEvent ev) { if (ev.getSource() instanceof Window) { Window window = (Window) ev.getSource(); if (!(window instanceof Frame)) { return; } Frame frame = (Frame) window; Point convertedPoint = SwingUtilities.convertPoint(window, ev.getPoint(), internalGetTitlePane()); int state = frame.getExtendedState(); if (titlePane != null && titlePane instanceof TitlePane && titlePane.contains(convertedPoint) && frame.isResizable()) { if ((ev.getClickCount() % 2) == 0 && ((ev.getModifiers() & InputEvent.BUTTON1_MASK) != 0)) { if ((state & BaseRootPaneUI.MAXIMIZED_BOTH) != 0) { ((TitlePane) titlePane).restore(); } else { ((TitlePane) titlePane).maximize(); } } } } } /** * Returns the corner that contains the point x, y, or -1 if the position doesn't * match a corner. */ private int calculateCorner(Component c, int x, int y) { int xPosition = calculatePosition(x, c.getWidth()); int yPosition = calculatePosition(y, c.getHeight()); if (xPosition == -1 || yPosition == -1) { return -1; } return yPosition * 5 + xPosition; } /** * Returns the Cursor to render for the specified corner. This returns 0 if the corner doesn't map to a valid * Cursor */ private int getCursor(int corner) { if (corner == -1) { return 0; } return cursorMapping[corner]; } /** * Returns an integer indicating the position of spot in width. The return value will * be: 0 if < BORDER_DRAG_THICKNESS 1 if < CORNER_DRAG_WIDTH 2 if >= CORNER_DRAG_WIDTH && * < width - BORDER_DRAG_THICKNESS 3 if >= width - CORNER_DRAG_WIDTH 4 if >= width - BORDER_DRAG_THICKNESS 5 * otherwise */ private int calculatePosition(int spot, int width) { if (spot < BORDER_DRAG_THICKNESS) { return 0; } if (spot < CORNER_DRAG_WIDTH) { return 1; } if (spot >= (width - BORDER_DRAG_THICKNESS)) { return 4; } if (spot >= (width - CORNER_DRAG_WIDTH)) { return 3; } return 2; } } //------------------------------------------------------------------------------ private static class ResizingPanel extends JPanel { private BufferedImage bi = null; public ResizingPanel(BufferedImage bi) { super(); this.bi = bi; } @Override public void paint(Graphics g) { super.paint(g); g.drawImage(bi, 0, 0, null); } } // end of class ResizingPanel } // end of class BaseRootPaneUI





© 2015 - 2024 Weber Informatics LLC | Privacy Policy