简介
由于这是一个老问题,我想我应该整理一个简单的 Swing GUI 来说明 MouseListener 的工作原理。
这是我做任何事情之前的 GUI。
当鼠标移动到选择区域时,中心的主面板将呈现选择器颜色。当鼠标移出选择区域时,主面板将恢复原来的颜色。
这是我的鼠标位于蓝色选择区域时的 GUI。
说明
如果您不熟悉 Java Swing,Oracle 提供了一个有用的教程,Creating a GUI With Swing。跳过使用 NetBeans IDE 学习摇摆部分。密切关注Concurrency in Swing 和Laying Out Components Within a Container 部分。
创建 Swing GUI 时,我使用 model/view/controller (MVC) 模式。这种模式使我能够分离我的关注点并一次专注于应用程序的一个部分。
MVC 模式意味着您首先创建模型,然后是视图,然后是控制器。这更像是一个迭代过程而不是瀑布。
在 Java Swing 中,MVC 模式意味着:
- 视图从模型中读取信息。
- 视图可能不会更新模型。
- 控制器更新模型并重新绘制/重新验证视图。
该模型由一个或多个普通 Java getter/setter 类组成。
视图由JFrame 和创建GUI 所需的JPanels 组成。
通常没有一个控制器来“统治他们所有人”。每个侦听器都充当独立的控制器来管理其模型和视图部分。
这是一个简单的应用程序,因此它由两个模型类、一个视图类和一个控制器类组成。在这个例子中模型根本没有更新。
我不是一次编写整个应用程序的代码。我写了几行代码并运行了测试。在对代码的工作方式感到满意之前,我对代码进行了很多更改。
型号
ColorSelection 类是一个普通的 Java getter/setter 类,它包含颜色名称、背景颜色和前景色。
MouseMovementModel 类是一个普通的 Java getter/setter 类,它包含 ColorSelection 实例。 GUI 基于此信息构建选择 JPanel。如果要添加其他选择颜色,请在此处添加。
查看
视图由JFrame、选择JPanel和主JPanel组成。
JFrame 有一个默认的BorderLayout。选择JPanel 进入NORTH 部分,主JPanel 进入CENTER 部分。一个部分中只能放置一个组件。该组件通常是JPanel。
选择JPanel 使用FlowLayout 来保存颜色选择JPanels。颜色选择JPanels 是根据应用程序模型中ColorSelection 实例的数量创建的。
颜色选择JPanel 是一个简单的JPanel,用于使用来自ColorSelection 实例的信息。
主要的JPanel 是一个简单的JPanel,它将显示背景颜色。控制器将负责更改背景颜色。
控制器
ColorListener 类扩展了 MouseAdapter。 MouseAdapter 类实现了MouseListener、MouseMotionListener 和MouseWheelListener 接口。使用MouseAdapter 类允许我只实现我正在为其编写代码的鼠标侦听器方法。
mouseEntered 方法将主要的JPanel 设置为ColorSelection 颜色。代码真的很简单。它使用ColorSelection 背景颜色更新视图。
mouseExited 方法将主 JPanel 设置回其原始颜色。
代码
这是完整的可运行代码。我将附加类设为内部类,以便将代码作为一个块发布。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MouseMovementExample implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new MouseMovementExample());
}
private final JPanel mainPanel;
private final JPanel[] colorPanel;
private final MouseMovementModel model;
public MouseMovementExample() {
this.model = new MouseMovementModel();
this.mainPanel = createMainPanel();
this.colorPanel = new JPanel[model.getSelections().length];
}
@Override
public void run() {
JFrame frame = new JFrame("Mouse Movement Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createSelectionPanel(), BorderLayout.NORTH);
frame.add(mainPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createSelectionPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
ColorSelection[] selections = model.getSelections();
for (int index = 0; index < selections.length; index++) {
ColorSelection selection = selections[index];
ColorListener listener = new ColorListener(this, selection);
colorPanel[index] = createColorPanel(selection, listener);
panel.add(colorPanel[index]);
}
return panel;
}
private JPanel createColorPanel(ColorSelection selection, ColorListener listener) {
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(selection.getBackgroundColor());
panel.addMouseListener(listener);
panel.setPreferredSize(new Dimension(200, 100));
JLabel label = new JLabel(selection.getColorName());
label.setFont(panel.getFont().deriveFont(Font.BOLD, 36f));
label.setForeground(selection.getForegroundColor());
label.setHorizontalAlignment(JLabel.CENTER);
panel.add(label, BorderLayout.CENTER);
return panel;
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(200, 200));
return panel;
}
public Color getMainPanelBackground() {
return this.mainPanel.getBackground();
}
public void setMainPanelBackground(Color color) {
this.mainPanel.setBackground(color);
}
public class ColorListener extends MouseAdapter {
private final Color originalBackgroundColor;
private final ColorSelection selection;
private final MouseMovementExample view;
public ColorListener(MouseMovementExample view, ColorSelection selection) {
this.view = view;
this.selection = selection;
this.originalBackgroundColor = view.getMainPanelBackground();
}
@Override
public void mouseEntered(MouseEvent e) {
view.setMainPanelBackground(selection.getBackgroundColor());
}
@Override
public void mouseExited(MouseEvent e) {
view.setMainPanelBackground(originalBackgroundColor);
}
}
public class MouseMovementModel {
private final ColorSelection[] selections;
public MouseMovementModel() {
this.selections = new ColorSelection[3];
this.selections[0] = new ColorSelection("Red", Color.RED, Color.WHITE);
this.selections[1] = new ColorSelection("Green", Color.GREEN, Color.BLACK);
this.selections[2] = new ColorSelection("Blue", Color.BLUE, Color.WHITE);
}
public ColorSelection[] getSelections() {
return selections;
}
}
public class ColorSelection {
private final Color backgroundColor, foregroundColor;
private final String colorName;
public ColorSelection(String colorName, Color backgroundColor, Color foregroundColor) {
this.colorName = colorName;
this.backgroundColor = backgroundColor;
this.foregroundColor = foregroundColor;
}
public Color getBackgroundColor() {
return backgroundColor;
}
public Color getForegroundColor() {
return foregroundColor;
}
public String getColorName() {
return colorName;
}
}
}