2017-06-27 3 views
0

J'ai créé une barre de menu avec quelques entrées et l'une d'elles est un CheckBoxMenuItem. Je veux effectuer un événement MouseListener si cet élément est coché et je veux qu'il s'arrête avec ça si je le décoche. En plus de cela, j'ai créé un JPanel sur lequel des événements de souris peuvent être effectués et une barre d'état.Java Quitter MouseListener si CheckBoxMenuItem est décoché

Pour résoudre ce problème, je pensais à un si boucle:

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"); 
        }  
       } 
      }); 

Mais si je lance mon programme avec ce code, le panneau avec les événements de souris ne se désactive pas si je décocher la case à cocher .

Qu'est-ce qui ne va pas?

Edit:

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(); 
+2

Vous ajoutez mouselistener chaque fois que vous cliquez sur la case à cocher. Ce n'est pas correct, vous devriez ajouter un auditeur une fois. Veuillez publier un [MCVE] (https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwi0zr-5pN7UAhWOa1AKHWSIBCMQFggrMAA&url=https%3A%2F%2Fstackoverflow.com % 2Fhelp% 2Fmcve & usg = AFQjCNHreFGjawnJ-ucm2EGso8qxNscnMA) pour obtenir une meilleure aide. – SomeDude

+0

Avez-vous ajouté une sortie pour voir si la méthode est appelée? Qu'en est-il de votre if/elseif? – Nathan

+0

Le mode souris n'est pas désactivé Texte Ajout d'un code, peut-être que cela aide à mieux comprendre. Merci pour l'aide de toute façon. – Corbjn

Répondre

1

OK, surpuissant, je sais, mais envisager de faire un Model-View-Controller mis en place, où la vue est aussi stupide que possible. Tout ce qu'il fait est de créer ses composants pour l'affichage et c'est tout. Le modèle conserve l'état de la case à cocher, il contient l'emplacement et l'état de la souris - si elle a été enfoncée, est en train de glisser ou est libérée. Le modèle peut utiliser le support de l'écouteur de propriétés de Java Bean pour que le contrôleur puisse y ajouter des écouteurs et être averti des changements d'état. Tout cela pourrait ressembler à:

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()); 
    } 
} 

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    
     } 
    } 
}