拖动和调整未修饰的JFrame
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拖动和调整未修饰的JFrame相关的知识,希望对你有一定的参考价值。
目前,我使用以下代码来拖动和移动未解决的JFrame。
private void initialiseGUI(Component component){
//<editor-fold defaultstate="collapsed" desc="code">
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);
}
});
//</editor-fold>
}
我必须写什么,以便用户可以通过拖动侧面来像装饰窗口一样调整大小?
答案
你可以看看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's 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<Byte, Integer> cursors = new HashMap<Byte, Integer>();
{
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;
以上是关于拖动和调整未修饰的JFrame的主要内容,如果未能解决你的问题,请参考以下文章
在未修饰的 JFrame 中支持 Windows-Left 和 Windows-Right