Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何处理java swing组件事件而不创建混乱的类?_Java_Swing_Events_Methods_Listener - Fatal编程技术网

如何处理java swing组件事件而不创建混乱的类?

如何处理java swing组件事件而不创建混乱的类?,java,swing,events,methods,listener,Java,Swing,Events,Methods,Listener,我试图用swing开发一个GUI界面,组件可以通过监听器与其他组件通信。我面临的问题是:- 方法 实现侦听器 使用使用匿名方法的侦听器方法添加侦听器 从实现侦听器的类中添加侦听器 问题 在处理大量对象时,实现侦听器会在尝试操作对象时造成混乱 与1相同,只是构造函数要求匿名方法使用final 如果不诉诸静态引用,则无法对侦听类之外的对象进行操作 这真的令人沮丧,因为我如何让MouseListenerClass在作为单独JFrame类一部分的JPanel上绘制,而不将JPanel传递给Mouse

我试图用swing开发一个GUI界面,组件可以通过监听器与其他组件通信。我面临的问题是:-

方法


  • 实现侦听器
  • 使用使用匿名方法的侦听器方法添加侦听器
  • 从实现侦听器的类中添加侦听器
  • 问题


  • 在处理大量对象时,实现侦听器会在尝试操作对象时造成混乱
  • 与1相同,只是构造函数要求匿名方法使用final
  • 如果不诉诸静态引用,则无法对侦听类之外的对象进行操作
  • 这真的令人沮丧,因为我如何让MouseListenerClass在作为单独JFrame类一部分的JPanel上绘制,而不将JPanel传递给MouseListenerClass对其进行操作

    我似乎唯一能工作的方法是创建一个名为MouseState的枚举,当mouse事件MousePressed被激发时,它会将静态枚举mouseStatus设置为pressed,然后JPanel paintComponent方法检查枚举mouseStatus并在有按下时进行绘制

    这似乎是错误的方式

    还有别的办法吗

    更新以反映Cyrille的评论:-


    谢谢@Cyrille,我不得不用铸造法修改你的代码,但前提仍然有效 公共无效鼠标按下(MouseEvent e){


    鼠标侦听器不应该在JPanel上绘制,而应该使用MVC(模型-视图-控件)模式

    例如,您将设置3个类:panel、listener和一个用于保存数据的类(模型类)。当启动listener时,它应该编辑模型。然后模型可以通知panel某些内容已更改,panel可以检查模型中的数据并绘制适当的像素。有关更多信息,请参阅


    顺便说一句:这是大多数标准Swing组件的工作方式。只有非常简单的组件(JPanel、JTextField等)允许不使用,并基于这些创建复杂组件您应该使用MVC,您不必使用任何类型的静态变量。您应该创建JPanel的子类来处理绘制,并在此类中提供一个方法供侦听器与其通信:

    public class MyPanel extends JPanel {
    
        // status used for drawing, can be anything you want, but let's say you need to know if the mouse is pressed.
        private boolean isMousePressed;
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // do your stuff here, using isMousePressed
        }
    
        public void setMousePressed(boolean pressed) {
            isMousePressed= pressed;
        }
    }
    
    然后,您的鼠标侦听器必须具有对MyPanel实例的引用,并使用正确的方法与之通信

    public class PaintingMouseListener implements MouseListener {
    
        private final JPanel targetPanel;
    
    
        public PaintingMouseListener(JPanel targetPanel) {
            this.targetPanel = targetPanel;
        }
    
    
        @Override
        public void mousePressed(MouseEvent e) {
            targetPanel.setMousePressed(true);
    
        }
    
        @Override
        public void mouseReleased(MouseEvent e) {
            targetPanel.setMousePressed(false);
        }
    
        // other methods of the listener
    }
    
    然后,使用对面板的引用创建鼠标侦听器

        MyPanel targetPanel = new MyPanel();
        // assign the mouse listener to whatever component needs it.
        component.addMouseListener(new PaintingMouseListener(targetPanel));
    

    这与MVC解决方案类似,只是它将模型(变量
    isMousePressed
    )和视图(MyPanel)放在一起一起。对于这样一个简单的东西,把它们放在一起比较简单,但随着事情变得越来越复杂,最好将它们分开,并将模型单独放在一个类中。

    JPanel
    没有内在的模型,但是
    JTextField
    有一个
    文档,如前所述。另请参阅这篇相关文章。谢谢@cyrle使用强制转换修改代码,但前提仍然有效。
    code
    public void mouseepressed(MouseEvent e){PaintPanel p=(PaintPanel)getTargetPanel();p.setmouseepressed(true);p.setMouseCoords(e.getPoint();}public void mouseereleased(MouseEvent e){PaintPanel p=(PaintPanel)getTargetPanel();p.setMousePressed(false);}public JPanel getTargetPanel(){return targetPanel;}`
        MyPanel targetPanel = new MyPanel();
        // assign the mouse listener to whatever component needs it.
        component.addMouseListener(new PaintingMouseListener(targetPanel));