+1 mKorbel 和 Denis Tulskiy 的回答。
我做了一种可能会有所帮助的抽象解决方案。JFrame
它支持从(NORTH,EAST,SOUTH 和 WEST)的所有四个侧面调整大小(增加和减少高度和宽度),JFrame
当鼠标移动到角落之一时,它也可以同时调整宽度和高度。
基本上我所做的是:
- 添加
MouseMotionListener
和MouseListener
到JFrame
- 覆盖
mouseDragged(..)
,和s 。mouseMoved(..)
_mousePressed(..)
mouseReleased(..)
Listener
- 设置
JFrame
为不可调整大小。
mouseMoved(..)
监听鼠标距离底部或右侧10px或更少的时间。,JFrame
然后设置适当的调整大小方向(高度或宽度),相应地更改鼠标Cursor
(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)
用于最右侧/宽度调整大小、Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)
底部/高度调整大小、Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)
框架顶部高度调整大小或Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)
左侧宽度调整大小)并调用canResize(true)
.
- 在
mouseDragged(..)
拖动方向时更新新尺寸的宽度或高度
- 在
mouseReleased(..)
设置JFrame
为新的大小。
- 在
mousePressed(..)
我们检查用户按下的坐标(这允许我们查看帧大小是否在减少/增加)。
看看我做的这个例子:
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JFrameSizeAfterDrag extends JFrame {
//direction holds the position of drag
private int w = 0, h = 0, direction, startX = 0, startY = 0;
public JFrameSizeAfterDrag() {
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
addMouseListener(new MouseAdapter() {
//so we can see if from where the user clikced is he increasing or decraesing size
@Override
public void mousePressed(MouseEvent me) {
super.mouseClicked(me);
startX = me.getX();
startY = me.getY();
System.out.println("Clicked: " + startX + "," + startY);
}
//when the mouse is relaeased set size
@Override
public void mouseReleased(MouseEvent me) {
super.mouseReleased(me);
System.out.println("Mouse released");
if (direction == 1 || direction == 2 || direction == 5 || direction == 6) {
setSize(w, h);
} else {//this should move x and y by as much as the mouse moved then use setBounds(x,y,w,h);
setBounds(getX() - (startX - me.getX()), getY() - (startY - me.getY()), w, h);
}
validate();
}
});
addMouseMotionListener(new MouseAdapter() {
private boolean canResize;
//while dragging check direction of drag
@Override
public void mouseDragged(MouseEvent me) {
super.mouseDragged(me);
System.out.println("Dragging:" + me.getX() + "," + me.getY());
if (canResize && direction == 1) {//frame height change
if (startY > me.getY()) {//decrease in height
h -= 4;
} else {//increase in height
h += 4;
}
} else if (canResize && direction == 2) {//frame width change
if (startX > me.getX()) {//decrease in width
w -= 4;
} else {//increase in width
w += 4;
}
} else if (canResize && direction == 3) {//frame height change
if (startX > me.getX()) {//decrease in width
w += 4;
} else {//increase in width
w -= 4;
}
} else if (canResize && direction == 4) {//frame width change
if (startY > me.getY()) {//decrease in height
h += 4;
} else {//increase in height
h -= 4;
}
} else if (canResize && direction == 5) {//frame width and height change bottom right
if (startY > me.getY() && startX > me.getX()) {//increase in height and width
h -= 4;
w -= 4;
} else {//decrease in height and with
h += 4;
w += 4;
}
} /* Windows dont usually support reszing from top but if you want :) uncomment code in mouseMoved(..) also
else if (canResize && direction == 6) {//frame width and height change top left
if (startY > me.getY() && startX > me.getX()) {//decrease in height and with
h += 4;
w += 4;
} else {//increase in height and width
h -= 4;
w -= 4;
}
} else if (canResize && direction == 8) {//frame width and height change top right
if (startY > me.getY() && startX > me.getX()) {//increase in height and width
h -= 4;
w -= 4;
} else {//decrease in height and with
h += 4;
w += 4;
}
}
*/ else if (canResize && direction == 7) {//frame width and height change bottom left
if (startY > me.getY() && startX > me.getX()) {//increase in height and width
h -= 4;
w -= 4;
} else {//decrease in height and with
h += 4;
w += 4;
}
}
}
@Override
public void mouseMoved(MouseEvent me) {
super.mouseMoved(me);
if (me.getY() >= getHeight() - 10 && me.getX() >= getWidth() - 10) {//close to bottom and right side of frame show south east cursor and allow height witdh simaltneous increase/decrease
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
direction = 5;
} /*Windows dont usually support reszing from top but if you want :) uncomment code in mouseDragged(..) too
else if (me.getY() <= 28 && me.getX() <= 28) {//close to top side and left side of frame show north west cursor and only allow increase/decrease in width and height simultaneosly
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
direction = 6;
} else if (me.getY() <= 28 && me.getX() >= getWidth() - 10) {//close to top and right side of frame show north east cursor and only allow increase/decrease in width and height simultaneosly
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
direction = 8;
}
*/ else if (me.getY() >= getHeight() - 10 && me.getX() <= 10) {//close to bottom side and left side of frame show north west cursor and only allow increase/decrease in width and height simultaneosly
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
direction = 7;
} else if (me.getY() >= getHeight() - 10) {//close to bottom of frame show south resize cursor and only allow increase height
//System.out.println("resize allowed");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
direction = 1;
} else if (me.getX() >= getWidth() - 10) {//close to right side of frame show east cursor and only allow increase width
//System.out.println("resize allowed");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
direction = 2;
} else if (me.getX() <= 10) {//close to left side of frame show east cursor and only allow increase width
//System.out.println("resize allowed");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
direction = 3;
} else if (me.getY() <= 28) {//close to top side of frame show east cursor and only allow increase height
// System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
direction = 4;
} else {
canResize = false;
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
// System.out.println("resize not allowed");
}
}
});
//just so GUI is visible and not small
add(new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
});
pack();
setVisible(true);
}
@Override
public void setVisible(boolean bln) {
super.setVisible(bln);
w = getWidth();
h = getHeight();
}
public static void main(String[] args) {
/**
* Create GUI and components on Event-Dispatch-Thread
*/
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JFrameSizeAfterDrag();
}
});
}
}
更新:
你做了很好的例子我通过添加MouseAdapter
哪些覆盖mouseReleased(..)
哪些调用resizePanel(...)
来修复代码mouseReleased(..)
请参阅此处以获取固定代码(还修复了一些小问题,例如添加ComponentAdapter
而不是ComponentListener
和AbstractAction
代替Action
):
import java.awt.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class JFrameSizeAfterDrag2 extends JFrame {
private Timer timer;
private JPanel panel2;
boolean canResize = true,firstTime = true;
public JFrameSizeAfterDrag2() {
super("GradientTranslucentWindow");
setBackground(new Color(0, 0, 0, 0));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(new JPanel(null) {//contentpane layout is null only
@Override
protected void paintComponent(Graphics g) {
Paint p = new GradientPaint(0.0f, 0.0f, new Color(0, 0, 0, 0), 0.0f, getHeight(), new Color(0, 0, 0, 0), true);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
});
panel2 = new JPanel();
panel2.setBackground(Color.black);
getContentPane().add(panel2);
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent me) {
super.mouseReleased(me);
if (canResize) {
resizePanel(getContentPane().getSize());
}
}
});
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
timer = new Timer(50, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (timer.isRunning()) {
canResize = false;
} else {
canResize = true;
if (firstTime == true) {
firstTime = false;
resizePanel(getContentPane().getSize());
}
}
}
});
timer.setRepeats(false);
timer.start();
}
});
pack();
}
public void resizePanel(Dimension dim) {
panel2.setBounds(0, 0, dim.width, dim.height);
revalidate();
}
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
boolean isPerPixelTranslucencySupported = gd.isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT);
if (!isPerPixelTranslucencySupported) {
System.out.println("Per-pixel translucency is not supported");
System.exit(0);
}
JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrameSizeAfterDrag2 gtw = new JFrameSizeAfterDrag2();
gtw.setVisible(true);
}
});
}
}