如果未选中CheckBoxMenuItem,则Java退出鼠标侦听器

如果未选中CheckBoxMenuItem,则Java退出鼠标侦听器,java,swing,actionlistener,mouselistener,jmenubar,Java,Swing,Actionlistener,Mouselistener,Jmenubar,我创建了一个包含一些条目的菜单栏,其中一个是CheckBoxMenuItem。 如果选中该项,我想执行MouseListener事件,如果取消选中,我想让它停止 除此之外,我还创建了一个可以执行鼠标事件的JPanel和一个状态栏 为了解决这个问题,我想到了一个if循环: clickItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {

我创建了一个包含一些条目的菜单栏,其中一个是CheckBoxMenuItem。 如果选中该项,我想执行MouseListener事件,如果取消选中,我想让它停止

除此之外,我还创建了一个可以执行鼠标事件的JPanel和一个状态栏

为了解决这个问题,我想到了一个if循环:

clickItem.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent e) {
                   if (clickItem.getState() == true) {
                       mousePanel.addMouseListener(mouseHandler);
                       mousePanel.addMouseMotionListener(mouseHandler);
                   }
                   else if (clickItem.getState() == false) {                           
                       statusBar.setText("Mouse Mode OFF");
                   }    
               }
           });
但是如果我用这段代码运行我的程序,如果我取消选中复选框,带有鼠标事件的面板不会关闭

怎么了

编辑:

private JLabel statusBar;
private JPanel mousePanel;


private class HandlerClass implements MouseListener, MouseMotionListener {

// Mouse events for MouseListener

public void mouseClicked(MouseEvent event) {

statusBar.setText(String.format("Clicked at %d %d", event.getX(), event.getY()));
        }
...

HandlerClass mouseHandler = new HandlerClass();

OK,OpDebug,我知道,但是考虑建立一个模型视图控制器,其中视图是尽可能愚蠢的。它所做的只是创建用于显示的组件,仅此而已。模型保存复选框的状态,它保存鼠标的位置和状态——无论鼠标是被按下、拖动还是被释放。该模型可以使用JavaBean的属性侦听器支持,以便控制器可以向其添加侦听器,并收到状态更改的通知。整个事情可能看起来像:

import javax.swing.*;

// main program that creates the model and view and plugs them into 
// the controller
public class SimpleMvc {
    private static void createAndShowGui() {
        SimpleModel model = new SimpleModel();
        SimpleView view = new SimpleView();
        new SimpleController(model, view);

        JFrame frame = new JFrame("Simple MVC");
        frame.setJMenuBar(view.getJMenuBar());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(view.getMainPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}


每次单击复选框时,您都在添加鼠标侦听器。这是不正确的,您应该添加一次侦听器。请发布以获得更好的帮助。是否添加了输出以查看是否调用了该方法?你的if/elseif呢?我没有让鼠标模式关闭文本添加一些代码,也许这有助于进一步理解。不管怎样,谢谢你的帮助。当复选框菜单项被选中或取消选中时,最好简单地更改模型的状态。鼠标侦听器可以在鼠标事件发生时查询模型的状态。
import java.awt.Point;
import java.beans.PropertyChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;

// model that holds the state of the program
// and notifies listeners of changes in this state
public class SimpleModel {
    public static final String CHECK_STATE = "check state";
    public static final String MOUSE_POINT = "mouse point";
    public static final String MOUSE_STATE = "mouse state";
    private SwingPropertyChangeSupport support = new SwingPropertyChangeSupport(this);
    private boolean checkState = false;
    private Point mousePoint = null;
    private SimpleMouseState mouseState = SimpleMouseState.RELEASED;

    public boolean isCheckState() {
        return checkState;
    }

    public void setCheckState(boolean checkState) {
        boolean oldValue = this.checkState;
        boolean newValue = checkState;
        this.checkState = checkState;

        // notify the listeners of the change
        support.firePropertyChange(CHECK_STATE, oldValue, newValue);
    }

    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
        support.addPropertyChangeListener(propertyName, listener);
    }

    public Point getMousePoint() {
        return mousePoint;
    }

    public void setMousePoint(Point mousePoint) {
        Point oldValue = this.mousePoint;
        Point newValue = mousePoint;
        this.mousePoint = mousePoint;
        support.firePropertyChange(MOUSE_POINT, oldValue, newValue);
    }

    public SimpleMouseState getMouseState() {
        return mouseState;
    }

    public void setMouseState(SimpleMouseState mouseState) {
        SimpleMouseState oldValue = this.mouseState;
        SimpleMouseState newValue = mouseState;
        this.mouseState = mouseState;
        support.firePropertyChange(MOUSE_STATE, oldValue, newValue);
    }    
}
// enum to encapsulate the mouse state
public enum SimpleMouseState {
    PRESSED("Pressed"),
    DRAGGED("Dragged"),
    RELEASED("Released");
    private String text;

    private SimpleMouseState(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }
}
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;

// our view, again make it as dumb as possible
// all the "brains" are in the model and controller
public class SimpleView {
    private static final int PREF_W = 600;
    private static final int PREF_H = 450;
    private JComponent mainPanel = new JPanel();
    private JMenuBar menuBar = new JMenuBar();
    private JLabel statusLabel = new JLabel("  ");

    public SimpleView() {
        JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
        statusPanel.setBorder(BorderFactory.createEtchedBorder());
        statusPanel.add(statusLabel);

        mainPanel.setPreferredSize(new Dimension(PREF_W, PREF_H));
        mainPanel.setLayout(new BorderLayout());
        mainPanel.add(statusPanel, BorderLayout.PAGE_END);
    }

    public JComponent getMainPanel() {
        return mainPanel;
    }

    public JMenuBar getJMenuBar() {
        return menuBar;
    }

    public void setStatusMessage(String text) {
        statusLabel.setText(text);
    }

}
import java.awt.Point;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;

// our controller, where we hook everything together
public class SimpleController {
    public static final String MOUSE_MODE_OFF = "Mouse Mode OFF";
    public static final String MOUSE_MODE_ON = "Mouse Mode ON";
    private SimpleModel model;
    private SimpleView view;
    private JCheckBoxMenuItem clickItem = new JCheckBoxMenuItem("Click Me");

    public SimpleController(SimpleModel model, SimpleView view) {
        this.model = model;
        this.view = view;
        view.setStatusMessage(MOUSE_MODE_OFF);

        // Add view listeners
        clickItem.addItemListener(new ViewClickItemListener());
        JMenu menu = new JMenu("Menu");
        menu.add(clickItem);
        view.getJMenuBar().add(menu);
        ViewMouseListener mouseListener = new ViewMouseListener();
        view.getMainPanel().addMouseListener(mouseListener);
        view.getMainPanel().addMouseMotionListener(mouseListener);

        // add model listeners
        model.addPropertyChangeListener(SimpleModel.CHECK_STATE, new ModelCheckStateListener());
        model.addPropertyChangeListener(SimpleModel.MOUSE_POINT, new ModelMousePointListener());
        model.addPropertyChangeListener(SimpleModel.MOUSE_STATE, new ModelMouseStateListener());
    }

    private class ModelMousePointListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            Point p = (Point) evt.getNewValue();
            String text = model.getMouseState().getText();
            view.setStatusMessage(String.format("%s at [%03d, %03d]", text, p.x, p.y));            
        }
    }

    private class ModelMouseStateListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            Point p = model.getMousePoint();
            String text = model.getMouseState().getText();
            if (p == null) {
                return;
            }
            view.setStatusMessage(String.format("%s at [%03d, %03d]", text, p.x, p.y));            
        }
    }

    private class ModelCheckStateListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if ((boolean) evt.getNewValue()) {
                view.setStatusMessage(MOUSE_MODE_ON);
            } else {
                view.setStatusMessage(MOUSE_MODE_OFF);
            }
        }
    }

    private class ViewClickItemListener implements ItemListener {
        @Override
        public void itemStateChanged(ItemEvent e) {
            model.setCheckState(e.getStateChange() == ItemEvent.SELECTED);
        }
    }

    private class ViewMouseListener extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            // check model's check state first
            if (model.isCheckState()) {
                // mouse listener is active -- change the model's state
                model.setMouseState(SimpleMouseState.PRESSED);
                model.setMousePoint(e.getPoint());
            } // else do nothing
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            // similar to mouse pressed
            if (model.isCheckState()) {
                model.setMouseState(SimpleMouseState.DRAGGED);
                model.setMousePoint(e.getPoint());
            } // else do nothing            
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            // similar to mouse pressed
            if (model.isCheckState()) {
                model.setMouseState(SimpleMouseState.RELEASED);
                model.setMousePoint(e.getPoint());
            } // else do nothing            
        }
    }
}