如何使用FXML创建Integer微调器

Chr*_*ith 7 javafx spinner fxml

我正在尝试创建一个Integer Spinner,而是创建一个而Double不是.

的Test.class

package com.neonorb.test;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Test extends Application{
    @Override
    public void start(Stage stage) throws Exception {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Demo.fxml"));
        Parent root = fxmlLoader.load();
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

DemoController.class

package com.neonorb.test;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Spinner;

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

public class DemoController implements Initializable{
    @FXML
    private Spinner<Integer> spinner;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        System.out.println(spinner.getValue());
    }
}
Run Code Online (Sandbox Code Playgroud)

Demo.fxml

<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.Spinner?>
<?import java.lang.Integer?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="com.neonorb.test.DemoController">
    <Spinner fx:id="spinner" min="1" initialValue="1" amountToStepBy="1">
        <max>
            <Integer fx:constant="MAX_VALUE"/>
        </max>
    </Spinner>
</BorderPane>
Run Code Online (Sandbox Code Playgroud)

当我执行它输出时1.0,我知道它是如何制作一个Double微调器.

我想发生的事情FXMLLoader是选择错误的构造函数Spinner.我该如何选择Integer

aw-*_*ink 14

问题

您需要为微调器设置值工厂.否则你将面临类型强制.如果您无法在那里进行设置,则可以定义将由static valueOf()调用的Integer值.

关于类型强制的JavaFX FXML简介:

类型强制

FXML使用"类型强制"将属性值转换为适当的类型.类型强制是必需的,因为XML支持的唯一数据类型是元素,文本和属性(其值也是文本).但是,Java支持许多不同的数据类型,包括内置的原始值类型以及可扩展的引用类型.

FXML加载器使用BeanAdapter的coerce()方法来执行任何所需的类型转换.此方法能够执行基本的基本类型转换,例如String to boolean或int to double,并且还将String转换为Class或String转换为Enum.可以通过在目标类型上定义静态valueOf()方法来实现其他转换.


与工厂的解决方案

已存在IntegerSpinnerValueFactory.因为它是SpinnerValueFactory的嵌套类,所以必须在tag-name中使用一个点.

有三个构造函数可用,您可以设置min/max和min/max/initialValue和min/max/initialValue/amountToStepBy.这是通过将其设置为属性来完成的.

Demo.fxml

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


<BorderPane xmlns:fx="http://javafx.com/fxml/1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" fx:controller="demoapp.DemoController">
  <center>
    <Spinner fx:id="spinner" BorderPane.alignment="CENTER" >
      <valueFactory>
        <SpinnerValueFactory.IntegerSpinnerValueFactory min="0" max="10"/>
      </valueFactory>
    </Spinner>
  </center>
</BorderPane>
Run Code Online (Sandbox Code Playgroud)


没有工厂的解决方案

您还可以定义两个变量并将它们用作静态valueOf().如上面引用的静态valueOf()方法所述.因此,您的FXMLLoader不必猜测您可能意味着哪种类型.它使用int值调用构造函数.

Demo.fxml

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


<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="demoapp.DemoController" xmlns="http://javafx.com/javafx/8.0_40" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"  >
  <center>
    <fx:define>
      <Integer fx:id="min" fx:value="0"/>
      <Integer fx:id="max" fx:value="10"/>
    </fx:define>
    <Spinner fx:id="spinner" BorderPane.alignment="CENTER" min="$min" max="$max">
    </Spinner>
  </center>
</BorderPane>
Run Code Online (Sandbox Code Playgroud)


Joh*_*tor 8

FXML 文件的一个小更新......

包括

<?import javafx.scene.control.SpinnerValueFactory.IntegerSpinnerValueFactory?>
Run Code Online (Sandbox Code Playgroud)

然后

        <Spinner fx:id="spinner" BorderPane.alignment="CENTER" editable="true" >
            <valueFactory>
                <SpinnerValueFactory.IntegerSpinnerValueFactory min="0" max="10" initialValue="5" amountToStepBy="1"/>
            </valueFactory>
        </Spinner>
Run Code Online (Sandbox Code Playgroud)

  • 不需要额外的导入,因为所有的导入都已经通过 `&lt;?import javafx.scene.control.* ?&gt;` 完成了。默认的 `amountToStepBy` 定义为 1,所以不需要写显式。请阅读 [JavaDoc](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/SpinnerValueFactory.IntegerSpinnerValueFactory.html) (2认同)