且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

修改JFrame中的独立JPanel

更新时间:2023-12-05 08:55:58


  1. 使用MVC,模型 - 视图 - 控制,分离关注。

  2. 拥有控制器,控制你的听众,改变模型的状态。

  3. 视图 - 你的GUI,有听众通过控件添加到它们,以便将用户输入传输到控件,从而传输到模型。

  4. View还可以直接向模型添加侦听器,以便在模型更改时更改其显示,或者通常通过控件间接完成。

  5. 不要将MouseListeners添加到JButtons。使用ActionListeners就是他们的用途。例如,如果禁用JButton,则附加到它的任何ActionListener都将无效 - 这是正确的行为。 MouseListeners也是如此。

  1. Use MVC, Model-View-Control, separation of concerns.
  2. Have the Control, which holds your listeners, change the state of the model.
  3. The Views -- your GUI's, have listeners added to them by the control, so that user input is transmitted to the control and thereby to the model.
  4. The View can also either directly add listeners to the model so that they can change their display if the model changes, or often this is done indirectly through the control.
  5. Don't add MouseListeners to JButtons. Use ActionListeners as that's what they're for. For example, if you disable a JButton, any ActionListeners attached to it won't work -- which is correct behavior. The same is not true for MouseListeners.

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

For more specific help, consider creating and posting a minimal example program.

编辑


例如:

Edit
For example:

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).