2015-10-15 79 views
1

我是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="&quot;[0-9]&quot;" /> 
     </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並查看它是否正常工作。

在此先感謝您的指導。

回答

0

你在這裏有點混亂..

讓我們開始你的主類。 testNumber.setRestrict("[0-9"); 無法正常工作,您需要關閉托架:("[0-9]")

然後在你的NumberTextField FXML 定義fx:rootid=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")); 

做所有這些變化,在我的例子中它的工作!

+0

謝謝,但它似乎仍然沒有工作。 –

+0

查看我更新的答案! – Tobi

+0

@HornigoldArthur工作嗎?欣賞upvote並接受;) – Tobi

相關問題