SwingPropertyChangeSupport在从文件中读取后刷新GUI

问题描述:

从我昨晚的问题开始:SwingPropertyChangeSupport to dynamically update JTextArea,我正在尝试在阅读文本文件后刷新GUI。SwingPropertyChangeSupport在从文件中读取后刷新GUI

我有一个数组,其中包含两位数的整数。我可以通过在文本区域输入一串数字来动态更新它,然后选择要修改的索引。该字符串被分成两位数字并依次添加。输入字符串并单击按钮后,此方法称为:

public void modifyArray() { 

    // show dialog to retrieve entered address 
    addressToModify = (String) JOptionPane 
      .showInputDialog("At which location?"); 

    // convert to integer if decimal address entered 
    memAddress = Integer.parseInt(addressToModify); 
    arrayForUpdate.instructionsIn(codeIn.getText(), memAddress); 
} 

此部分代码现在按预期工作。也就是说,如果我输入“123456”,然后输入位置“0”(或“0000”)时,显示被更新为这样的:

Index  0000 Value: 12 
Index  0001 Value: 34 
Index  0002 Value: 56 
Index  0003 Value: 00 

我也有含有由一个字符串的文本文件四位数字提供数组索引,然后是一系列两位数值添加到数组中。我可以通过gui按钮/文件选择器加载。示例文件的内容是:

000

我有以下的方法来处理该文件:

public void readRecord(File fileName) { 

    // create file reader 
    try { 
     FileReader reader = null; 
     try { 
      // open input file 
      reader = new FileReader(fileName); 

      // create scanner to read from file reader 
      Scanner in = new Scanner(reader); 

      // read each line and remove whitespace 
      while (in.hasNextLine()) { 
       String line = in.nextLine().trim(); 
       parseRecord(line); 
      } 

     } finally { 
      // close reader assuming it was successfully opened 
      if (reader != null) 
       reader.close(); 
     } 
     } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 

public void parseRecord(String record) { 

    // create address substring from start, 4 long 
    String addrString = record.substring(0, 3); 
    int s1Address = Integer.parseInt(addrString); 

    // create binary data substring (4 from start, up to end) 
    String dataString = record.substring(4, record.length()); 

    // pass data string as parameter to InstructionsIn method 
    arrayForUpdate.instructionsIn(dataString, s1Address); 
} 

在上述两种情形中,“instructionsIn”方法被调用。在第一种情况下,这会导致显示屏被更新,但在第二种情况下它不会显示,我不知道为什么。我希望有人能够发现我错过的东西。

下面是代码的完整,简化的版本,运行:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.FocusListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.Scanner; 

import javax.swing.JButton; 
import javax.swing.JFileChooser; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 
import javax.swing.event.SwingPropertyChangeSupport; 

public class PropertyChangeExample extends JFrame implements ActionListener { 

private static final long serialVersionUID = 1L; 
private String addressToModify, mList; 
private int memAddress; 
private JTextArea codeIn, displayOutput; 
private S_Record sRec; 
private JButton loadButton, modifyArrayButton; 
private FocusListener focusListener; 
private JPanel displayPanel; 
private ArrayForUpdate arrayForUpdate = new ArrayForUpdate(); 

public static void main(String[] arg) { 
    PropertyChangeExample display = new PropertyChangeExample(); 
    display.setVisible(true); 
} 

public PropertyChangeExample() { 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setSize(450, 170); 
    layoutLeft(); 
    layoutDisplay(); 
    layoutBottom(); 
} 

public void layoutDisplay() { 
    displayPanel = new JPanel(); 
    add(displayPanel, BorderLayout.CENTER); 
    displayOutput = new JTextArea(32, 38); 
    displayPanel.add(displayOutput); 
    displayOutput.addFocusListener(focusListener); 

    mList = arrayForUpdate.getBoundProperty(); 
    displayOutput.setText(mList); 

    arrayForUpdate.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent pcEvt) { 
      if (pcEvt.getPropertyName().equals(
        ArrayForUpdate.BOUND_PROPERTY)) { 
       mList = (pcEvt.getNewValue().toString()); 
       displayOutput.setText(mList); 
      } 
     } 
    }); 
} 

public void layoutLeft() { 
    JPanel left = new JPanel(); 
    add(left, BorderLayout.WEST); 
    codeIn = new JTextArea(10, 7); 
    left.add(codeIn, BorderLayout.NORTH); 
    codeIn.addFocusListener(focusListener); 
} 

public void layoutBottom() { 
    JPanel bottom = new JPanel(); 
    bottom.setBackground(Color.LIGHT_GRAY); 
    loadButton = new JButton("Load file"); 
    loadButton.addActionListener(this); 
    bottom.add(loadButton); 
    add(bottom, BorderLayout.SOUTH); 
    modifyArrayButton = new JButton("Add value to array"); 
    modifyArrayButton.addActionListener(this); 
    bottom.add(modifyArrayButton); 
} 

public void actionPerformed(ActionEvent ae) { 
    if (ae.getSource() == modifyArrayButton) { 
     modifyArray(); 
    } 

    if (ae.getSource() == loadButton) { 
     processInputFile(); 
    } 
} 

public void modifyArray() { 
    addressToModify = (String) JOptionPane 
      .showInputDialog("At which location?"); 

    // convert to integer if decimal address entered 
    memAddress = Integer.parseInt(addressToModify); 
    arrayForUpdate.instructionsIn(codeIn.getText(), memAddress); 
} 

public void processInputFile() { 

    sRec = new S_Record(); 
    JFileChooser chooser = new JFileChooser(); 
    int returnVal = chooser.showOpenDialog(getParent()); 
    if (returnVal == JFileChooser.APPROVE_OPTION) { 
     // create the file 
     File file = chooser.getSelectedFile(); 

     // pass to readRecord method in S_Record class 
     sRec.readRecord(file); 
    } 
} 
} 

class S_Record { 

private ArrayForUpdate arrayForUpdate = new ArrayForUpdate(); 

public void readRecord(File fileName) { 

    // create file reader 
    try { 
     FileReader reader = null; 
     try { 
      // open input file 
      reader = new FileReader(fileName); 

      // create scanner to read from file reader 
      Scanner in = new Scanner(reader); 

      // read each line and remove whitespace 
      while (in.hasNextLine()) { 
       String line = in.nextLine().trim(); 
       parseRecord(line); 
      } 
     } finally { 
      // close reader assuming it was successfully opened 
      if (reader != null) 
       reader.close(); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

public void parseRecord(String record) { 

    // create address substring from start, 4 long 
    String addrString = record.substring(0, 3); 

    int s1Address = Integer.parseInt(addrString); 

    // create binary data substring (4 from start, up to end) 
    String dataString = record.substring(4, record.length()); 

    // pass data string as parameter to InstructionsIn method 
    arrayForUpdate.instructionsIn(dataString, s1Address); 
} 
} 

class ArrayForUpdate { 

public static final String BOUND_PROPERTY = "bound property"; 
private String boundProperty = ""; 
private SwingPropertyChangeSupport spcSupport = new SwingPropertyChangeSupport(
     this); 
private int[] myArray; 
private final int MEM_LOCATIONS = 6; 
/** StringBuilder object for displaying memory */ 
private StringBuilder mList; 

public ArrayForUpdate() { 

    myArray = new int[MEM_LOCATIONS]; 
    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 %04x %10s %02x", "Index: ", 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 len = code.length(); 
    int chunkLength = 2; // the length of each chunk of code 
    int i = 0; 

    // traverse entered code and split into 2 digit chunks 
    for (i = 0; i < len; i += chunkLength) { 

     String chunk = code.substring(i, Math.min(len, i + chunkLength)); 
     int oc = Integer.parseInt(chunk, 16); 

     // 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; 
    setArrayyDisplayString(); 
} 

public String getBoundProperty() { 
    return boundProperty; 
} 

/** 
* Method to implement changes to array for display 
* 
* @param boundProperty - the String representing the memory array 
*/ 
public void setBoundProperty(String boundProperty) { 
    String oldValue = this.boundProperty; 
    String newValue = boundProperty; 
    this.boundProperty = newValue; 
    spcSupport.firePropertyChange(BOUND_PROPERTY, oldValue, newValue); 
} 

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

这看起来是引用的问题。

您似乎至少有两个ArrayForUpdate对象,一个由GUI监听的对象,另一个完全不同的实例位于S_Record类的内部。后者是从文件中获取信息的那个,而前一个,GUI正在收听的不是。解决方案:确保在两个地方只使用一个ArrayForUpdate对象。也许你可以通过它的构造函数将GUI实例的引用传递给你的S_Record对象?

+0

非常感谢。这看起来很有效。先生,你们的帮助最近几周得到了很多赞赏! – Robert 2012-08-08 21:40:22

+1

@Robert:不客气。现在不要忘记在后台线程中完成文件读取业务。 – 2012-08-08 21:40:58

+0

道歉,我很新的编程,我不知道你的意思是由后台线程? – Robert 2012-08-08 21:48:05