Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用界面更新GUI_Java_User Interface_Interface_Jtextarea - Fatal编程技术网

Java 使用界面更新GUI

Java 使用界面更新GUI,java,user-interface,interface,jtextarea,Java,User Interface,Interface,Jtextarea,一位经验丰富的开发人员告诉我,传递GUI实例是个坏主意 基本上,我有一个构建和显示GUI的类。在actionListener中,我创建了一个执行一些时间密集型任务的对象,并希望在任务的某些里程碑完成时显示状态 下面是该课程的一个非常简化的版本: public class MyGui extends JFrame { private static final long serialVersionUID = 1L; private JPanel mainPanel; priva

一位经验丰富的开发人员告诉我,传递GUI实例是个坏主意

基本上,我有一个构建和显示GUI的类。在actionListener中,我创建了一个执行一些时间密集型任务的对象,并希望在任务的某些里程碑完成时显示状态

下面是该课程的一个非常简化的版本:

public class MyGui extends JFrame {

   private static final long serialVersionUID = 1L;

   private JPanel mainPanel;
   private JPanel selectionPanel;
   private JPanel activityPanel;
   private JPanel executePanel;

   private JButton connectButton;
   private JButton disconnectButton;
   private JButton abortButton;

   private JList aList;

   private JComboBox comboBox;

   private JRadioButton primaryButton;
   private JRadioButton secondaryButton;

   private static JTextArea activityTextArea;

   MyGui() {

      this.setTitle("My Tool");

      mainPanel = new JPanel();
      mainPanel.setLayout(new GridLayout(3, 1));
      mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      mainPanel.setBackground(Color.darkGray);
      this.add(mainPanel);

      createMainSelectionArea();
      createNodeSelectionArea();
      createStatusArea();
      createExecuteArea();

      mainPanel.add(selectionPanel);
      mainPanel.add(activityPanel);
      mainPanel.add(executePanel);

      this.add(mainPanel);
      this.setResizable(false);

      addActivity("test1");
      addActivity("test2");
      addActivity("test3");
      addActivity("test4");
      addActivity("test5");
      addActivity("test6");

      this.setSize(600, 400);
      this.setVisible(true);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }

   private void createMainSelectionArea() {

      RadioButtonListener radioButtonListener = new RadioButtonListener();

      primaryButton = new JRadioButton("Primary");
      primaryButton.setBackground(Color.darkGray);
      primaryButton.setForeground(Color.white);
      primaryButton.addActionListener(radioButtonListener);

      secondaryButton = new JRadioButton("Secondary");
      secondaryButton.setBackground(Color.darkGray);
      secondaryButton.setForeground(Color.white);
      secondaryButton.addActionListener(radioButtonListener);

      ButtonGroup buttonGroup = new ButtonGroup();
      buttonGroup.add(primaryButton);
      buttonGroup.add(secondaryButton);

      JPanel buttonGroupPanel = new JPanel(new GridLayout(3, 1));
      buttonGroupPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      buttonGroupPanel.setOpaque(true);
      buttonGroupPanel.setBackground(Color.darkGray);
      buttonGroupPanel.setForeground(Color.white);
      buttonGroupPanel.add(primaryButton);
      buttonGroupPanel.add(secondaryButton);

      selectionPanel = new JPanel(new GridLayout(1, 2));
      selectionPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      selectionPanel.setBackground(Color.darkGray);
      selectionPanel.add(buttonGroupPanel);
   }

   private void createNodeSelectionArea() {

      String[] data1 = {"one", "two", "three", "4", "5", "6"};
      String[] data2 = {"four", "five", "six", "seven", "eight"};

      ComboBoxListener comboBoxListener = new ComboBoxListener();

      comboBox = new JComboBox(data1);
      comboBox.setBorder(BorderFactory.createLineBorder(Color.white));
      comboBox.setPreferredSize(new Dimension(150, 20));;
      comboBox.setBackground(Color.white);
      comboBox.setForeground(Color.black);
      comboBox.addActionListener(comboBoxListener);

      JPanel comboBoxPanel = new JPanel();
      comboBoxPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      comboBoxPanel.setBackground(Color.darkGray);
      comboBoxPanel.add(comboBox, BorderLayout.CENTER);

      ListBoxListener listBoxListener = new ListBoxListener();

      aList = new JList(data2);
      aList.setBackground(Color.black);
      aList.setForeground(Color.white);
      aList.addListSelectionListener(listBoxListener);

      JScrollPane scrollPane = new JScrollPane(aList);
      scrollPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
      scrollPane.setBackground(Color.darkGray);

      JPanel listBoxPanel = new JPanel(new GridLayout(1,1));
      TitledBorder border = BorderFactory.createTitledBorder("A Selection");
      border.setTitleColor(Color.white);
      border.setBorder(BorderFactory.createLineBorder(Color.white));

      listBoxPanel.setBorder(border);
      listBoxPanel.setBackground(Color.darkGray);
      listBoxPanel.setForeground(Color.white);
      listBoxPanel.add(scrollPane);

      selectionPanel.add(comboBoxPanel);
      selectionPanel.add(listBoxPanel);
   }

   private void createStatusArea() {

      activityTextArea = new JTextArea();
      activityTextArea.setEditable(false);
      activityTextArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
      activityTextArea.setBackground(Color.black);
      activityTextArea.setForeground(Color.white);

      JScrollPane scrollPane = new JScrollPane(activityTextArea);
      scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      scrollPane.setBackground(Color.darkGray);

      TitledBorder activityTitle = BorderFactory.createTitledBorder("Status");
      activityTitle.setTitleColor(Color.white);
      activityTitle.setBorder(BorderFactory.createLineBorder(Color.white));
      activityTitle.setTitlePosition(TitledBorder.CENTER);

      activityPanel = new JPanel(new GridLayout(1, 1));
      activityPanel.setBackground(Color.darkGray);
      activityPanel.setBorder(activityTitle);
      activityPanel.add(scrollPane);
   }

   public void addActivity(String activity) {

      activityTextArea.append(activity + "\n");
      activityTextArea.setCaretPosition(activityTextArea.getDocument().getLength());
   }

   public void createExecuteArea() {

      ButtonListener buttonListener = new ButtonListener();

      connectButton = new JButton("Connect");
      connectButton.setPreferredSize(new Dimension(115, 30));
      connectButton.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory.createLineBorder(Color.lightGray)));
      connectButton.setBackground(Color.white);
      connectButton.addActionListener(buttonListener);

      disconnectButton = new JButton("Disconnect");
      disconnectButton.setPreferredSize(new Dimension(115, 30));
      disconnectButton.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory.createLineBorder(Color.lightGray)));
      disconnectButton.setBackground(Color.white);
      disconnectButton.addActionListener(buttonListener);

      abortButton = new JButton("Abort");
      abortButton.setPreferredSize(new Dimension(115, 30));
      abortButton.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory.createLineBorder(Color.lightGray)));
      abortButton.setBackground(Color.white);
      abortButton.addActionListener(buttonListener);

      executePanel = new JPanel(new GridBagLayout());
      executePanel.setBackground(Color.darkGray);
      GridBagConstraints c = new GridBagConstraints();

      JPanel buttonPanel = new JPanel();
      buttonPanel.setBackground(Color.darkGray);

      buttonPanel.add(connectButton);
      buttonPanel.add(disconnectButton);
      buttonPanel.add(abortButton);

      executePanel.add(buttonPanel, c);
   }

   private class ButtonListener implements ActionListener {

      @Override
      public void actionPerformed(ActionEvent e) {

         if(e.getSource().equals(connectButton)) { 

            System.out.println("Connect Button"); 
         }

         if(e.getSource().equals(disconnectButton)) { 

            System.out.println("Disconnect Button"); 
         }

         if(e.getSource().equals(abortButton)) { 

            System.out.println("Abort Button"); 
         }
      }
   }

   private class RadioButtonListener implements ActionListener {

      @Override
      public void actionPerformed(ActionEvent e) {

         if(e.getSource().equals(primaryButton)) {

            System.out.println("Primary Selected");
         }

         if(e.getSource().equals(secondaryButton)) {

            System.out.println("Secondary Selected");
         }
      }
   }

   private class ComboBoxListener implements ActionListener {

      @Override
      public void actionPerformed(ActionEvent e) {

         if(e.getSource().equals(comboBox)) {

            System.out.println(comboBox.getSelectedItem());
            DataClass dataClass = new DataClass(MyGui.this, otherStuff);
            dataClass.doStuff();  // This class was calling the addActivity() method.
         }
      }
   }

   private class ListBoxListener implements ListSelectionListener {

      @Override
      public void valueChanged(ListSelectionEvent e) {

         if(e.getSource().equals(aList)) {

            System.out.println(aList.getSelectedValue());
         }
      }
   }

}
因此,我将(假设类名为MyGui)传递给
MyGui

因此,我没有执行上述操作,而是创建了以下界面:

public interface GuiUpdater {

   void update(MyGui MyGui, String update);
}
public class MyGui extends JFrame implements GuiUpdater {
并修改了上面的
MyGui
类来实现该接口,并以这种方式调用它:

   @Override
   public void update(MyGui myGui, String update) {
      // TODO Auto-generated method stub
      myGui.addActivity(update);
   }
所以我可以从其他类中更新它,我也在这些类中实现了这个接口。因此,我将MyGui的一个实例从main传递给其他类

我认为这和我以前做的事情是一样的(只是不同而已)


这是使用接口的正确方式吗?如果不是,在不传递GUI实例的情况下,从不同类更新GUI的正确方法是什么?

接口用于定义对象可以支持的方法,而无需接口的使用者了解该对象或其希望实现接口的方式。在您的情况下,您希望在
MyGui
上提供一个更新方法,该方法不需要在
MyGui
类和其他代码之间进行紧密耦合。如果这样定义接口,则可以编写可能需要更新GUI以仅与类型为
GuiUpdater
的对象交互的所有代码:

public interface GuiUpdater {

   void update(String update);
}
然后修改
MyGui
类声明以实现此接口:

public interface GuiUpdater {

   void update(MyGui MyGui, String update);
}
public class MyGui extends JFrame implements GuiUpdater {
您还必须在
MyGui
中实现此方法:

@Override
public void update(String update) {
     this.addActivity(update);
}
这与你在问题中的观点相似,但有一个重要区别。因为它是作为
MyGui
内部的方法实现的,所以您可以访问
MyGui
实例的所有内部状态(例如
this
)。换句话说,您不需要将
MyGui
实例作为参数传递,因为此方法位于
MyGui
内部

现在,我们可以假设您有一个名为
MyGui
MyGui
实例,它有一个可能需要更新GUI的函数,例如:

public void foo(GuiUpdater updater) {
    updater.update("Interfaces are great");
}
您可以像调用
foo(myGui)
一样调用此函数,因为
myGui
满足该接口。这将
foo
的实现与
MyGui
的实现分离,并意味着任何一方都不会受到另一方实现更改的影响


无论您如何构建软件(MVC、MVP等),编写接口代码都是一个好习惯。它隐藏了实现细节,因此减少了更改这些细节的影响。

如果您的MyGui类正在实现接口,为什么要将MyGui参数添加到方法中?“这不是多余的吗?”我想这是我困惑的一部分。在没有MyGui参数的情况下,如何从其他类更新textArea?这在MyGui类中是多余的-你是对的。你熟悉MCV设计模式,模型视图控制吗?这是许多人使用的,您可以通过控件链接模型和视图(GUI)。@HovercraftFullOfEels我不熟悉MCV,但我会研究它。我建议您研究一下,包括在和标记的组合上搜索此网站。一旦您了解了这一点,请研究依赖注入。