我正在尝试开发一个带有swing的GUI界面,在该界面中,组件可以通过侦听器与其他组件进行通信。我面临的问题是:-
方法
- 实现侦听器
- 使用匿名方法添加具有侦听器方法的侦听器
- 从实现侦听器的类中添加侦听器
问题
- 在处理大量对象时,实现侦听器会造成在对象上操作的混乱
- 与1相同,只是构造函数需要匿名方法的韵母
- 不能在不使用静态引用的情况下对侦听类之外的对象进行操作
这真的很令人沮丧,因为我如何让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)放在一起。对于这样一个简单的东西,把它们放在一起更简单,但随着事情变得越来越复杂,最好把它们分开,并把模型放在一个类中。