Java 刷新选项卡开关上的JPanel内容
我正在编写一个简单的UI,只是为了掌握一些窍门。我有一个选项卡式窗口,有两个选项卡,一个有一个按钮,可以计算一个整数,另一个有一个文本字段,显示所述整数的内容。至少这是计划 如果我把所有的东西都塞进一节课,一切都会很好。我可以从actionlistener访问tab 1,并从tab 2中的按键更改tab 1中的文本字段。但很明显,我不想把我的整个课程都放在一节课上 在这里,我不知道该做什么:我需要告诉类Tab1中的textfield在类Tab2中的按钮上进行更改。在这里应该做什么?我的第一个想法是在创建Tab2时移交一个Tab1实例,这样我就可以执行Tab1.changeText()。但一旦我有了更多的相互作用的标签,这会很快变得一团糟。因此,我想在每次打开第一个选项卡时更新它的内容,但我不知道如何做到这一点。我也不知道这样做是否正确。所以,救命啊 这里有一些代码。“content”是content的一个实例,一个处理所有逻辑的类,就像添加到计数器一样 主要GUI类:Java 刷新选项卡开关上的JPanel内容,java,swing,jpanel,jtabbedpane,Java,Swing,Jpanel,Jtabbedpane,我正在编写一个简单的UI,只是为了掌握一些窍门。我有一个选项卡式窗口,有两个选项卡,一个有一个按钮,可以计算一个整数,另一个有一个文本字段,显示所述整数的内容。至少这是计划 如果我把所有的东西都塞进一节课,一切都会很好。我可以从actionlistener访问tab 1,并从tab 2中的按键更改tab 1中的文本字段。但很明显,我不想把我的整个课程都放在一节课上 在这里,我不知道该做什么:我需要告诉类Tab1中的textfield在类Tab2中的按钮上进行更改。在这里应该做什么?我的第一个想法
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
吗