gpt4 book ai didi

java - 使用界面更新 GUI

转载 作者:行者123 更新时间:2023-12-02 05:37:31 24 4
gpt4 key购买 nike

一位经验丰富的开发人员告诉我,传递 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.this 传递给有问题的 DataClass,然后使用 addActivity("status update") ;

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

public interface GuiUpdater {

void update(MyGui MyGui, String update);
}

并修改了上面的MyGui类来实现该接口(interface)并这样调用:

   @Override
public void update(MyGui myGui, String update) {
// TODO Auto-generated method stub
myGui.addActivity(update);
}

所以我可以从其他类中更新它,我也实现了这个接口(interface)。所以我将 MyGui 的实例从 main 传递给其他类。

我认为这和我之前做的事情是一样的(只是不同)。

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

最佳答案

接口(interface)用于定义对象可以支持的方法,而不需要接口(interface)的使用者了解有关该对象的太多信息或它希望如何实现该接口(interface)。在您的情况下,您希望为 MyGui 提供一个更新方法,该方法不需要 MyGui 类与其他代码之间的紧密耦合。如果您这样定义界面,那么您可以编写可能需要更新 GUI 的所有代码,以仅与 GuiUpdater 类型的对象交互:

public interface GuiUpdater {

void update(String update);
}

然后,您将修改 MyGui 类声明来实现此接口(interface):

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 满足该接口(interface)。这将 foo 的实现与 MyGui 的实现解耦,并且意味着任何一方都不会受到对另一方实现的更改的影响。

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

关于java - 使用界面更新 GUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24836365/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com