Swing PropertyChangeSupport 动态更新 JTextArea
Posted
技术标签:
【中文标题】Swing PropertyChangeSupport 动态更新 JTextArea【英文标题】:SwingPropertyChangeSupport to dynamically update JTextArea 【发布时间】:2012-08-03 08:49:30 【问题描述】:我正在尝试建立关于 SwingPropertyChangeSupport 问题的答案
我正在尝试修改此处给出的代码,这是非常有用的 Hovercraft Full Of Eels 的回答: WindowListener does not work as expected,允许在通过输入对话框输入更改时更新显示的数组。
阵列更新正常,但未在 GUI 中刷新。我希望有人能告诉我哪里出错了。
代码如下:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.event.SwingPropertyChangeSupport;
public class Main
public static void main(String[] arg)
GuiForUpdate display = new GuiForUpdate();
display.setVisible(true);
class GuiForUpdate extends JFrame implements ActionListener
/**
*
*/
private static final long serialVersionUID = 1L;
private FocusListener focusListener;
private String mList;
private JButton changeArrayButton;
private JTextArea codeIn, displayOutput;
private int arrayIndex;
private JPanel displayPanel;
private ArrayForUpdating arrayForUpdate = new ArrayForUpdating();
public GuiForUpdate()
setSize(224, 180);
layoutLeft();
layoutDisplay();
layoutBottom();
/**
* adds a display area for array
*/
public void layoutDisplay()
displayPanel = new JPanel();
add(displayPanel, BorderLayout.CENTER);
displayOutput = new JTextArea();
displayPanel.add(displayOutput);
displayOutput.addFocusListener(focusListener);
mList = arrayForUpdate.getBoundProperty();
arrayForUpdate.addPropertyChangeListener(new PropertyChangeListener()
@Override
public void propertyChange(PropertyChangeEvent pcEvt)
if (pcEvt.getPropertyName().equals(
ArrayForUpdating.BOUND_PROPERTY))
mList = (pcEvt.getNewValue().toString());
);
displayOutput.setText(mList);
/**
* adds left hand side elements to left of GUI
*/
public void layoutLeft()
JPanel left = new JPanel();
add(left, BorderLayout.WEST);
codeIn = new JTextArea(2, 2);
left.add(codeIn);
codeIn.addFocusListener(focusListener);
/**
* adds bottom elements to bottom of GUI
*/
public void layoutBottom()
JPanel bottom = new JPanel();
changeArrayButton = new JButton("Modify array");
changeArrayButton.addActionListener(this);
bottom.add(changeArrayButton);
add(bottom, BorderLayout.SOUTH);
/**
* Process button clicks
*/
public void actionPerformed(ActionEvent ae)
if (ae.getSource() == changeArrayButton)
// first check if any code entered
if (codeIn.getText().trim().length() != 0)
// call modifyMemory() method
modifyArray();
else
JOptionPane.showMessageDialog(null,
"Please enter something first.");
/**
* method to process modify array
*/
public void modifyArray()
// show dialog to retrieve entered address
String addressToModify = (String) JOptionPane
.showInputDialog("At which location?");
// confirm if a string was entered
if ((addressToModify != null) && (addressToModify.length() > 0))
// convert to integer if decimal address entered
arrayIndex = Integer.parseInt(addressToModify);
// pass as integer
processInput(arrayIndex);
public void processInput(int a)
String newValue = codeIn.getText();
arrayForUpdate.instructionsIn(newValue, a);
class ArrayForUpdating
public static final String BOUND_PROPERTY = "bound property";
private String boundProperty = "";
private SwingPropertyChangeSupport spcSupport = new SwingPropertyChangeSupport(
this);
private StringBuilder mList;
private int[] myArray;
public ArrayForUpdating()
myArray = new int[5];
for (int i = 0; i < myArray.length; i++)
myArray[i] = 0;
setArrayyDisplayString();
/**
* method to create formatted string of array
*/
public void setArrayyDisplayString()
// create StringBuilder for display in memory tab
mList = new StringBuilder();
for (int i = 0; i < myArray.length; i++)
mList.append(String.format("%10s %02d %10s %02d", "Pos: ", i,
"Value: ", myArray[i]));
mList.append("\n");
setBoundProperty(mList.toString());
/**
* This method takes in a string passed through from the GUI
*/
public void instructionsIn(String codeIn, int loc)
String code = codeIn.trim();
int oc = Integer.parseInt(code);
// add the data to the array
setArrayData(loc, oc);
loc++;
/**
* method to add data to the array
*/
public void setArrayData(int a, int memData)
myArray[a] = memData;
// print array to console for checking
for (int i = 0; i < myArray.length; i++)
System.out.println("location: " + i + " value: " + myArray[i]);
setArrayyDisplayString();
public SwingPropertyChangeSupport getSpcSupport()
return spcSupport;
public void setSpcSupport(SwingPropertyChangeSupport spcSupport)
this.spcSupport = spcSupport;
public String getBoundProperty()
return boundProperty;
public void setBoundProperty(String boundProperty)
String oldValue = this.boundProperty;
System.out.println("old = " + oldValue);
String newValue = boundProperty;
System.out.println("new = " + newValue);
this.boundProperty = newValue;
spcSupport.firePropertyChange(BOUND_PROPERTY, oldValue, newValue);
public void addPropertyChangeListener(PropertyChangeListener listener)
spcSupport.addPropertyChangeListener(listener);
-编辑- 希望消除编译错误。
【问题讨论】:
请编辑您的问题以包含一个 sscce 来展示您描述的问题。有相关的例子here和here。 抱歉,我已尝试对其进行编辑以使其更简单。 没问题,但是如果你的例子是完整的,你会得到更好的结果,就像引用的那样。 我刚刚添加了 Main 类,这就是现在的全部内容。 您的代码充满了编译错误,因此很难为您提供帮助。考虑重构您的代码,使其符合 [sscce](http//sscce.org) 规范,并且请仅发布经过测试的有效代码。 【参考方案1】:代码看起来或多或少是正确的(即我找不到任何明显的错误)。您应该尝试在调试器中运行它,并在调试代码时遇到问题时提出一个新问题。
【讨论】:
我试过了,在“propertyChange”方法处设置了一个断点,但它似乎从未被调用过。不知道为什么,但谢谢。 在setBoundProperty
中的firePropertyChange
上设置断点并单步执行其背后的代码。
嗯。该数组似乎没有在该方法中更新。还不知道为什么。谢谢。
如果属性的新旧值相等,则不会触发任何事件。
对不起,我的错误。新旧似乎确实不同。【参考方案2】:
这是一个在无模式对话框中使用ObservedPanel
的完整示例。
public class PropertyChangeDialog extends JPanel
private JLabel label = new JLabel("null", JLabel.CENTER);
private ObservedPanel observed = new ObservedPanel();
public PropertyChangeDialog()
this.setBorder(BorderFactory.createTitledBorder("Observer"));
this.add(label);
observed.addPropertyChangeListener(new PropertyChangeListener()
@Override
public void propertyChange(PropertyChangeEvent e)
if (e.getPropertyName().equals(ObservedPanel.PHYSICIST))
String value = e.getNewValue().toString();
label.setText(value);
);
private void display()
JFrame f = new JFrame("PropertyChangeDialog");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
JDialog dialog = new JDialog(f);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.add(observed);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
public static void main(String[] args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
new PropertyChangeDialog().display();
);
【讨论】:
谢谢,请原谅我的无知,但什么是“ObservedPanel”?我的 IDE 抱怨它无法解析为类型。 对,这是指向另一个 SO 答案的链接。 现在知道了,谢谢。我仍然没有更清楚,但会继续修补。 @Robert 我推断您正在使用 netbeans GUI 构建器,又名 matisse?如果是这样,那么“ObservedPanel”只是 JPanel 的扩展。请注意,PropertyChangeDialog extends JPanel
这正是 Netbeans 做事的方式。这允许您在设计视图中将这些类复制/粘贴到彼此中。编译完这些类后,切换到设计视图并复制您想要的类,粘贴到您想要的位置。
@Thufir:PropertyChangeDialog
和 ObservedPanel
都不使用 Matisse GUI 编辑器。对不起,如果我错过了什么。【参考方案3】:
当我将displayOutput.setText(mList)
放在propertyChange
方法中时,它起作用了:
@Override
public void propertyChange(PropertyChangeEvent pcEvt)
if (pcEvt.getPropertyName().equals(
ArrayForUpdating.BOUND_PROPERTY))
mList = (pcEvt.getNewValue().toString());
displayOutput.setText(mList);
感谢大家的帮助,尤其是您的耐心。
【讨论】:
以上是关于Swing PropertyChangeSupport 动态更新 JTextArea的主要内容,如果未能解决你的问题,请参考以下文章