Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.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 刷新选项卡开关上的JPanel内容_Java_Swing_Jpanel_Jtabbedpane - Fatal编程技术网

Java 刷新选项卡开关上的JPanel内容

Java 刷新选项卡开关上的JPanel内容,java,swing,jpanel,jtabbedpane,Java,Swing,Jpanel,Jtabbedpane,我正在编写一个简单的UI,只是为了掌握一些窍门。我有一个选项卡式窗口,有两个选项卡,一个有一个按钮,可以计算一个整数,另一个有一个文本字段,显示所述整数的内容。至少这是计划 如果我把所有的东西都塞进一节课,一切都会很好。我可以从actionlistener访问tab 1,并从tab 2中的按键更改tab 1中的文本字段。但很明显,我不想把我的整个课程都放在一节课上 在这里,我不知道该做什么:我需要告诉类Tab1中的textfield在类Tab2中的按钮上进行更改。在这里应该做什么?我的第一个想法

我正在编写一个简单的UI,只是为了掌握一些窍门。我有一个选项卡式窗口,有两个选项卡,一个有一个按钮,可以计算一个整数,另一个有一个文本字段,显示所述整数的内容。至少这是计划

如果我把所有的东西都塞进一节课,一切都会很好。我可以从actionlistener访问tab 1,并从tab 2中的按键更改tab 1中的文本字段。但很明显,我不想把我的整个课程都放在一节课上

在这里,我不知道该做什么:我需要告诉类Tab1中的textfield在类Tab2中的按钮上进行更改。在这里应该做什么?我的第一个想法是在创建Tab2时移交一个Tab1实例,这样我就可以执行Tab1.changeText()。但一旦我有了更多的相互作用的标签,这会很快变得一团糟。因此,我想在每次打开第一个选项卡时更新它的内容,但我不知道如何做到这一点。我也不知道这样做是否正确。所以,救命啊

这里有一些代码。“content”是content的一个实例,一个处理所有逻辑的类,就像添加到计数器一样

主要GUI类:

public class GUI extends JFrame {

  //Stuff..

  JTabbedPane tabs = new JTabbedPane();
  tabs.addTab("One", new Tab1(content));
  tabs.addTab("Two", new Tab2(content));

  //Stuff..
表1:

public class Tab1 extends JPanel {

  public Tab1(Content content) {
    JPanel tab1 = new JPanel();
    //Stuff..
    JTextField tfCount = new JTextField(content.getCounter(), 10);
    tab1.add(tfCount);

    this.add(tab1);

    //Stuff..
表2:

public class Tab2 extends JPanel {

  public Tab2(Content content) {
    JPanel tab2 = new JPanel();
    //Stuff..

    JButton btnCount2 = new JButton("Count");
    btnCount2.addActionListener(new TestListener(this.content));

    tab2.add(btnCount2);
    this.add(tab2);
  }

  private class TestListener implements ActionListener {

    Content content;

    public TestListener(Content content) {
        this.content = content;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        this.content.addToCounter(1);
    }
}

现在,如果所有这些都在一个类(加上子类)中,我可以从Tab2访问tfCount并执行tfCount.setText(content.getCounter());。不过,现在tfCount在另一个类中,我无法访问它,除非我将Tab1的实例交给Tab2(比如tabs.addTab(“两个”,新Tab2(content,Tab1);))。难道我不能让Tab1在每次打开时都重新绘制它自己,比如有一个执行tfCount.setText(content.getCounter())的方法吗在Tab1中,每当它被打开时,或者沿着这些线打开?如果是这样,我该怎么做?

当控件以这种方式分开时,您有一个视图选项

你可以。。。 与每个其他选项卡共享每个“选项卡”的实例,允许它们访问其他控件或相互连接侦听器。这是非常紧密耦合和混乱的

另一个问题是,按钮是否真的关心文本字段,或者反之亦然

你可以。。。 创建一个包含当前
int
值的简单模型,并提供更改该值的方法

当值发生更改时,模型将能够触发
更改事件
(例如),相关方可以监听并相应地更新自己

这将解耦代码,降低复杂性,并大大提高代码中各种元素的灵活性和重用性

这通常被称为观察者模式,在Swing中广泛使用

一个可能的(侦听器)示例。。。 对我来说,我总是从一个界面开始,它描述了为了达到所需目标必须满足的绝对最低要求。每个选项卡都希望知道当前值,能够设置下一个值,并侦听模型的更改

public interface NumberModel {
    public int getValue();
    public void setValue(int value);

    public void addChangeListener(ChangeListener listener);
    public void removeChangeListener(ChangeListener listener);
}
一个
抽象
实现处理更“常见”的实现细节,具体实现不希望实现的东西,因为它对所有实现都很常见。在这种情况下,侦听器管理

public abstract class AbstractNumberModel implements NumberModel {

    private List<ChangeListener> listeners;

    public AbstractNumberModel() {
        listeners = new ArrayList<>(25);
    }

    @Override
    public void addChangeListener(ChangeListener listener) {
        listeners.add(listener);
    }

    @Override
    public void removeChangeListener(ChangeListener listener) {
        listeners.remove(listener);
    }

    protected ChangeListener[] getChangeListeners() {
        // FIFO...
        List<ChangeListener> copy = new ArrayList<>(listeners);
        Collections.reverse(copy);
        return copy.toArray(copy.toArray(new ChangeListener[listeners.size()]));
    }

    protected void fireStateChanged() {
        ChangeListener[] listeners = getChangeListeners();
        if (listeners != null && listeners.length > 0) {
            ChangeEvent evt = new ChangeEvent(this);
            for (ChangeListener listener : listeners) {
                listener.stateChanged(evt);
            }
        }
    }
}
我们可以做一些像
public interface NumberModel
这样的事情,使我们的模型更灵活一些,例如,它允许您定义可以容纳
Integer
Double
Float
Long
的模型,但我将把这些留给您


每个选项卡视图都需要一个
setModel(NumberModel)
方法,以便将模型传递给它。在这些方法中,您将向模型附加一个侦听器,并
获取当前值,以便模型和视图同步。

使用以这种方式分离的控件,您可以选择视图

你可以。。。 与每个其他选项卡共享每个“选项卡”的实例,允许它们访问其他控件或相互连接侦听器。这是非常紧密耦合和混乱的

另一个问题是,按钮是否真的关心文本字段,或者反之亦然

你可以。。。 创建一个包含当前
int
值的简单模型,并提供更改该值的方法

当值发生更改时,模型将能够触发
更改事件
(例如),相关方可以监听并相应地更新自己

这将解耦代码,降低复杂性,并大大提高代码中各种元素的灵活性和重用性

这通常被称为观察者模式,在Swing中广泛使用

一个可能的(侦听器)示例。。。 对我来说,我总是从一个界面开始,它描述了为了达到所需目标必须满足的绝对最低要求。每个选项卡都希望知道当前值,能够设置下一个值,并侦听模型的更改

public interface NumberModel {
    public int getValue();
    public void setValue(int value);

    public void addChangeListener(ChangeListener listener);
    public void removeChangeListener(ChangeListener listener);
}
一个
抽象
实现处理更“常见”的实现细节,具体实现不希望实现的东西,因为它对所有实现都很常见。在这种情况下,侦听器管理

public abstract class AbstractNumberModel implements NumberModel {

    private List<ChangeListener> listeners;

    public AbstractNumberModel() {
        listeners = new ArrayList<>(25);
    }

    @Override
    public void addChangeListener(ChangeListener listener) {
        listeners.add(listener);
    }

    @Override
    public void removeChangeListener(ChangeListener listener) {
        listeners.remove(listener);
    }

    protected ChangeListener[] getChangeListeners() {
        // FIFO...
        List<ChangeListener> copy = new ArrayList<>(listeners);
        Collections.reverse(copy);
        return copy.toArray(copy.toArray(new ChangeListener[listeners.size()]));
    }

    protected void fireStateChanged() {
        ChangeListener[] listeners = getChangeListeners();
        if (listeners != null && listeners.length > 0) {
            ChangeEvent evt = new ChangeEvent(this);
            for (ChangeListener listener : listeners) {
                listener.stateChanged(evt);
            }
        }
    }
}
我们可以做一些像
public interface NumberModel
这样的事情,使我们的模型更灵活一些,例如,它允许您定义可以容纳
Integer
Double
Float
Long
的模型,但我将把这些留给您


每个选项卡视图都需要一个
setModel(NumberModel)
方法,以便将模型传递给它。在这些方法中,您将向模型附加一个侦听器,并
get
当前值,以便模型和视图同步。

您想过使用
Getters
Setters