gpt4 book ai didi

Java 观察者/Observable 更新

转载 作者:行者123 更新时间:2023-11-30 06:50:35 25 4
gpt4 key购买 nike

我尝试应用 Observable/Observer 模式,但当我尝试更改 JTextPane 的文本字段时,我的代码出现问题。

我有 3 个类,PlayControllerSecondWindow 这里是它们的代码示例。

public class Play() {
Controller c = new Controller();
SecondWindow sw = new SecondWindow();
c.addObserver(sw)

c.setText("blabla");
}

我的类 Controller :

public class Controller extends Observable(){

private String text ="";

private static Controller getInstance() {
if (instance == null) {
instance = new Controller();
}
return instance;
}

public void setText(String s) {
text = s;
setChanged();
notifyObservers();
}
}

第二窗口:

public class SecondWindow extends JFrame implements Observer{
private JPanel contentPane;
private Controller c;
private JTextPane txt = new JTextPane();

public SecondWindow () {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SecondWindow frame = new SecondWindow();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

public SecondWindow() {
initComponents();
createEvents();
c = Controller.getInstance();
}

public void initComponents() {

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(1000, 0, 300,500);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);

txt.setBounds(0, 0, 280, 460);
txt.enable(false);
contentPane.add(txt);
}

public void update(Observable arg0 , Object arg1){
// Things to change here
}

我无法将变量 c 放入文本字​​段(如 txt.setText(c.getText) 指令)。我确信它会读取方法更新,但我不知道如何确保它有效。

最佳答案

提示:根据Observerable API notifyObservers 方法有一个重载,它接受任何对象作为参数:

public void notifyObservers(Object arg)

这甚至可以是一个字符串。并根据 Observer API ,然后将该对象传递到观察者中的 update 方法中,您可以在那里使用它。

void update(Observable o,
Object arg)

arg - an argument passed to the notifyObservers method.


这里有一个单独的问题:

contentPane.setLayout(null);

对于大多数 Swing 爱好者来说,看到这一点就像听到黑板上的钉子声一样——这是痛苦的。虽然 null 布局和 setBounds() 对于 Swing 新手来说似乎是创建复杂 GUI 的最简单、最好的方法,但创建的 Swing GUI 越多,使用它们时遇到的困难就越严重。当 GUI 调整大小时,它们不会调整组件的大小,它们是增强或维护的皇家女巫,当放置在滚动 Pane 中时,它们会完全失败,在所有平台或与原始分辨率不同的屏幕分辨率上查看时,它们看起来非常糟糕。相反,您需要研究和学习布局管理器,然后嵌套 JPanel,每个 JPanel 使用自己的布局管理器来创建在所有操作系统上看起来都不错的令人愉悦且复杂的 GUI。


第二个问题:您的代码不是 Swing 线程安全的,因为 Swing GUI 很可能通过 Swing 事件调度线程或 EDT 的可观察off 得到通知。虽然这个简单的程序不太可能导致频繁或严重的问题,但一般来说,如果可以的话,最好使用 SwingPropertyChangeSupport 和 PropertyChangeListeners 而不是 Observer/Observable。


下一个附带问题
这:

public class Controller extends Observable(){

不可编译/符合 Java 标准。 SecondWindow 类的重复无参数构造函数也是如此。是的,我们知道您想要做什么,但是尝试理解别人的代码已经够困难的了,您真的不想通过发布某种不可编译的代码来让它变得更难,相信我。


例如,可以使用 PropertyChangeListener 在 Swing 中实现一些简单的操作,如下所示:

import java.util.concurrent.TimeUnit;

public class Play2 {
public static void main(String[] args) {
Model2 model2 = new Model2();
View2 view2 = new View2();
new Controller2(model2, view2);
view2.show();
for (int i = 0; i < 10; i++) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// one of the few times it's OK to ignore an exception
}
String text = String.format("Counter Value: %d", i);
model2.setText(text);
}
}
}

import java.beans.PropertyChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;

public class Model2 {
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
public static final String TEXT = "text"; // name of our "bound" property
private String text = "";

public String getText() {
return text;
}

public void setText(String text) {
String oldValue = this.text;
String newValue = text;
this.text = text;
pcSupport.firePropertyChange(TEXT, oldValue, newValue);
}

public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}

public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}

public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(name, listener);
}

public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(name, listener);
}
}

import javax.swing.*;

public class View2 {
private JPanel mainPanel = new JPanel();
private JTextField textField = new JTextField(10);

public View2() {
textField.setFocusable(false);
mainPanel.add(new JLabel("Text:"));
mainPanel.add(textField);
}

public JPanel getMainPanel() {
return mainPanel;
}

public void setText(String text) {
textField.setText(text);
}

public void show() {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("View");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

public class Controller2 {
private Model2 model2;
private View2 view2;

public Controller2(Model2 model2, View2 view2) {
this.model2 = model2;
this.view2 = view2;
model2.addPropertyChangeListener(Model2.TEXT, new ModelListener());
}

private class ModelListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent pcEvt) {
view2.setText((String) pcEvt.getNewValue());
}
}
}

关于Java 观察者/Observable 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41251875/

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