【问题标题】:SceneBuilder Custom Control ClasspathSceneBuilder 自定义控件类路径
【发布时间】:2014-08-21 09:45:26
【问题描述】:

我对 SceneBuilder 和 Java FX 处理自定义控件的方式束手无策。

  1. 我是使用 fx:root,还是不使用它?我选择使用它。所以内 控件的Controller+Root类,我把自己设置为root 和控制器,根据需要。但它仍然说“根没有 被设置。在加载之前使用方法 setRoot()。"

  2. 在将容纳自定义控件的父 FXML 中,我是什么 应该导入?

  3. 什么是正确的类路径,以便我可以显示我的自定义 SceneBuilder 2.0 中的控件?我不太明白 “/.../.../.../bin”的东西。

  4. 有了新的<fx:include>标签,是否有必要使用 <MyCustomControl /> 不再在标记中了?

到目前为止,我的自定义控件只是一个进度指示器,以避免复杂化。

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.HBox?>


<fx:root type="HBox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
   <children>
      <ProgressBar fx:id="progressBar" prefWidth="200.0" progress="0.0" />
   </children>
</fx:root>

package application.ctrl;

import java.io.IOException;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import application.Main;

它的控制器:

public class ProgressSelector extends HBox {

    @FXML
    private ProgressIndicator progressBar;



    public ProgressSelector() {
        FXMLLoader loader = new FXMLLoader(getClass().getResource(
                Main.PROGRESS_SELECTOR));
        loader.setRoot(this);
        loader.setController(this);
        loader.setClassLoader(this.getClass().getClassLoader());
        try {
            loader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

父 FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.VBox?>
<?import application.ctrl.ProgressSelector?>

<VBox fx:id="vbox" spacing="5.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.ctrl.ObjectiveEditorCtrl">
   <children>
      <HBox>
         <children>
            <Button mnemonicParsing="false" onAction="#back" text="&lt;" />
            <Label text="Editing Objective:" />
         </children>
      </HBox>
      <TextField fx:id="objectiveName" />
      <ProgressSelector />
      <HBox>
         <children>
            <Label text="Planned Start:" />
            <Region HBox.hgrow="ALWAYS" />
            <DatePicker fx:id="plannedStart" />
         </children>
      </HBox>
      <HBox>
         <children>
            <Label text="Actual Start:" />
            <Region HBox.hgrow="ALWAYS" />
            <DatePicker fx:id="actualStart" />
         </children>
      </HBox>
      <HBox>
         <children>
            <Label text="Planned Finish:" />
            <Region HBox.hgrow="ALWAYS" />
            <DatePicker fx:id="plannedFinish" />
         </children>
      </HBox>
      <HBox>
         <children>
            <Label text="Actual Finish:" />
            <Region HBox.hgrow="ALWAYS" />
            <DatePicker fx:id="actualFinish" />
         </children>
      </HBox>
      <HBox alignment="CENTER_RIGHT">
         <children>
            <Button mnemonicParsing="false" onAction="#save" text="Save" />
            <Button mnemonicParsing="false" onAction="#back" text="Cancel" />
         </children>
      </HBox>
   </children>
   <padding>
      <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
   </padding>
</VBox>

它的控制器:

package application.ctrl;

import interfaces.ControlledScreenInterface;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import application.ScreenController;
import application.objects.Objective;

public class ObjectiveEditorCtrl implements Initializable,
        ControlledScreenInterface {

    @FXML
    private TextField objectiveName;
    @FXML
    private ProgressSelector completion;
    @FXML
    private DatePicker plannedStart;
    @FXML
    private DatePicker plannedFinish;
    @FXML
    private DatePicker actualStart;
    @FXML
    private DatePicker actualFinish;
    @FXML
    private VBox vbox;

    private ScreenController parent;
    private Objective current;



    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // TODO Auto-generated method stub

    }



    public void init(Objective current) {
        this.current = current;
        objectiveName.setText(current.getName());
        // completion.setProgress(current.getCompletion());
        plannedStart.setValue(current.getPlannedStart());
        actualStart.setValue(current.getActualStart());
        plannedFinish.setValue(current.getPlannedFinish());
        actualFinish.setValue(current.getActualFinish());
    }



    public void save() {
        // current.setName(objectiveName.getText());
        // // current.setCompletion(completion.getProgress());
        // current.setPlannedStart(plannedStart.getValue());
        // current.setPlannedFinish(plannedFinish.getValue());
        // current.setActualStart(actualStart.getValue());
        // current.setActualFinish(actualFinish.getValue());
        // back();
    }



    public void back() {
        parent.back();
    }



    @Override
    public void setParentScreen(ScreenController parent) {
        this.parent = parent;
    }
}

【问题讨论】:

    标签: java javafx javafx-8 scenebuilder


    【解决方案1】:

    这里有很多问题。

    1 - 使用 fx:root 允许您自定义 FXMLLoader,您可以更改实例化组件的方式:How to create multiple javafx controllers with different fxml files?

    但是,对于 SceneBuilder 2,它根本无法正常工作! Scene Builder 2 的“规范”方式(适用于 1)似乎不使用 fx:root。

    2 - 这取决于您在 1 中选择的模式。可以是 FXML 中具有显式导入的自定义 java 组件,或者使用 fxml:include。先是 FXML,然后是控制器。或者抽象组件(和控制器作为 fx:root)然后是 FXML。

    3 - SceneBuilder 2 在类加载器方面存在许多问题,因为每个自定义组件都加载了不同的类加载器,这意味着您将运行很多找不到类的异常,例如异常。解决它的一种方法是 fork SceneBuilder 强制它只使用一个类加载器用于所有自定义组件:Custom Components in Scenebuilder 2.0

    或者等待修复。或者不使用 fx:root 而更喜欢 fx:include。或者根本不使用 Scene Builder,这对于许多有效的解决方案来说都是一个有效的解决方案。

    【讨论】:

      猜你喜欢
      • 2012-08-24
      • 2016-08-21
      • 2015-12-08
      • 2021-08-17
      • 2018-12-20
      • 2014-12-02
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多