2

昨夜の私の質問: SwingPropertyChangeSupport to dynamic update JTextAreaに続いて、テキスト ファイルを読み込んだ後に GUI を更新しようとしています。

2 桁の整数を保持する配列があります。テキスト領域に数字の文字列を入力し、変更するインデックスを選択することで、動的に更新できます。文字列は 2 桁の部分に分割され、順番に追加されます。文字列を入力してボタンをクリックすると、次のメソッドが呼び出されます。

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

また、配列インデックスを提供する 4 桁の文字列と、その後に配列に追加される一連の 2 桁の値を含む文字列を含むテキスト ファイルもあります。GUIボタン/ファイルチューザーを介してこれをロードできます。サンプル ファイルの内容は次のとおりです。

0000123456

ファイルを処理するには、次の方法があります。

    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" メソッドが呼び出されます。最初のシナリオでは表示が更新されますが、2 番目のシナリオでは更新されず、その理由がわかりません。誰かが私が見逃しているものを見つけてくれることを願っていました。

実行されるコードの完全で簡略化されたバージョンを次に示します。

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);
 }
}
4

1 に答える 1

3

これは参照の問題のようです。

少なくとも2つのArrayForUpdateオブジェクトがあるように見えます。1つはGUIによってリッスンされ、もう1つはS_Recordクラス内に保持されている完全に別個のインスタンスです。後者はファイルから情報を取得しているものですが、前者はGUIによってリッスンされているものではありません。解決策:両方の場所で使用されるArrayForUpdateオブジェクトが1つだけであることを確認してください。おそらく、コンストラクターを介してGUIのインスタンスの参照をS_Recordオブジェクトに渡すことができますか?

于 2012-08-08T21:33:59.930 に答える