当我释放鼠标按钮时,MouseEvent未注册发布 [英] MouseEvent is not registering a release when I release the mouse button

查看:39
本文介绍了当我释放鼠标按钮时,MouseEvent未注册发布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public void mousePressed(MouseEvent e){//在组件上按下鼠标按钮时调用.如果(e.getButton()== MouseEvent.BUTTON1){isDown = true;System.out.println("isDown现在为true");}如果(e.getButton()== MouseEvent.BUTTON3){isDown2 = true;System.out.println("isDown2现在为真");}做 {点位置= MouseInfo.getPointerInfo().getLocation();int x = location.x-(drawingPanel.getLocationOnScreen()).x;int y = location.y-(drawingPanel.getLocationOnScreen()).y;drawingPanel.paint(drawingPanel.getGraphics(),(x-(x%20)-1),(y-(y%20)-1),19,19);} while(isDown);System.out.println(鼠标已被按下.");}public void mouseReleased(MouseEvent e){//在组件上释放鼠标按钮时调用.如果(e.getButton()== MouseEvent.BUTTON1){isDown = false;System.out.println("isDown现在为false");}如果(e.getButton()== MouseEvent.BUTTON3){isDown2 = false;System.out.println("isDown2现在为false");}System.out.println(鼠标已被释放.");} 

这是我到目前为止所拥有的.我的初衷是设计代码,以便在按下鼠标时将布尔值 isDown 设置为true,然后在时运行 while 循环> isDown 为true.如果释放鼠标按钮,我将 isDown 设置为false,以终止 while 循环.

我在这里弄乱了什么?两个MouseEvent方法不能同时运行吗? isDown 布尔变量中的更改未注册,并且我的手上有一个无限的while循环.

解决方案

这是对事件调度线程的经典违反.

所有UI代码都在单个线程中运行.所有事件都是从同一线程分派UI的,这意味着如果您阻塞此线程(使用循环或其他阻塞操作),则不会分派任何事件.这将使您的程序看起来像已被挂起.

有关更多信息,请参见 Swing并发详细信息.

您真正应该做的是使用如何使用鼠标侦听器./p>

drawingPanel.paint(drawingPanel.getGraphics(),(x-(x%20)-1),(y-(y%20)-1),19,19); 也让我无休止.

您永远不应使用 getGraphics 进行自定义绘制. getGraphics 可以返回null,并且仅是上一次绘制周期的快照.使用此方法完成的任何绘画都将在发生另一次重新绘画时被删除/清除.

您应该创建一个自定义组件(例如 JPanel )并覆盖它的 paintComponent 方法,并在其中执行所需的绘画.有关详细信息,请查看执行自定义绘画

示例

 公共类MouseDraggedTest {公共静态void main(String [] args){新的MouseDraggedTest();}公共MouseDraggedTest(){EventQueue.invokeLater(new Runnable(){@Override公共无效run(){尝试 {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} catch(ex Exception){}JFrame frame = new JFrame("Test");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.add(new TestPane());frame.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);}});}公共类TestPane扩展了JPanel {私有Map< Point,List< Point>>mapPoints;私有Point currentPoint;公共TestPane(){mapPoints = new HashMap<>(25);MouseAdapter mouseListener = new MouseAdapter(){@Overridepublic void mousePressed(MouseEvent e){currentPoint = e.getPoint();mapPoints.put(currentPoint,new ArrayList< Point>(25));}@Overridepublic void mouseReleased(MouseEvent e){List< Point>points = mapPoints.get(currentPoint);如果(points.isEmpty()){mapPoints.remove(currentPoint);}currentPoint = null;}@Override公共无效mouseDragged(MouseEvent me){List< Point>points = mapPoints.get(currentPoint);points.add(me.getPoint());repaint();}};addMouseListener(mouseListener);addMouseMotionListener(mouseListener);}@Override公共维度getPreferredSize(){返回新的Dimension(200,200);}@Override受保护的void paintComponent(Graphics g){super.paintComponent(g);对于(Point startPoint:mapPoints.keySet()){List< Point>points = mapPoints.get(startPoint);对于(点p:点){如果(startPoint!= null){g.drawLine(startPoint.x,startPoint.y,p.x,p.y);}startPoint = p;}}}}} 

public void mousePressed(MouseEvent e) {
    //Invoked when a mouse button has been pressed on a component.
    if (e.getButton() == MouseEvent.BUTTON1) {
        isDown = true;
        System.out.println("isDown is now true");
    }
    if (e.getButton() == MouseEvent.BUTTON3) {
        isDown2 = true;
        System.out.println("isDown2 is now true");
    }
    do {
        Point location = MouseInfo.getPointerInfo().getLocation(); 
        int x = location.x - (drawingPanel.getLocationOnScreen()).x;
        int y = location.y - (drawingPanel.getLocationOnScreen()).y;
        drawingPanel.paint(drawingPanel.getGraphics(), (x - (x % 20) - 1), (y - (y % 20) - 1), 19, 19);
    } while (isDown);
    System.out.println("Mouse has been pressed down.");
}

public void mouseReleased(MouseEvent e) {
    //Invoked when a mouse button has been released on a component.
    if (e.getButton() == MouseEvent.BUTTON1) {
        isDown = false;
        System.out.println("isDown is now false");
    }
    if (e.getButton() == MouseEvent.BUTTON3) {
        isDown2 = false;
        System.out.println("isDown2 is now false");
    }
    System.out.println("Mouse has been released.");
}

This is what I have so far. My original intentions were to design the code so that the boolean isDown would be set to true when the mouse was pressed down and then I would have the while loop run while isDown is true. If the mouse button is released, I would set isDown to false in order to terminate the while loop.

What I am messing up here? Is it not possible for two MouseEvent methods to be running at the same time? The change in the isDown boolean variable is not being registered and I have an infinite while loop on my hands.

解决方案

This is a classic violation of the Event Dispatching Thread.

All UI code is run from within a single thread. All events are dispatched the UI from this same thread, meaning that should you block this thread (using a loop or other blocking operation), no events will be dispatched. This will make your program look like it's hung.

Take a look at Concurrency in Swing for more details.

What you really should be doing is using a MouseMoitionListener to track drag events instead. Check out How to use Mouse Listeners for more details.

This drawingPanel.paint(drawingPanel.getGraphics(), (x - (x % 20) - 1), (y - (y % 20) - 1), 19, 19); also worries me to no end.

You should never be using getGraphics to perform custom painting. getGraphics can return null and is only a snap shot of the last paint cycle. Any painting done using this method will be removed/cleaned when another repaint occurs.

You should be creating a custom component (such as a JPanel) and overriding it's paintComponent method and performing any painting you need in it. Check out Performing Custom Painting for more details

Example

public class MouseDraggedTest {

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

    public MouseDraggedTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

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

    public class TestPane extends JPanel {

        private Map<Point, List<Point>> mapPoints;
        private Point currentPoint;

        public TestPane() {
            mapPoints = new HashMap<>(25);
            MouseAdapter mouseListener = new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    currentPoint = e.getPoint();
                    mapPoints.put(currentPoint, new ArrayList<Point>(25));
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    List<Point> points = mapPoints.get(currentPoint);
                    if (points.isEmpty()) {
                        mapPoints.remove(currentPoint);
                    }
                    currentPoint = null;
                }

                @Override
                public void mouseDragged(MouseEvent me) {
                    List<Point> points = mapPoints.get(currentPoint);
                    points.add(me.getPoint());
                    repaint();
                }
            };
            addMouseListener(mouseListener);
            addMouseMotionListener(mouseListener);
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            for (Point startPoint : mapPoints.keySet()) {
                List<Point> points = mapPoints.get(startPoint);
                for (Point p : points) {
                    if (startPoint != null) {
                        g.drawLine(startPoint.x, startPoint.y, p.x, p.y);
                    }
                    startPoint = p;
                }
            }
        }
    }
}

这篇关于当我释放鼠标按钮时,MouseEvent未注册发布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆