拖动和调整未修饰的JFrame

目前,我正在使用以下代码来拖动和移动未解决的JFrame。

private void initialiseGUI(Component component){ // component.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { posX = e.getX(); posY = e.getY(); } }); component.addMouseMotionListener(new MouseAdapter() { public void mouseDragged(MouseEvent evt) { //sets frame position when mouse dragged Rectangle rectangle = getBounds(); getGUI().setBounds(evt.getXOnScreen() - posX, evt.getYOnScreen() - posY, rectangle.width, rectangle.height); } }); // } 

我必须写什么,以便用户可以通过拖动侧面来像装饰窗口一样resize?

您可以查看Rob Camick先生的ComponentResizer类。 非常简单直接使用。

只需实例化ComponentResizer并使用以下内容注册框架:

 JFrame frame = new JFrame(); ComponentResizer cr = new ComponentResizer(); cr.registerComponent(frame); cr.setSnapSize(new Dimension(10, 10)); cr.setMaximumSize(new Dimension(...)); cr.setMinimumSize(new Dimension(...)); 

这是使用该类的完整示例

在此处输入图像描述

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.LineBorder; public class UndecoratedExample { private JFrame frame = new JFrame(); class MainPanel extends JPanel { public MainPanel() { setBackground(Color.gray); } @Override public Dimension getPreferredSize() { return new Dimension(400, 400); } } class BorderPanel extends JPanel { private JLabel label; int pX, pY; public BorderPanel() { label = new JLabel(" X "); label.setOpaque(true); label.setBackground(Color.RED); label.setForeground(Color.WHITE); setBackground(Color.black); setLayout(new FlowLayout(FlowLayout.RIGHT)); add(label); label.addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent e) { System.exit(0); } }); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent me) { // Get x,y and store them pX = me.getX(); pY = me.getY(); } public void mouseDragged(MouseEvent me) { frame.setLocation(frame.getLocation().x + me.getX() - pX, frame.getLocation().y + me.getY() - pY); } }); addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent me) { frame.setLocation(frame.getLocation().x + me.getX() - pX, frame.getLocation().y + me.getY() - pY); } }); } } class OutsidePanel extends JPanel { public OutsidePanel() { setLayout(new BorderLayout()); add(new MainPanel(), BorderLayout.CENTER); add(new BorderPanel(), BorderLayout.PAGE_START); setBorder(new LineBorder(Color.BLACK, 5)); } } private void createAnsShowGui() { ComponentResizer cr = new ComponentResizer(); cr.setMinimumSize(new Dimension(300, 300)); cr.setMaximumSize(new Dimension(800, 600)); cr.registerComponent(frame); cr.setSnapSize(new Dimension(10, 10)); frame.setUndecorated(true); frame.add(new OutsidePanel()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new UndecoratedExample().createAnsShowGui(); } }); } } 

我最近为此建立了自己的原型。 也许你会觉得这很有用。

它使用两个不同的组件,一个在另一个之上。 与Rob Camick的ComponentResizer不同,启发了它,设置为JFrame中的组件的鼠标侦听器将起作用。 您不会让JFrame捕获所有鼠标事件,因此无法将侦听器附加到JFrame中的组件。 它仅在必须显示双头箭头的时间和地点捕获鼠标事件。

关键是顶层组件中的这个方法:

 @Override public boolean contains(int x, int y) { return x < insets.left || y < insets.top || getHeight() - y < insets.bottom || getWidth() - x < insets.right; } 

这是代码:

 import java.awt.Component; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; public class BackgroundComponentDragger implements MouseMotionListener { private Component controlledComponent; /* * Point where cursor was last clicked. */ private Point originPoint; public BackgroundComponentDragger(Component component) { this.controlledComponent = component; } @Override public void mouseDragged(MouseEvent e) { Point currentFramePosition = controlledComponent.getLocation(); Point newFramePosition = new Point(currentFramePosition.x + e.getX() - originPoint.x, currentFramePosition.y + e.getY() - originPoint.y); controlledComponent.setLocation(newFramePosition); } @Override public void mouseMoved(MouseEvent e) { originPoint = e.getPoint(); } } import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Insets; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.util.HashMap; import java.util.Map; public class ComponentBorderDragger implements MouseMotionListener { private Component controlledComponent; private byte direction; protected static final byte NORTH = 1; protected static final byte WEST = 2; protected static final byte SOUTH = 4; protected static final byte EAST = 8; private Cursor sourceCursor; private static Map cursors = new HashMap(); { cursors.put((byte) 1, Cursor.N_RESIZE_CURSOR); cursors.put((byte) 2, Cursor.W_RESIZE_CURSOR); cursors.put((byte) 4, Cursor.S_RESIZE_CURSOR); cursors.put((byte) 8, Cursor.E_RESIZE_CURSOR); cursors.put((byte) 3, Cursor.NW_RESIZE_CURSOR); cursors.put((byte) 9, Cursor.NE_RESIZE_CURSOR); cursors.put((byte) 6, Cursor.SW_RESIZE_CURSOR); cursors.put((byte) 12, Cursor.SE_RESIZE_CURSOR); } private Insets dragInsets; private Dimension minSize; private Point basePoint; public ComponentBorderDragger(Component controlledComponent, Insets dragInsets, Dimension minSize) { super(); this.controlledComponent = controlledComponent; this.dragInsets = dragInsets; this.minSize = minSize; } @Override public void mouseDragged(MouseEvent e) { if (direction == 0) { return; } Point newPoint = e.getPoint(); int x, y, width, height, newBasePointX, newBasePointY; x = controlledComponent.getX(); y = controlledComponent.getY(); width = controlledComponent.getWidth(); height = controlledComponent.getHeight(); newBasePointX = newPoint.x; newBasePointY = newPoint.y; if ((direction & EAST) == EAST) { int newWidth; newWidth = Math.max(minSize.width, width + newPoint.x - basePoint.x); width = newWidth; } if ((direction & SOUTH) == SOUTH) { int novoAlto; novoAlto = Math.max(minSize.height, height + newPoint.y - basePoint.y); height = novoAlto; } if ((direction & WEST) == WEST) { int newWidth, newX; newWidth = Math.max(minSize.width, width - newPoint.x + basePoint.x); newX = Math.min(x + width - minSize.width, x + newPoint.x - basePoint.x); // Changing coordenates of new base point to refer to the new component position newBasePointX -= newX - x; x = newX; width = newWidth; } if ((direction & NORTH) == NORTH) { int newHeigth, newY; newHeigth = Math.max(minSize.height, height - newPoint.y + basePoint.y); newY = Math.min(y + height - minSize.height, y + newPoint.y - basePoint.y); // Changing coordenates of new base point to refer to the new component position newBasePointY -= newY - y; y = newY; height = newHeigth; } controlledComponent.setBounds(x, y, width, height); basePoint = new Point(newBasePointX, newBasePointY); } @Override public void mouseMoved(MouseEvent e) { Component originator = e.getComponent(); if (direction == 0) { sourceCursor = originator.getCursor(); } calculateDirection(e.getPoint(), e.getComponent().getSize()); setCursor(e.getComponent()); basePoint = e.getPoint(); } private void setCursor(Component component) { if (direction == 0) { component.setCursor(sourceCursor); } else { int cursorType = cursors.get(direction); Cursor cursor = Cursor.getPredefinedCursor(cursorType); component.setCursor(cursor); } } private void calculateDirection(Point point, Dimension componentSize) { direction = 0; if (point.x < dragInsets.left) { direction |= WEST; } if (point.y < dragInsets.top) { direction |= NORTH; } if (point.x > componentSize.width - dragInsets.right) { direction |= EAST; } if (point.y > componentSize.height - dragInsets.bottom) { direction |= SOUTH; } } } import java.awt.Insets; import javax.swing.JComponent; public class FrameComponent extends JComponent { private static final long serialVersionUID = 3383070502274306213L; private Insets insets; @Override public boolean contains(int x, int y) { return x < insets.left || y < insets.top || getHeight() - y < insets.bottom || getWidth() - x < insets.right; } public FrameComponent(Insets insets) { this.insets = insets; } } import java.awt.Dimension; import java.awt.Insets; import java.awt.Toolkit; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import javax.swing.JFrame; import javax.swing.JPanel; public class GUI { private JFrame compoundFrame; private JPanel backgroundPanel; Dimension gUISize = new Dimension(400, 400); public GUI() { buildResizeableFrame(); } public void activate() { compoundFrame.setVisible(true); } private void buildResizeableFrame() { compoundFrame = new JFrame(); FrameComponent frame = new FrameComponent(new Insets(5, 5, 5, 5)); backgroundPanel = new JPanel(); compoundFrame.setLayout(null); compoundFrame.add(frame); compoundFrame.add(backgroundPanel); setFrameSizeController(frame, backgroundPanel); setFrameController(frame); setBackgroundPanelController(backgroundPanel); Dimension dimPant = Toolkit.getDefaultToolkit().getScreenSize(); compoundFrame.setBounds(dimPant.width / 4, dimPant.height / 4, dimPant.width / 2, dimPant.height / 2); compoundFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); compoundFrame.setUndecorated(true); } private void setFrameSizeController(FrameComponent frame, JPanel panel) { compoundFrame.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { Dimension sizeIn = ((JFrame) e.getComponent()).getContentPane().getSize(); frame.setSize(sizeIn); panel.setSize(sizeIn); } }); } private void setFrameController(FrameComponent frame) { ComponentBorderDragger controller = new ComponentBorderDragger(compoundFrame, new Insets(5, 5, 5, 5), new Dimension(10, 10)); frame.addMouseMotionListener(controller); } private void setBackgroundPanelController(JPanel panel) { panel.addMouseMotionListener(new BackgroundComponentDragger(compoundFrame)); } public static void main(String[] args) { new GUI().activate(); } } 

注意:此代码设置null LayoutManager和容器的侦听器,以在需要时调整内部组件的大小。 不鼓励这种做法。 应将此逻辑移动到自定义布局管理器。