- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个带有一些条目的菜单栏,其中之一是 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();
最佳答案
好吧,我知道,有点矫枉过正,但请考虑进行模型- View - Controller 设置,其中 View 尽可能愚蠢。它所做的只是创建用于显示的组件,仅此而已。该模型保存复选框的状态,它保存鼠标的位置和状态——无论是按下、拖动还是释放。该模型可以使用 Java Bean 的属性监听器支持,以便 Controller 可以向其添加监听器并收到状态更改的通知。整个事情可能看起来像:
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
}
}
}
关于如果未选中 CheckBoxMenuItem,Java 退出 MouseListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44783486/
我正在尝试使用 Nimbus 外观和感觉更改 CheckBoxMenuItem 的图标。 UIManager.put("CheckBoxMenuItem[Selected].checkIcon
我正在构建一个包含多个 MenuItem 的 AWT PopupMenu。这些项目具有在单击时触发命令的 ActionListeners。 添加到纯 MenuItems 的 ActionListene
有 CheckBoxMenuItems 和 ButtonGroup。当我为当前 CheckBoxMenuItem 设置监听器时,会检查条件并在此监听器中产生错误。我已经激活了另一个CheckBoxMe
我创建了一个带有一些条目的菜单栏,其中之一是 CheckBoxMenuItem。如果选中该项目,我想执行 MouseListener 事件,并且如果取消选中它,我希望它停止。 除此之外,我还创建了一个
我正在用 Java 编写一个简单的绘图程序,我有一个 MenuBar(不是 JMenuBar)来选择要绘制的形状和颜色。我想设置键盘快捷键以在矩形、椭圆形和直线之间进行选择。我知道我可以将 MenuS
我是一名优秀的程序员,十分优秀!