どのように私はJavaFXのツリービューとツリー項目、シリアライズを作るのですか?

papert1ger:

ObjectOutputStreamの使用して、私のツリービューを保存しようとすると:(javafx.scene.control.TreeView java.io.NotSerializableException)私はこのエラーを得ています。

私はSerializableを実装していない直列化および1つのメインクラスを実装する2つのクラスがあります。

2クラスは、ベンダーと住所です。ベンダークラスは、4つの変数(名前、年齢、性別、住所のクラス型のアドレス)、すべての変数を設定するには、setメソッドを使用して、コンストラクタ、のための唯一の名前の変数を設定し、取得するためにsetメソッドを使用して、コンストラクタ/セット方法が含まれています変数。

Addressクラスは、変数を設定し、取得するためにsetメソッドを使用して2つの変数(通りの名前と郵便番号)、デフォルトコンストラクタ/変数の設定方法が含まれています。

これは私のメインクラスです

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class SimpleTreeView extends Application {

  private TreeView<Vendor> treeView;

  public void start(Stage stage) {
    stage.setTitle("Simple TreeView");

    treeView = new TreeView<>();
    TreeItem<Vendor> root = new TreeItem<>(new Vendor("Root"));
    root.setExpanded(true);
    treeView.setRoot(root);
    treeView.setShowRoot(false);
    TreeItem<Vendor> start = new TreeItem<>(new Vendor("Start"));
    root.getChildren().add(start);

    Button saveButton = new Button("Save");
    saveButton.setOnMouseClicked(event -> saveTreeView(stage));

    VBox vBox = new VBox(20);
    vBox.getChildren().addAll(treeView, saveButton);

    stage.setScene(new Scene(vBox));

    stage.show();
  }

  private void saveTreeView(Stage stage) {
    FileChooser fileChooser = new FileChooser();
    fileChooser.setTitle("Save");
    File file = fileChooser.showSaveDialog(stage);

    if (file != null) {
      try {
        ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file));
        os.writeObject(treeView);
        os.close();
      }
      catch (Exception e) {
        System.out.println(e);
      }
    }
  }

  public static void main(String[] args) {
    launch(args);
  }

}
ファビアン:

ノードは、復元するには複雑すぎるだろうあまりにも多くの内部状態がある(おそらくあなたはyouselfを実装するカスタムのものを除く)シリアライズすることはできません。(それらを拡張することなく)ノードにメソッド/インターフェースを追加する可能性について欠くことができなく追加することができるSerializableインターフェイスおよび状態を復元し、適切にこのデータを読み取るために必要とされるデータの部分を保存するためのメソッドを追加します。

もしあなたが、あなたが実際に興味を持っている特性を回復することを可能にする、シリアライズラッパークラスを作成している最高の私見では、それは、ノードをシリアル化しようとしないことが最善です。データをロードするときに、新しいノードを作成し、ロードされたデータとそれを埋めます。

あなたがこれを行うことができますどのように次の例が示しますTreeItem<? extends Serializable>そこのデータが展開プロパティなどの行方不明ですが、あなたは復元することができるはずvalue財産や子供を。(実装はもう少し複雑なために必要以上にあるTreeItem小さな深さが、あなたは単純な再帰的なアプローチはにつながる可能性があることを認識する必要があり、特定の深さを有する構造StackOverflowError秒。)

この場合、すべての項目は、子供の数、それ自身のvalueプロパティを書き込み、その後、すべての子供に同じことをやっによってシリアライズされます。このデータを復元するために使用することができますint型と値のペアのシーケンスの結果:

public class TreeItemSerialisation {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        TreeItem<String> root = new TreeItem<>("root");
        TreeItem<String> c1 = new TreeItem<>("root.1");
        TreeItem<String> c3 = new TreeItem<>("root.3");
        root.getChildren().addAll(c1, new TreeItem<>("root.2"), c3);
        TreeItem<String> c3_1 = new TreeItem<>("root.3.1");
        c3_1.getChildren().add(new TreeItem<>("root.3.1.1"));
        c3.getChildren().add(c3_1);
        c1.getChildren().addAll(new TreeItem<>("root.1.1"), new TreeItem<>("root.1.2"));

        // serialize
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {
            oos.writeObject(new TreeItemSerialisationWrapper(root));
        }

        // unserialize
        TreeItem<String> root2;
        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()))) {
            root2 = (TreeItem<String>) ois.readObject();
        }
        // TODO do something with root2
    }

}
public class TreeItemSerialisationWrapper<T extends Serializable> implements Serializable {
    private static final long serialVersionUID = 1L;

    private transient TreeItem<T> item;

    public TreeItemSerialisationWrapper(TreeItem<T> item) {
        if (item == null) {
            throw new IllegalArgumentException();
        }
        this.item = item;
    }

    /**
     * Custom way of writing the TreeItem structure
     */
    private void writeObject(ObjectOutputStream out)
             throws IOException {
        Stack<TreeItem<T>> stack = new Stack<>();
        stack.push(item);

        out.defaultWriteObject();
        do {
            TreeItem<T> current = stack.pop();

            int size = current.getChildren().size();
            out.writeInt(size);

            // write all the data that needs to be restored here
            out.writeObject(current.getValue());

            // "schedule" serialisation of children.
            // the first one is inserted last, since the top one from the stack is
            // retrieved first
            for (int i = size - 1; i >= 0; --i) {
                stack.push(current.getChildren().get(i));
            }
        } while (!stack.isEmpty());
    }

    /**
     * happens before readResolve; recreates the TreeItem structure
     */
    private void readObject(ObjectInputStream in)
             throws IOException, ClassNotFoundException {
        class Container {
            int count;
            final TreeItem<T> item;
            Container(ObjectInputStream in) throws ClassNotFoundException, IOException {
                // read the data for a single TreeItem here
                this.count = in.readInt();
                this.item = new TreeItem<>((T) in.readObject());
            }
        }
        in.defaultReadObject();
        Container root = new Container(in);
        this.item = root.item;

        if (root.count > 0) {
            Stack<Container> stack = new Stack<>();
            stack.push(root);
            do {
                Container current = stack.peek();
                --current.count;
                if (current.count <= 0) {
                    // we're done with this item
                    stack.pop();
                }

                Container newContainer = new Container(in);
                current.item.getChildren().add(newContainer.item);
                if (newContainer.count > 0) {
                    //schedule reading children of non-leaf
                    stack.push(newContainer);
                }
            } while(!stack.isEmpty());
        }
    }

    /** 
     * We're not actually interested in this object but the treeitem
     * @return the treeitem
     * @throws ObjectStreamException
     */
    private Object readResolve() throws ObjectStreamException {
        return item;
    }

}

方法についてはreadObjectreadResolvewriteObject仕事を参照のjavadocをSerializable

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=407542&siteId=1