无法同时调整JFrame的大小和位置

问题描述 投票:0回答:2

我正在尝试做一些训练项目,在这个项目中,我添加了一个未修饰的 JFrame,因此我向其中添加了 MouseMotionListener 以更改鼠标光标,然后更改其大小和位置,使其看起来像任何可调整大小的修饰 JFrame

pblm:在北面和西面,框架没有调整大小,它保持改变位置而不改变它的大小,但是当我在调试模式下运行程序时它工作

我尝试使用线程和 setBounds 而不是 setSize,我也尝试添加 frame.revalidate() 和 frame.repaint(),但没有任何效果,任何建议

谢谢你的时间


package newpackage;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;



public class ResizeUndecoratedJFrame {

    private int oldCursPosX;
    private int oldCursPosY;
    private Dimension lastSize;
    private Dimension minFrameSize;
    private int tempX, tempY;

    public ResizeUndecoratedJFrame() {
        JFrame frame = new JFrame();
        frame.setUndecorated(true);
        JPanel p = new JPanel();
        p.setMinimumSize(new Dimension(400, 300));
        p.setPreferredSize(new Dimension(400, 300));
        p.setMaximumSize(new Dimension(400, 300));
        frame.add(p);
        frame.setSize(400, 300);
        minFrameSize = new Dimension(400, 300);
        frame.setLocationRelativeTo(null);
        

        frame.addMouseMotionListener(new MouseMotionAdapter() {
            // change Cursor
            @Override
            public void mouseMoved(MouseEvent e) {
                tempX = e.getX();
                tempY = e.getY();
                int w = frame.getWidth();
                int h = frame.getHeight();
                if ((tempX <= 3) || (tempY <= 3) || (w - tempX <= 3) || (h - tempY <= 3)) {
                    int type;
                    if (w - tempX <= 3) {
                        type = Cursor.E_RESIZE_CURSOR;
                    } else {
                        if (tempX <= 3) {
                            type = Cursor.W_RESIZE_CURSOR;
                        } else {
                            if (tempY <= 3) {
                                type = Cursor.N_RESIZE_CURSOR;
                            } else {
                                type = Cursor.S_RESIZE_CURSOR;
                            }
                        }
                    }

                    frame.setCursor(Cursor.getPredefinedCursor(type));
                    oldCursPosX = e.getX();
                    oldCursPosY = e.getY();
                    lastSize = frame.getSize();
                } else {
                    frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                }
            }


            @Override
            public void mouseDragged(MouseEvent e) {
                int type = frame.getCursor().getType();
                if (type != Cursor.DEFAULT_CURSOR) {
                    // calculate the distance between last cursor position when it's pressed and the current position
                    int distX = 0, distY = 0;
                    int currentX = e.getX();
                    int currentY = e.getY();
                    boolean isWestOrNorth = false;

                    if (type == Cursor.E_RESIZE_CURSOR) {
                        distX = currentX - oldCursPosX;
                    } else {
                        if (type == Cursor.W_RESIZE_CURSOR) {
                            isWestOrNorth = true;
                            distX = oldCursPosX - currentX;
                        } else {
                            if (type == Cursor.N_RESIZE_CURSOR) {
                                isWestOrNorth = true;
                                distY = oldCursPosY - currentY;
                            } else {
                                distY = currentY - oldCursPosY;
                            }
                        }
                    }

                    int tempW = (int) (lastSize.getWidth() + distX);
                    int tempH = (int) (lastSize.getHeight() + distY);
                    // make sure user can't resize JFrame less than this minimum size
                    if ((distX < 0 && tempW <= minFrameSize.getWidth()) || (distY < 0 && tempH <= minFrameSize.getHeight())) {
                        return;
                    }

                    if (isWestOrNorth) {
                        frame.setLocation(Math.round(frame.getLocationOnScreen().x + e.getX() - tempX),
                                Math.round(frame.getLocationOnScreen().y + e.getY() - tempY));
                    }
                    frame.setSize(new Dimension(tempW, tempH));
                }
            }
        });

        frame.setVisible(true);
    }


    public static void main(String[] args) {
        new ResizeUndecoratedJFrame();
    }
}

java swing jframe
2个回答
1
投票

我会在按下时使用

MouseListener
来保存鼠标位置,而不是在里面这样做
mouseMoved

frame.addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {
        oldCursPosX = e.getX();
        oldCursPosY = e.getY();
    }
});

mouseDragged
中,是这样的:

int x = frame.getX();
int y = frame.getY();
int width = frame.getWidth();
int height = frame.getHeight();
int dx = e.getX() - oldCursPosX;
int dy = e.getY() - oldCursPosY;
switch (type) {
    case Cursor.N_RESIZE_CURSOR:
        frame.setLocation(x, y+dy);
        if (height-dy >= minFrameSize.height) {
            frame.setSize(width, height-dy);
        }
        dy = 0; // frame has moved - it is the reference for coordinates
        break;
    case Cursor.S_RESIZE_CURSOR:
        if (height+dy >= minFrameSize.height) {
            frame.setSize(width, height+dy);
        }
        break;
    // ... similar for W and E
}
oldCursPosX += dx;
oldCursPosY += dy;

设置 Cursor 仍然会在

mouseMoved()
中完成,只需删除赋值语句即可。

这个答案中的代码是not旨在完成,优化,甚至无效 - 只是基本的想法


0
投票

在拖动过程中移动窗口时会发生一些奇怪的事情。尝试使用绝对坐标,并且正如有人所说,将位置保存在 mousePressed 事件上。

我经常使用以下接口的实现来处理鼠标拖动事件:

public interface MouseDragger {
    public void mouseDragged(int x, int y);
    public void mouseReleased(int x, int y);
}

在移动/调整大小的组件中,我将实现 MouseListener 和 MouseMotionListener,并实现以下方法:

...
MouseDragger mouseDragger;
...

@Override
public void mousePressed(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
        System.out.println(e);
        mouseDragger = ResizeMouseDragger.get(this, e.getX(), e.getY());
    }
}

@Override
public void mouseReleased(MouseEvent e) {
    if (mouseDragger != null && e.getButton() == MouseEvent.BUTTON1) {
        mouseDragger.mouseReleased(e.getX(), e.getY());
        mouseDragger = null;
    }
}

@Override
public void mouseDragged(MouseEvent e) {
    if (mouseDragger != null) {
        System.out.println(e);
        mouseDragger.mouseDragged(e.getX(), e.getY());
    }
}

@Override
public void mouseMoved(MouseEvent e) {
    Direction dir = Direction.hitTest(
            getSize(), e.getX(), e.getY());
    if (dir == null) {
        setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    } else {
        setCursor(dir.getCursor());
    }
}

上课

ResizeMouseDragger
看起来像这样:

类 ResizeMouseDragger 实现 MouseDragger { 私人最终组件补偿; 私人最终方向目录; 私有最终矩形边界; 私人最终诠释 x; 私人最终诠释 y;

public ResizeMouseDragger(Component comp, Direction dir, int x, int y) {
    this.comp = comp;
    this.bounds = comp.getBounds();
    this.dir = dir;
    Point pt = MouseInfo.getPointerInfo().getLocation();
    this.x = pt.x;
    this.y = pt.y;
}

public static MouseDragger get(Component comp, int x, int y) {
    Direction dir = Direction.hitTest(comp.getSize(), x, y);
    if (dir == null) {
        return null;
    } else {
        return new ResizeMouseDragger(comp, dir, x, y);
    }
}

@Override
public void mouseDragged(int x, int y) {
    Point pt = MouseInfo.getPointerInfo().getLocation();
    int dx = pt.x - this.x;
    int dy = pt.y - this.y;
    switch (dir) {
        case NORTH: {
            if (dy != 0) {
                comp.setBounds(bounds.x, bounds.y + dy,
                        bounds.width, bounds.height - dy);
            }
            break;
        }
        case SOUTH: {
            if (dy != 0) {
                comp.setBounds(bounds.x, bounds.y,
                        bounds.width, bounds.height + dy);
            }
            break;
        }
        case WEST: {
            if (dx != 0) {
                comp.setBounds(bounds.x + dx, bounds.y,
                        bounds.width - dx, bounds.height);
            }
            break;
        }
        case EAST: {
            if (dx != 0) {
                comp.setBounds(bounds.x, bounds.y,
                        bounds.width + dx, bounds.height);
            }
            break;
        }
    }
}

@Override
public void mouseReleased(int x, int y) {
}

}

我会有一个

Direction
类:

public enum Direction {
    NORTH(Cursor.N_RESIZE_CURSOR),
    SOUTH(Cursor.S_RESIZE_CURSOR),
    WEST(Cursor.W_RESIZE_CURSOR),
    EAST(Cursor.E_RESIZE_CURSOR),
    NORTH_WEST(Cursor.NW_RESIZE_CURSOR),
    NORTH_EAST(Cursor.NE_RESIZE_CURSOR),
    SOUTH_WEST(Cursor.SW_RESIZE_CURSOR),
    SOUTH_EAST(Cursor.SE_RESIZE_CURSOR);

    private static final int HANDLE_WIDTH = 4;

    private final int cursor;

    public static Direction hitTest(Dimension size, int x, int y) {
        if (x < 0 || y < 0 || x > size.width || y > size.height) {
            // outside of the frame
            return null;
        } else if (x <= HANDLE_WIDTH) {
            // west
            if (y <= HANDLE_WIDTH) {
                return NORTH_WEST;
            } else if (y >= size.height-HANDLE_WIDTH) {
                return SOUTH_WEST;
            } else {
                return WEST;
            }
        } else if (x >= size.width-HANDLE_WIDTH) {
            // east
            if (y <= HANDLE_WIDTH) {
                return NORTH_EAST;
            } else if (y >= size.height-HANDLE_WIDTH) {
                return SOUTH_EAST;
            } else {
                return EAST;
            }
        } else {
            if (y <= HANDLE_WIDTH) {
                return NORTH;
            } else if (y >= size.height-HANDLE_WIDTH) {
                return SOUTH;
            } else {
                // center
                return null;
            }
        }
    }

    private Direction(int cursor) {
        this.cursor = cursor;
    }

    public Cursor getCursor() {
        return Cursor.getPredefinedCursor(cursor);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.