1到mKorbel和Denis Tulskiy的答案.
我做了一些可能有帮助的抽象解决方案.它支持从JFrame(NORTH,EAST,SOUTH和WEST)的所有四个边调整JFrame的大小(增加和减少高度和宽度),当鼠标移动到其中一个时,它也可以同时按宽度和高度重新调整大小.角落.
基本上我做的是:
>将MouseMotionListener和MouseListener添加到JFrame
>覆盖监听器的mouseDragged(..),mouseMoved(..),mousePressed(..)和mouseReleased(..).
>将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(..),当mouseReleased(…)调用resizePanel(…)
看到这里的固定代码(还修复了一些小的东西,如添加了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);
}
});
}
}