JavaFX使用自己的函数创建和使用自定义控件

时间:2015-07-18 07:19:07

标签: java javafx

我创建了一个简单的自定义控件,如图所示:
enter image description here

当我点击“Click me”按钮时,控制台会向我显示此消息“按钮被点击了!”通过名为doSomething的函数,这是自定义控件的fxml文件代码:

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

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

<fx:root prefHeight="83.0" prefWidth="196.0" type="javafx.scene.layout.AnchorPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <TextField fx:id="textField" layoutY="2.0" prefHeight="25.0" prefWidth="196.0" />
      <Button layoutX="72.0" layoutY="29.0" mnemonicParsing="false" onAction="#doSomething" text="Click me" />
   </children>
</fx:root>

这是此自定义控件的控制器:

package control;

import java.io.IOException;

import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;

public class Controller extends AnchorPane {
    @FXML private TextField textField;

    public Controller() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("CustomControlView.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    public String getText() {
        return textProperty().get();
    }

    public void setText(String value) {
        textProperty().set(value);
    }

    public StringProperty textProperty() {
        return textField.textProperty();
    }

    @FXML
    protected void doSomething() {
        System.out.println("The button was clicked!");
    }
}

控件工作正常,我可以使用“JavaFX场景构建器”在另一个fxml文件中调用它(如图所示):
enter image description here

这是fxml文件代码:

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

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

<AnchorPane prefHeight="237.0" prefWidth="324.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <javafx.scene.layout.AnchorPane layoutX="64.0" layoutY="92.0" prefHeight="40.0" prefWidth="196.0">
         <children>
            <TextField fx:id="textField" layoutY="2.0" prefHeight="25.0" prefWidth="196.0" />
            <Button layoutX="72.0" layoutY="29.0" mnemonicParsing="false" onAction="#doSomething" text="Click me" />
         </children>
      </javafx.scene.layout.AnchorPane>
      <Label layoutX="75.0" layoutY="14.0" text="Trying the custom control:">
         <font>
            <Font size="15.0" />
         </font>
      </Label>
   </children>
</AnchorPane>

但问题是我必须重新定义自定义控件按钮的doSomething功能!!!我的意思是当我将自定义控件添加到另一个fxml文件时,此自定义控件的所有功能都应该无需重新定义就像Swing一样 我错了吗?

1 个答案:

答案 0 :(得分:0)

问题是,Scene Builder只是将自定义控件的代码复制到新控件中而不是链接它。要使用自定义控件,您必须使用fx:include FXML标记。

因此FXML文件应该类似于:

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

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

<AnchorPane prefHeight="237.0" prefWidth="324.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <fx:include source="yourCustomControl.fxml" />
      <Label layoutX="75.0" layoutY="14.0" text="Trying the custom control:">
         <font>
            <Font size="15.0" />
         </font>
      </Label>
   </children>
</AnchorPane>

但是,您必须手动执行此操作。据我所知,Scene Builder无法做到这一点。