【问题标题】:Serialize JavaFX components序列化 JavaFX 组件
【发布时间】:2012-06-17 12:51:57
【问题描述】:

我正在尝试在 Java FX 下开发一个小的拖放应用程序。用户将在某些位置放置 JFX 组件,如按钮、菜单、标签。完成后,他将保存此布局,稍后他将重新打开布局并再次使用它。

存储有关在某个位置放置的所有对象的信息很重要。

我决定为此使用序列化。但我无法序列化 JavaFX 组件。我尝试序列化按钮、场景、舞台、JFXPane,但似乎没有任何效果(我获得了 NotSerializableException)。

任何建议如何保存所有组件然后检索它们?

P.S.:我试图用 FXML 找出一些方法,但没有成功。

非常感谢您的回答:)

【问题讨论】:

    标签: java serialization user-interface javafx


    【解决方案1】:

    您是对的,JavaFX(从 2.1 开始)不支持使用 Java Serializable 接口对组件进行序列化 - 因此您不能使用该机制。

    JavaFX 可以使用 FXMLLoader.load() 方法从 FXML 文档反序列化。

    不过,诀窍是如何将现有组件和状态写入 FXML?

    目前,执行 FXML 序列化的平台没有任何公开内容。显然,创建通用场景图 => FXML 序列化程序是一项相当复杂的任务(据我所知,没有公开的第 3 方 API)。迭代场景图并为一组有限的组件和属性写出 FXML 并不难。

    【讨论】:

    • 还有同事在这里发帖。有一种解决方案可以创建我可以序列化的对象。另一方面,要从我的代码中创建 FXML。在我的项目中,创建 FXML 的复杂性可能会更高一些,但是使用为具体组件标识注释 @FXML 来恢复整个场景要容易得多。由于我必须快速开发它,我将使用他的解决方案。但我也会用 FXML 创建来研究这个。因为我认为它对其他人来说更自动。
    • 你有没有看到一些计划将这个特性(直接从源代码从组件创建 FXML)集成到 JavaFX 的标准库中?
    • 不,我认为不太可能将这样的功能添加到 JavaFX 标准库中。
    • 嗯,很可惜,因为它可以节省很多额外的工作。但也许一段时间后,有人 (:D) 会开发一个额外的库来处理这个问题。 :)
    • 最后我选择将布局保存到 FXML 文件中。在我进行更深入的分析之后,它看起来更容易了。
    【解决方案2】:

    如果在服务器端保存用户组件的主要目标 - 是有可能向用户显示相同的界面 - 为什么不保存您需要的关于用户组件的所有描述性信息,以及何时需要 - 只是使用存储的描述信息再次重建用户界面?这是原始示例:

    /* That is the class for storing information, which you need from your components*/
     public class DropedComponentsCoordinates implements Serializable{
    private String componentID;
    private String x_coord;
    private String y_coord;
    //and so on, whatever you need to get from yor serializable objects;
    //getters and setters are assumed but not typed here.
     }
    
     /* I assume a variant with using FXML. If you don't - the main idea does not change*/
     public class YourController implements Initializable {
    
    List<DropedComponentsCoordinates> dropedComponentsCoordinates;
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        dropedComponentsCoordinates = new ArrayList();
    }
    
    //This function will be fired, every time 
    //a user has dropped a component on the place he/she wants
    public void OnDropFired(ActionEvent event) {
        try {
            //getting the info we need from components
            String componentID = getComponentID(event);
            String component_xCoord = getComponent_xCoord(event);
            String component_yCoord = getComponent_yCoord(event);
    
            //putting this info to the list
            DropedComponentsCoordinates dcc = new DropedComponentsCoordinates();
            dcc.setX_Coord(component_xCoord);
            dcc.setY_Coord(component_yCoord);
            dcc.setComponentID(componentID);
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private String getComponentID(ActionEvent event){
        String componentID;
        /*getting cpmponentID*/
        return componentID;
    }
    private String getComponent_xCoord(ActionEvent event){
        String component_xCoord;
        /*getting component_xCoord*/
        return component_xCoord;
    }
    private String getComponent_yCoord(ActionEvent event){
        String component_yCoord;
        /*getting component_yCoord*/
        return component_yCoord;
    }
    }
    

    【讨论】:

    • 非常感谢您的回答。我正在考虑这样的策略,但我仍然想知道是否自动出现在网络上。并没有如jewelsea 发布的那样。所以最后我个人会使用这个解决方案:)
    猜你喜欢
    • 2021-07-15
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多