如何避免同时使用两个 JButton

How to avoid to work two JButton at the same time

我正在用 Java 编写一个简单的绘图程序。由于所有绘画应用程序都有用于 brushTool、sprayTool、sprayTool 的按钮...这些工具有自己的 class,可扩展到 MouseAdapter。他们正在按应有的方式工作。但是,当我在选择另一个工具后选择一个工具时,问题就开始了,按钮和它们的 ActionListeners 都在继续执行,并且它们同时执行它们编写的内容。我的意思是,如果我选择 lineTool(绘制直线)和 rectangleTool,我也会有一条对角线。这是我的两个按钮的示例。我要做的是在单击另一个按钮时停止当前操作。你们能帮帮我吗

brushBotton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            pen = new PenTool(mainDrawArea);
            mainDrawArea.addMouseListener(pen);
            mainDrawArea.addMouseMotionListener(pen);
            }
    });

rectangleButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
                shapeToolbar.setVisible(false);
                rect = new RectangleTool(mainDrawArea);
                rect.setStrokeSize(strokeInt);
                mainDrawArea.addMouseListener(rect);
                mainDrawArea.addMouseMotionListener(rect);
            }
        });

您不能在每次单击按钮时都向绘图区域添加 MouseListener。

相反,您需要跟踪当前的 MouseListener。然后,当您单击一个按钮时,您需要:

  1. 移除当前的 MouseListener
  2. 添加新的 MouseListener

我会为一组切换按钮替换按钮动作侦听器

https://docs.oracle.com/javase/tutorial/uiswing/components/buttongroup.html

然后您在单个鼠标侦听器中移动所有内容。

public void mousePressed(MouseEvent e) {
   this.drawingState = !this.drawingState
   if ( isRightCLick(e) ) resetAllPendingOperation();
   if (drawingState) {
      this.startPoint = getPointFromEvent(e);
      switch(toolbarGetCurrentTool()) {
          case "line":
            registerMouseLineListener(startPoint);//here you draw live preview
          break
          case "rectangle":
            registerMouseRectangleListener(startPoint); //here you draw live preview
          break;
      }
   } else {
     //user clicked the second time, commit changes
     //same switch as above
      this.endPoint = getPointFromEvent(e);
                switch(toolbarGetCurrentTool()) {
          case "line":
            commitLine(startPoint, endpoint);//here you draw live preview
          break
          case "rectangle":
            commitRectangle(startPoint, endpoint); //here you draw live preview
          break;
      }
   }
}

您目前正在将侦听器绑定到 mainDrawArea,而不是为每个单独的按钮设置一个动作。

请注意,您在 actionPerformed() 中为每个按钮的 actionListener 编写的代码是您希望在每次单击该按钮时触发的操作。您不想在我们每次单击按钮时都向 mainDrawArea 添加新的侦听器。

您可以为当前操作创建一个状态,例如:

brushBotton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            state = BRUSH;
        }
    });

lineBotton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            state = LINE;
        }
    });

state 可以是整数,BRUSHLINE 是常量,例如 0 和 1。

然后在监听器中(对于mainDrawArea),检查当前状态

switch (state){
    case BRUSH: //trigger action needed for brushing;
               break;
    case LINE: //trigger action needed for drawing line;
               break;
}