Modifying independent JPanels from the JFrame(从 JFrame 修改独立的 JPanel)
问题描述
我有一个带有两个独立 JPanel 的 JFrame.其中一个 JPanel 充满了 JButton,而另一个则有几个文本字段.我通过 JFrame 向按钮添加了鼠标侦听器,并且我想这样做,以便当从第一个 JPanel 触发事件时,第二个 JPanel 中的文本字段会发生更改.这两个面板有自己的类.我该怎么做呢?
I've got a JFrame with two separate JPanels. One of the JPanels is filled with JButtons while the other has a couple of text fields. I added mouse listeners to the buttons via the JFrame and I want to make it so that when an event is fired from the first JPanel, the text fields in the second JPanel are changed. The two panels have their own classes. How would I go about doing this?
推荐答案
- 使用 MVC、模型-视图-控制、关注点分离.
- 让包含您的侦听器的控件更改模型的状态.
- 视图 - 您的 GUI,控件添加了侦听器,以便将用户输入传输到控件,从而传输到模型.
- View 也可以直接向模型添加侦听器,以便在模型更改时它们可以更改其显示,或者通常通过控件间接完成.
- 不要将 MouseListeners 添加到 JButtons.使用 ActionListeners,因为这就是它们的用途.例如,如果您禁用一个 JButton,任何附加到它的 ActionListener 都将不起作用——这是正确的行为.MouseListener 的情况并非如此.
如需更具体的帮助,请考虑创建和发布最小示例程序.
For more specific help, consider creating and posting a minimal example program.
编辑
例如:
import java.awt.GridLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.SwingPropertyChangeSupport;
public class MvcMain {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MvcView view = new MvcView();
MvcModel model = new MvcModel();
MvcControl control = new MvcControl(view, model);
view.createAndDisplay();
}
});
}
}
class MvcView {
private MvcModel model;
private ButtonPanel buttonPanel = new ButtonPanel();
private TextFieldPanel textFieldPanel = new TextFieldPanel();
private JPanel mainPanel = new JPanel();
public MvcModel getModel() {
return model;
}
public ButtonPanel getButtonPanel() {
return buttonPanel;
}
public TextFieldPanel getTextFieldPanel() {
return textFieldPanel;
}
public MvcView() {
mainPanel.setLayout(new GridLayout(0, 1));
mainPanel.add(textFieldPanel);
mainPanel.add(buttonPanel);
}
public void setModel(MvcModel model) {
this.model = model;
model.addPropertyChangeListener(new ModelListener());
}
public void createAndDisplay() {
JFrame frame = new JFrame("MVC Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class ModelListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (ButtonTitle.class.getCanonicalName().equals(evt.getPropertyName())) {
ButtonTitle newValue = model.getButtonTitle();
textFieldPanel.textFieldSetText(newValue.getTitle());
}
}
}
}
enum ButtonTitle {
START("Start"), STOP("Stop"), PAUSE("Pause");
private String title;
private ButtonTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
}
@SuppressWarnings("serial")
class ButtonPanel extends JPanel {
public ButtonPanel() {
setBorder(BorderFactory.createTitledBorder("Button Panel"));
setLayout(new GridLayout(1, 0, 5, 0));
for (ButtonTitle btnTitle : ButtonTitle.values()) {
add(new JButton(new ButtonAction(btnTitle)));
}
}
private class ButtonAction extends AbstractAction {
private ButtonTitle btnTitle;
public ButtonAction(ButtonTitle btnTitle) {
super(btnTitle.getTitle());
this.btnTitle = btnTitle;
}
public void actionPerformed(java.awt.event.ActionEvent e) {
Object oldValue = null;
ButtonTitle newValue = btnTitle;
ButtonPanel.this.firePropertyChange(
ButtonTitle.class.getCanonicalName(), oldValue, newValue);
};
}
}
@SuppressWarnings("serial")
class TextFieldPanel extends JPanel {
private JTextField textField = new JTextField(15);
public TextFieldPanel() {
setBorder(BorderFactory.createTitledBorder("TextField Panel"));
add(textField);
}
public void textFieldSetText(String text) {
textField.setText(text);
}
}
class MvcControl {
private MvcView view;
private MvcModel model;
public MvcControl(MvcView view, MvcModel model) {
this.view = view;
this.model = model;
view.setModel(model);
view.getButtonPanel().addPropertyChangeListener(new ButtonPanelListener());
}
private class ButtonPanelListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (ButtonTitle.class.getCanonicalName().equals(evt.getPropertyName())) {
ButtonTitle newValue = (ButtonTitle) evt.getNewValue();
model.setButtonTitle(newValue);
}
}
}
}
class MvcModel {
private ButtonTitle buttonTitle;
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public ButtonTitle getButtonTitle() {
return buttonTitle;
}
public void setButtonTitle(ButtonTitle buttonTitle) {
ButtonTitle oldValue = this.buttonTitle;
ButtonTitle newValue = buttonTitle;
this.buttonTitle = buttonTitle;
pcSupport.firePropertyChange(ButtonTitle.class.getCanonicalName(),
oldValue, newValue);
}
}
该示例缺少使用接口,这将允许进一步分离关注点,从而导致更松散的耦合(一件好事).
The example is lacking in use of interfaces which would allow for a further separation of concerns resulting in looser coupling (a good thing).
这篇关于从 JFrame 修改独立的 JPanel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从 JFrame 修改独立的 JPanel
基础教程推荐
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01