如何在不产生混乱类的情况下处理java swing组件事件



我正在尝试开发一个带有swing的GUI界面,在该界面中,组件可以通过侦听器与其他组件进行通信。我面临的问题是:-

方法


  1. 实现侦听器
  2. 使用匿名方法添加具有侦听器方法的侦听器
  3. 从实现侦听器的类中添加侦听器

问题


  1. 在处理大量对象时,实现侦听器会造成在对象上操作的混乱
  2. 与1相同,只是构造函数需要匿名方法的韵母
  3. 不能在不使用静态引用的情况下对侦听类之外的对象进行操作

这真的很令人沮丧,因为我如何让MouseListenerClass在一个JPanel上绘制,这个JPanel是一个单独的JFrame类的一部分,而不将JPanel传递给mouseListenerCClass对其进行操作。

我似乎唯一能工作的方法是创建一个名为MouseState的Enum,当鼠标事件MousePress启动时,它将静态Enum mouseStatus设置为pressed,然后JPanel paintComponent方法检查Enum mouse Status,并在有press的情况下绘制。

这似乎是错误的方式。

还有别的办法吗?

更新以反映Cyrille的评论:-

谢谢@Cyrille,我不得不使用强制转换来修改你的代码,但前提仍然有效。"public void mousePressed(MouseEvent e){

    PaintPanel p=(PaintPanel) getTargetPanel();
    p.setMousePressed(true);
    p.setMouseCoords(e.getPoint());
}

public void mouseReleased(MouseEvent e) {
    PaintPanel p=(PaintPanel) getTargetPanel();
    p.setMousePressed(false);
}
public JPanel getTargetPanel() {
    return targetPanel;
}'

鼠标监听器不应该在JPanel上绘制。相反,您应该使用MVC(模型-视图-控制器)模式。

例如,您将设置3个类:面板、侦听器和用于保存数据的类(模型类)。当监听器被触发时,它应该编辑模型。然后,模型可以通知面板发生了变化,面板可以检查模型中的数据并绘制适当的像素。看见http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller了解更多信息。

BTW:这是大多数标准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)放在一起。对于这样一个简单的东西,把它们放在一起更简单,但随着事情变得越来越复杂,最好把它们分开,并把模型放在一个类中。

相关内容

最新更新