Bits of Java (トップ)

目次  前へ  次へ

Swing コンポーネントを保存する (その1)

Swing のコンポーネントを XML に保存する場合にはいくつか注意しなければならない点があります。 コンテナのコンストラクタ内で add されたコンポーネントは XML には書き出されません。 例えば JFrame のサブクラスを作成し、そのデフォルトコンストラクタ内でテキストフィールドを貼り付けた場合には XML への保存時にはそのテキストフィールドは保存されません。 よってテキストフィールドに入力されていた値も失われることになります。

下の SampleFrame を実行するとテキストフィールドとボタンを備えたフレームが表示されます。 ボタンを押すとフレームを XMLEncoder を使って frame.xml に保存します。 FrameDecoder を実行すると frame.xml からフレームを復元して表示します。 このページの一番下の frame.xml の内容はテキストフィールドに aaa を入力してからボタンを押した場合に出力される XML の内容です。

SampleFrame はテキストフィールドに入力された文字列も XML に保存されていますが、これは getTextFieldText メソッド、setTextFieldText メソッドによる textFieldText というプロパティの存在によるものです。 逆にこの getTextFieldText メソッド、setTextFieldText メソッドを定義していなければテキストフィールドの入力値は失われることになります。 一般にコンストラクタで貼り付けたコンポーネントの内部状態を XML に保存するためには、その内部状態をプロパティとする getter メソッドと setter メソッドを定義しなければなりません。

/******************** SampleFrame.java ********************/
import java.awt.*;
import java.awt.event.*;
import java.beans.XMLEncoder;
import java.io.*;
import javax.swing.*;

public class SampleFrame extends JFrame {

    JTextField textField = new JTextField(20);

    public SampleFrame() {
        super("XMLEncoder Test");
        JButton xmlEncodeButton = new JButton("XMLEncode");
        xmlEncodeButton.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    xmlEncode();
                }
            }
        );
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel1 = new JPanel();
        panel1.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.insets.top= 5;
        c.insets.left = 5;
        c.insets.bottom = 5;
        c.insets.right = 5;
        panel1.add(new JLabel("text : "), c);

        c.gridx++;
        c.weightx = 0.1;
        panel1.add(textField, c);
        c.gridy = 1;
        c.gridx = 1;
        c.anchor = GridBagConstraints.EAST;
        panel1.add(xmlEncodeButton, c);

        getContentPane().add(panel1);
        pack();
    }

    public String getTextFieldText() {
        return textField.getText();
    }
    public void setTextFieldText(String text) {
        textField.setText(text);
    }

    private void xmlEncode() {
        XMLEncoder encoder = null;
        try {
            encoder = new XMLEncoder(new BufferedOutputStream(
                                         new FileOutputStream("frame.xml")));
            encoder.writeObject(this);
            JOptionPane.showMessageDialog(this, "frame.xmlを出力しました。");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (encoder != null) {
                encoder.close();
            }
        }
    }

    public static void main(String[] args) {
        new SampleFrame().setVisible(true);
    }
}


/******************** FrameDecoder.java ********************/
import java.beans.XMLDecoder;
import javax.swing.JFrame;
import java.io.*;

public class FrameDecoder {
    public static void main(String[] args) throws Exception {
        XMLDecoder decoder = null;
        try {
            decoder = new XMLDecoder(new BufferedInputStream(
                                         new FileInputStream("frame.xml")));
            JFrame frame = (JFrame)decoder.readObject();
            frame.setVisible(true);
        } finally {
            if (decoder != null) {
                decoder.close();
            }
        }
    }
}

/******************** frame.xml ********************/
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_01" class="java.beans.XMLDecoder">
 <object class="SampleFrame">
  <void property="visible">
   <boolean>true</boolean>
  </void>
  <void property="name">
   <string>frame0</string>
  </void>
  <void property="textFieldText">
   <string>aaa</string>
  </void>
 </object>
</java>