从 JFrame 修改独立的 JPanel

2023-12-09

我有一个带有两个独立 JPanel 的 JFrame。其中一个 JPanel 充满了 JButton,而另一个则有几个文本字段。我通过 JFrame 将鼠标侦听器添加到按钮,并且希望当从第一个 JPanel 触发事件时,第二个 JPanel 中的文本字段会发生更改。这两个面板有自己的类。我该怎么做呢?


  1. 使用MVC、模型-视图-控制、关注点分离。
  2. 让控制监听器来改变模型的状态。
  3. 视图——您的 GUI,具有由控件添加到其中的侦听器,以便将用户输入传输到控件,从而传输到模型。
  4. 视图还可以直接向模型添加侦听器,以便在模型更改时侦听器可以更改其显示,或者通常这是通过控件间接完成的。
  5. 不要将 MouseListener 添加到 JButton。使用 ActionListeners,因为这就是它们的用途。例如,如果禁用 JButton,则附加到它的任何 ActionListener 将无法工作——这是正确的行为。对于 MouseListener 来说情况并非如此。

如需更具体的帮助,请考虑创建并发布最小示例程序.


Edit
例如:

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

该示例缺乏接口的使用,这将允许进一​​步分离关注点,从而导致更松散的耦合(这是一件好事)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 JFrame 修改独立的 JPanel 的相关文章

随机推荐

  • 如何衡量承诺的执行时间?

    我正在尝试编写一个函数来测量另一个函数的执行时间 export class Profiler public measureSyncFunc fn gt any Promise
  • 从命令行使用 nntool [MATLAB]

    我有这个代码 in 5 columns of data points out 1 column of data points net newfit in out 5 net train net in out 现在我想要 访问误差变量生成的
  • 在matlab中加载stl文件并转换为3D数组

    我有一个 stl 文件 我已使用 stlread 函数将其加载到 Matlab 中 此时我有一组面和顶点 如何将这些面和顶点转换为 512x512x100 数组等 3D 二进制数组以获得二进制 3D 体积 啊你真幸运 我最近正在处理 STL
  • C++ 中运算符 << 的重写

    我正在为我的学校做一个 C 项目 我有两个班级 雇员和老师 Teacher 源自 Employe 并优先于其职能 我们重写运算符 lt lt 打印员工或教师的一些信息 每个班级都有一个const int attribute LevelAcc
  • 密钥“PRIMARY”重复输入“0”

    我不明白为什么在尝试填充此表时会收到此错误 目前表中没有任何内容 所以我不明白为什么会有重复的 这是我正在使用的代码 INSERT INTO Suppliers supp id company name town phone Values
  • 调试rails 3.1.1 应用程序

    我尝试向使用 ruby 1 9 2 的 Rails 3 1 1 应用程序添加调试器 我已将以下内容添加到我的 gemfile 中 gem ruby debug19 require gt ruby debug 我收到以下错误 rvm gems
  • 使用 PHP 发送批量电子邮件

    当新用户加入时 我必须向网站中的所有用户发送邮件 我的问题是脚本在发送大约 400 封邮件后停止执行 我已将 set time limit 设置为 0 并且我在发送 10 封邮件后给予 sleep 2 此问题背后的原因可能是什么 此问题的任
  • 列表列表到词典列表

    如何将列表列表转换为字典列表 更具体地说 我该如何处理 a1 b1 c1 d1 e1 f1 g1 h1 i1 a2 b2 c2 d2 e2 f2 g2 h2 i2 a3 b3 c3 d3 e3 f3 g3 h3 i3 a4 b4 c4 d4
  • JBoss 7.1 Weld 在耳边的罐子里发现了 Managed Bean,但战争并没有

    jboss as 7 1 1 动态 Web 模块 3 0 JSF 2 0 Mojarra Eclipse Indigo sr2 我有一个 EAR Ynale ear 其中包含一个 YnaleImpl jar 和一个 Ynale war Yn
  • 我如何操作一个非常大的列表

    我有超过 10000 个文件 我首先将目录设置为文件所在的文件夹 然后我用以下命令链接到所有文件 txt像这样的格式 filenames lt list files path to the file pattern txt full nam
  • DENSE_RANK() 无重复

    我的数据如下所示 col1 col2 denserank whatiwant 1 1 1 1 2 1 1 1 3 2 2 2 4 2 2 2 5 1 1 3 6 2 2 4 7 2 2
  • 如果通过 Xcode 安装应用程序,它会在我的 iOS 设备上继续运行多长时间?

    刚刚开始使用 iOS 并构建了一个非常简单的应用程序 我在 iPad 上使用和测试了该应用程序 如果我在 Xcode 中单击 停止 应用程序仍然可以在我的 iPad 上启动和使用 而无需 Xcode 调试 考虑到我没有 Apple 开发者帐
  • Android 平台上的“Fatal signal 7 (SIGBUS) at 0x5937abd0 (code=2)”到底是什么意思?

    致命信号 7 SIGBUS at 0x5937abd0 code 2 的确切含义是什么 回溯和堆栈信息如下 12 23 17 43 37 904 F libc 16421 Fatal signal 7 SIGBUS at 0x5937abd
  • 自定义 WordPress 3.5.2 插件“您没有足够的权限访问此页面。”

    我一直在尝试集成一个名为的自定义 WordPress 插件custom rss通过以下方式进入 WordPresshttp net tutsplus com tutorials wordpress creating a custom wor
  • 删除android中的特定联系人

    在我的应用程序中 我需要删除特定的CONTACT从电话通讯录中 但我只删除了特定号码 而不是整个联系人 所以请帮助我 提前致谢 要删除所有联系人 请使用以下代码 ContentResolver cr getContentResolver C
  • 升级后,@MapsId 在保存现有实体时抛出错误,但在其他方面工作正常

    我正在努力升级Spring Boot 1 5 21 项目 Java 8u221 to Spring Boot 2 1 9 Java 11 0 2 开放 在这两种情况下 我们都使用带有 spring boot 启动器和依赖解析器的 gradl
  • 如何在 AngularJS 中检测 HTML 渲染何时完成

    我对这个课题进行了广泛的研究 但无论我做什么 我发现实现这个目标都极其困难 我想在 AngularJS Web 应用程序中完全呈现所有元素时执行代码 我想我找到了建议使用路由器和视图的解决方案 但我无法在我的情况下使用它 因为它似乎需要某些
  • 使用 String hashCode() 方法? [关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 来自链接 http www tutorialspoint com java java string hashcode htm Java中hashCode和equals方法的关系 良好的
  • Python Pylab,如何更改指定轴大小的标签的大小

    我正在尝试绘制核衰变的微分横截面 因此 y 轴的大小约为10 38 m 2 pylab 默认将轴绘制为0 0 0 2 0 4 等并有一个 1e 38 在 y 轴的顶部 我需要增加一点字体大小 我尝试过调整标签大小 py tick param
  • 从 JFrame 修改独立的 JPanel

    我有一个带有两个独立 JPanel 的 JFrame 其中一个 JPanel 充满了 JButton 而另一个则有几个文本字段 我通过 JFrame 将鼠标侦听器添加到按钮 并且希望当从第一个 JPanel 触发事件时 第二个 JPanel