0

所以我想要完成的是创建两个 JFrame。一个将覆盖整个屏幕,当用户单击该屏幕时,当用户单击并拖动鼠标时会显示一个新的 JFrame。用户第一次点击的地方是新 JFrame 的左上角,而用户释放鼠标的地方是 JFrame 的右下角。单击并释放鼠标时,制作两个 JFrame 并显示第二个 JFrame 没有问题。问题是我希望新的 JFrame 在用户移动鼠标时实时显示,以便在释放鼠标之前。我试过了

public void mouseDragged(MouseEvent e) {

            FrontWindow f = new FrontWindow();

            while (true) {          
                f.setBounds(Shared.xPressed, Shared.yPressed, (Utils.getXPosition() - Shared.xPressed) , (Utils.getYPosition() - Shared.yPressed));
                f.setVisible(true);
            }

        }

但这没有用。

4

4 回答 4

4

不需要while循环。将生成多个 mouseDragged() 事件。

您应该在 mousePressed() 事件上创建新框架。然后,当每个 mouseDragged() 事件生成时,您更改框架的大小。

当然,这看起来不太好,因为拖动不会与框架的大小同步。更好的方法是在移动鼠标时只绘制一个矩形。然后在 mouseReleased 上创建并以绘制矩形的大小显示框架。

有关使用鼠标绘制矩形的基础知识,请参阅自定义绘制方法。在您的情况下,您可能希望使用 Glass Pane 来处理鼠标事件和矩形的绘制。

于 2013-06-25T01:26:22.197 回答
2

while (true)在您的mouseDragged()事件处理程序中阻止 Swing 的事件调度程序线程 (EDT)。这意味着您的程序不会收到任何额外的事件。所以当用户第一次开始拖动鼠标时,你就开始了这个无限循环。但是操作系统无法通知您鼠标在用户拖动时继续移动,因为您阻止了它这样做的能力。

于 2013-06-25T01:29:22.100 回答
0

尝试MouseInfo.getPointerInfo().getLocation()在单独的线程中运行,使用SwingUtilities.invokeLater()

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        Point mp = MouseInfo.getPointerInfo().getLocation();
        f.setBounds(Shared.xPress, Shared.yPress, mp.x - Shared.xPress, mp.y - Shared.yPressed);
    }
}

NBinvokeLater()不会启动单独的线程。您应该创建一个新线程并调用invokeLater()它的run()方法。

于 2013-06-25T01:31:29.210 回答
0

Swing 是一个单线程框架。也就是说,它使用单个线程将它的所有事件分派给它的所有相关方。

如果有任何东西阻塞了这个线程(例如 infinate while-loop),那么线程就无法处理任何进入应用程序的新事件,包括重绘请求。这将使您的应用程序看起来像挂起(在您的情况下,它实际上已经挂起)。

查看Swing 中的并发以获取更多详细信息。

以下示例允许用户在窗口表面单击/拖动,它将呈现一个表示拖动过程的矩形。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DrawRectangle {

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

    public DrawRectangle() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Rectangle dragRect;

        public TestPane() {

            MouseHandler handler = new MouseHandler();
            addMouseListener(handler);
            addMouseMotionListener(handler);

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (dragRect != null) {
                g2d.setColor(Color.DARK_GRAY);
                g2d.draw(dragRect);
            }
            g2d.dispose();
        }

        public class MouseHandler extends MouseAdapter {

            private Point clicked;

            @Override
            public void mousePressed(MouseEvent e) {
                clicked = e.getPoint();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseDragged(MouseEvent e) {

                Point p = e.getPoint();

                int x = Math.min(p.x, clicked.x);
                int y = Math.min(p.y, clicked.y);

                int width = Math.max(p.x, clicked.x) - x;
                int height = Math.max(p.y, clicked.y) - y;

                dragRect = new Rectangle(x, y, width, height);
                repaint();

            }

        }

    }
}
于 2013-06-25T01:34:45.997 回答