Java 从JFrame修改独立的JPanel

Java 从JFrame修改独立的JPanel,java,swing,jframe,jpanel,Java,Swing,Jframe,Jpanel,我有一个JFrame和两个独立的JPanel。其中一个jpanel用JButtons填充,而另一个有两个文本字段。我通过JFrame将鼠标侦听器添加到按钮中,我希望这样,当从第一个JPanel触发事件时,第二个JPanel中的文本字段会发生更改。这两个面板有自己的类。我该怎么做呢 使用MVC,模型视图控制,分离关注点 让保存侦听器的控件更改模型的状态 视图(您的GUI)由控件向其添加侦听器,以便将用户输入传输到控件,从而传输到模型 视图还可以直接将侦听器添加到模型中,以便在模型更改时可以更改其显

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

  • 使用MVC,模型视图控制,分离关注点
  • 让保存侦听器的控件更改模型的状态
  • 视图(您的GUI)由控件向其添加侦听器,以便将用户输入传输到控件,从而传输到模型
  • 视图还可以直接将侦听器添加到模型中,以便在模型更改时可以更改其显示,或者通常通过控件间接完成
  • 不要将鼠标侦听器添加到JButtons。使用ActionListeners,因为这就是它们的用途。例如,如果禁用JButton,任何附加到它的ActionListeners都将无法工作——这是正确的行为。对于鼠标听者来说,情况并非如此
  • < >为了更具体的帮助,请考虑创建和发布.
    编辑
    例如:

    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);
       }
    }
    
    该示例缺少使用接口,这将允许进一步分离关注点,从而导致更松散的耦合(一件好事)

  • 使用MVC,模型视图控制,分离关注点
  • 让保存侦听器的控件更改模型的状态
  • 视图(您的GUI)由控件向其添加侦听器,以便将用户输入传输到控件,从而传输到模型
  • 视图还可以直接将侦听器添加到模型中,以便在模型更改时可以更改其显示,或者通常通过控件间接完成
  • 不要将鼠标侦听器添加到JButtons。使用ActionListeners,因为这就是它们的用途。例如,如果禁用JButton,任何附加到它的ActionListeners都将无法工作——这是正确的行为。对于鼠标听者来说,情况并非如此
  • < >为了更具体的帮助,请考虑创建和发布.
    编辑
    例如:

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

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

    清晰简洁,示例如下。谢谢大家!@西尔弗:不客气。请注意,我不是专业人士,因此这可能是一个很糟糕的例子。+1然后…但是顺便说一下,有很多MVC版本,有时模型作为swing组件从视图中是不可见的are@nachokk:是的,但是它将被控件观察到,这就是为什么我将“间接”位放在上面的原因。清晰简洁,带有示例。谢谢大家!@西尔弗:不客气。请注意,我不是专业人士,因此这可能是一个很糟糕的例子。+1然后…但是顺便说一下,有很多MVC版本,有时模型作为swing组件从视图中是不可见的are@nachokk:是的,但是控件将观察到它,这就是我将“间接”位置于上方的原因。