需要帮助创建自定义UI并将其添加到Scene Builder
我是Netbeans,JavaFX和Scene Builder的新手。我使用最新版本,意思是8.x.我有一个要求,从几年到几年。年份为4位数字,应为数字。需要帮助创建自定义UI并将其添加到Scene Builder
我找到了一个解决方案,并将其作为独立演示进行测试。所以我创建了下面的FXML和一个JAVA来创建一个JAR,我可以在Scene Builder中导入它。
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<fx:root id="AnchorPane" prefHeight="30.0" prefWidth="150.0" type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="numbertextfield.NumberTextField">
<children>
<TextField layoutX="14.0" layoutY="14.0" prefHeight="30.0" prefWidth="150.0" promptText="Enter only numbers " AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</fx:root>
控制器代码
package numbertextfield;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
/**
*
* @author Hornigold Arthur
*/
public class NumberTextField extends TextField {
private final IntegerProperty maxLength = new SimpleIntegerProperty(this, "maxLength", -1);
private final StringProperty restrict = new SimpleStringProperty(this, "restrict");
@FXML
private TextField numberTextField;
public void NumberTextFieldController() {
// TODO
System.out.println(" Inside NumberTextField Controller");
numberTextField.textProperty().addListener(new ChangeListener<String>() {
private boolean ignore;
@Override
public void changed(ObservableValue<? extends String> observableValue, String s, String s1) {
if (ignore || s1 == null) {
return;
}
if (maxLength.get() > -1 && s1.length() > maxLength.get()) {
ignore = true;
numberTextField.setText(s1.substring(0, maxLength.get()));
ignore = false;
}
if (restrict.get() != null && !restrict.get().equals("") && !s1.matches(restrict.get() + "*")) {
ignore = true;
numberTextField.setText(s);
ignore = false;
}
}
});
//
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("/NumberTextField.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
//
}
/**
* * The max length property. * * @return The max le
* @return ngth
* property.
*/
public IntegerProperty maxLengthProperty() {
return maxLength;
}
/**
* * Gets the max length of the text field. * * @return The
* max length.
* @return
*/
public int getMaxLength() {
return maxLength.get();
}
/**
* * Sets the max length of the text field. * * @param
* maxLength The max length.
* @param maxLength
*/
public void setMaxLength(int maxLength) {
this.maxLength.set(maxLength);
}
/**
* * The restrict property. * * @return The restrict
* property.
* @return
*/
public StringProperty restrictProperty() {
return restrict;
}
/**
* * Gets a regular expression character class which restricts the user
* input. * * @return The regular expression. * @see
* #getRestrict()
* @return
*/
public String getRestrict() {
return restrict.get();
}
/**
* * Sets a regular expression character class which restricts the user
* input. * E.g. [0-9] only allows numeric values. *
*
*
* @param restrict The regular expression.
*/
public void setRestrict(String restrict) {
this.restrict.set(restrict);
}
}
我进口的场景生成jar文件作为自定义类,并建立了一个 FXML用于独立的模块。
<?xml version="1.0" encoding="UTF-8"?>
<?import numbertextfield.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<NumberTextField fx:id="testNumber" layoutX="226.0" layoutY="125.0" maxLength="4" restrict=""[0-9]"" />
</children>
</AnchorPane>
下面的Java代码应该加载此FXML(它正确,并且显示出NumberTextField,但它允许任何长度的非数字字符。
package anothertest;
import java.io.IOException;
import javafx.application.Application;
import static javafx.application.ConditionalFeature.FXML;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import numbertextfield.NumberTextField;
/**
*
* @author Hornigold Arthur
*/
public class AnotherTest extends Application {
@FXML
NumberTextField testNumber = new NumberTextField();
@Override
public void start(Stage mainStage) throws Exception {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(AnotherTest.class.getResource("AnotherTest.fxml"));
AnchorPane rootLayout = (AnchorPane) loader.load();
testNumber.setMaxLength(4);
testNumber.setRestrict("[0-9");
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
mainStage.setScene(scene);
mainStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
但以下代码可以完美地从互联网样本中获取。
package testnumberinput;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextField;
/**
*
* @author Hornigold Arthur
*/
public class TestNumberInput extends Application {
@Override
public void start(Stage primaryStage) {
RestrictiveTextField textInput = new RestrictiveTextField();
textInput.setMaxLength(4);
textInput.setRestrict("[0-9]");
Label label1 = new Label("Enter a number : ");
textInput.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
HBox hBox = new HBox();
hBox.getChildren().addAll(label1, textInput);
StackPane root = new StackPane();
root.getChildren().add(hBox);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("This is a test ..... !");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
/**
* * A text field, which restricts the user's input.
* <p>
* * The restriction can either be a maximal number of characters which the
* user is allowed to input * or a regular expression class, which contains
* allowed characters. * </p>
*
* <p/>
* * <b>Sample, which restricts the input to maximal 10 numeric characters</b>:
*
* <pre>
* * {@code
* * RestrictiveTextField textField = new RestrictiveTextField();
* * textField.setMaxLength(10);
* * textField.setRestrict("[0-9]");
* * }
* * </pre> * * @author Christian Schudt
*/
class RestrictiveTextField extends TextField {
private IntegerProperty maxLength = new SimpleIntegerProperty(this, "maxLength", -1);
private StringProperty restrict = new SimpleStringProperty(this, "restrict");
public RestrictiveTextField() {
textProperty().addListener(new ChangeListener<String>() {
private boolean ignore;
@Override
public void changed(ObservableValue<? extends String> observableValue, String s, String s1) {
if (ignore || s1 == null) {
return;
}
if (maxLength.get() > -1 && s1.length() > maxLength.get()) {
ignore = true;
setText(s1.substring(0, maxLength.get()));
ignore = false;
}
if (restrict.get() != null && !restrict.get().equals("") && !s1.matches(restrict.get() + "*")) {
ignore = true;
setText(s);
ignore = false;
}
}
});
}
/**
* * The max length property. * * @return The max length
* property.
*/
public IntegerProperty maxLengthProperty() {
return maxLength;
}
/**
* * Gets the max length of the text field. * * @return The
* max length.
*/
public int getMaxLength() {
return maxLength.get();
}
/**
* * Sets the max length of the text field. * * @param
* maxLength The max length.
*/
public void setMaxLength(int maxLength) {
this.maxLength.set(maxLength);
}
/**
* * The restrict property.
* * @return The restrict property.
*/
public StringProperty restrictProperty() {
return restrict;
}
/**
* * Gets a regular expression character class which restricts the user
* input. * * @return The regular expression. * @see
* #getRestrict()
*/
public String getRestrict() {
return restrict.get();
}
/**
* * Sets a regular expression character class which restricts the user
* input. * E.g. [0-9] only allows numeric values. *
*
*
* @param restrict The regular expression.
*/
public void setRestrict(String restrict) {
this.restrict.set(restrict);
}
}
有人能告诉我我犯了什么错误吗?非常感谢。
为了方便,我修改了整个项目并将它们放到了单个NETBEANS项目中,以查看它是否可行。告诉我是否下列零件是正确的。它依然行不通。田野“时期来自”让我可以种类一切。
这是fxml-1。 (EditedNumber.fxml)
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<fx:root fx:id="numberField" promptText="Enter Number" type="TextField" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" />
这是fxml-1的控制器。 (EditedNumber.java)
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package InputNumber;
import java.io.IOException;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.TextField;
/**
*
* @author Hornigold Arthur
*/
public class EditedNumber extends TextField{
/**
*
* @author Hornigold Arthur
*/
private final IntegerProperty maxLength = new SimpleIntegerProperty(this, "maxLength", -1);
private final StringProperty restrict = new SimpleStringProperty(this, "restrict");
@FXML
private TextField numberField;
public void EditedNumber() {
// TODO
System.out.println(" Inside NumberTextField Controller");
numberField = new TextField();
numberField.textProperty().addListener(new ChangeListener<String>() {
private boolean ignore;
@Override
public void changed(ObservableValue<? extends String> observableValue, String s, String s1) {
if (ignore || s1 == null) {
return;
}
if (maxLength.get() > -1 && s1.length() > maxLength.get()) {
ignore = true;
numberField.setText(s1.substring(0, maxLength.get()));
ignore = false;
}
if (restrict.get() != null && !restrict.get().equals("") && !s1.matches(restrict.get() + "*")) {
ignore = true;
numberField.setText(s);
ignore = false;
}
}
});
//
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("Editor.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
//
/**
* * The max length property. * * @return The max le
*
* @return
*/
public IntegerProperty maxLengthProperty() {
return maxLength;
}
/**
* * Gets the max length of the text field. * * @return The
* max length.
*
* @return
*/
public int getMaxLength() {
return maxLength.get();
}
/**
* * Sets the max length of the text field. * * @param
* maxLength The max length.
*
* @param maxLength
*/
public void setMaxLength(int maxLength) {
this.maxLength.set(maxLength);
}
/**
* * The restrict property. * * @return The restrict
* property.
*
* @return
*/
public StringProperty restrictProperty() {
return restrict;
}
/**
* * Gets a regular expression character class which restricts the user
* input. * * @return The regular expression. * @see
* #getRestrict()
*
* @return
*/
public String getRestrict() {
return restrict.get();
}
/**
* * Sets a regular expression character class which restricts the user
* input. * E.g. [0-9] only allows numeric values. *
*
*
* @param restrict The regular expression.
*/
public void setRestrict(String restrict) {
this.restrict.set(restrict);
}
}
MY假设是-TOGETHER出来的产品应该在团队FOR A NEW UI类型。
这是fxml-2。它使用EditedNumber UI类型。 (mainFXML.fxml)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import InputNumber.EditedNumber?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.40">
<children>
<Label layoutX="128.0" layoutY="104.0" text="Period From : " textAlignment="RIGHT">
<font>
<Font name="Bookman Old Style" size="18.0" />
</font>
</Label>
<EditedNumber fx:id="periodFrom" layoutX="255.0" layoutY="98.0" style="-fx-background-color: lightblue; -fx-border-color: red; -fx-border-width: 2;">
<font>
<Font name="Bookman Old Style" size="18.0" />
</font>
</EditedNumber>
</children>
</AnchorPane>
这是控制器(或主节目)(InputNumber.java)
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package InputNumber;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/**
*
* @author Hornigold Arthur
*/
public class InputNumber extends Application {
@FXML
EditedNumber periodFrom;
@Override
public void start(Stage mainStage) {
periodFrom = new EditedNumber();
periodFrom.setMaxLength(4);
periodFrom.setRestrict("[0-9]");
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(InputNumber.class.getResource("mainFXML.fxml"));
AnchorPane rootLayout = (AnchorPane) loader.load();
Scene scene = new Scene(rootLayout);
mainStage.setScene(scene);
mainStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
没有编译错误。如果这可以正常工作,那么我可以将EDITED NUMBER类移动到Scene Builder并查看它是否正常工作。
在此先感谢您的指导。
你在这里有点混乱..
让我们开始你的主类。 testNumber.setRestrict("[0-9");
无法正常工作,您需要关闭托架:("[0-9]")
然后在你的NumberTextField FXML 定义fx:root
id=AnchorPane
但在你的类,你扩展TextField
。决定你想要扩展哪一个!我建议扩展TextField,但是在你的类中你不需要额外的私有FieldField,因为那样你就会有两个TextField。
作为控制器您写了controller="numbertextfield.NumberTextField"
但这不是特定的Classname。在你的班级中,你再次定义了控制器。你不能设置两次!请再决定你想放置这些线的位置。
对于TextField
你没有定义fx:id
但在你的类要通过@FXML
标签来访问它。也不可能。
然后在NumberField类中,您确实有这种称为NumberTextFieldController
的方法,它永远不会被调用。里面的代码必须在NumberTextField
的构造函数中,而不是一个额外的方法。 然后,您必须首先加载FXML,然后才能访问TextField的textproperty
。因此,请在FXMLLoader
之间向上移动这些行。
请做一些清理,然后再试一次!
编辑:
还是很多的错误!也许你应该把芦苇this文件。
EditedNumber类:我想你实例化了numberField,因为你在下一行有NPE吗?删除该行并将fxmlLoader.load()
移动到构造函数的第一行,以便您的fxml文件被加载,并且该字段将被实例化,但您甚至不需要字段numberField
,因为您的类是TextField。删除它并更改呼叫,例如从numberField.textProperty()
到this.textProperty()
你还没有构造函数。删除void
这里
public void EditedNumber() {...}
你为什么要加载这个资源?你说这个名字是EditedNumber.fxml
而不是Editor.fxml
。您需要添加/
作为第一个字符以查找fxml。
final FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("Editor.fxml"));
做所有这些变化,在我的例子中它的工作!
谢谢,但它似乎仍然没有工作。 –
查看我更新的答案! – Tobi
@HornigoldArthur工作吗?欣赏upvote并接受;) – Tobi