JavaFX: Eigene Klasse/Komponente in FXML nutzen

BenutzereingabenIch freue mich über jeden einzelnen Kommentar von euch. Egal ob Feedback, Anmerkung, Berichtigung oder Frage.
Am 11. Oktober 2013 um ca 12:39 Uhr hat Gustav einen sehr interessanten Kommentar zu meinen Beitrag “JavaFX: TextField Eingabe beschränken (nur Zahlen, Buchstaben, etc.)” gesendet. Er hat gefragt, wie man eine eigene Klasse, zum Beispiel die NumberTextField, in einer FXML-Oberfläche verwenden kann. Da die Antwort bestimmt viele von euch interessiert, schreibe ich einen kleinen Blog-Beitrag dazu:)

 

TextField nur mit Nummern

TextFieldUm was geht es eigentlich? In JavaFX gibt es out-of-the-box keine Komponente, die nur numerische Eingaben entgegen nimmt. Natürlich ist das doof, für Betragsfelder, Altersangaben oder Jahreszahlen. Daher muss man sich eine eigene Komponente bauen, die von der eigentlichen TextField-Klasse ableitet. Das Ergebnis sieht so aus:

 

import javafx.scene.control.TextField;

public class NumberTextField extends TextField {
	
	 @Override public void replaceText(int start, int end, String text) {
	        if (text.matches("[0-9]") || text == "") {
	            super.replaceText(start, end, text);
	        }
	    }
	 
	    @Override public void replaceSelection(String text) {
	        if (text.matches("[0-9]") || text == "") {
	            super.replaceSelection(text);
	        }
	    }

}

 

FXML

Um jetzt diese neue Komponente in FXML zu nutzen, muss man folgendes tun:

  • Die Klasse includieren (Zeile 9)
  • Die Komponente einbinden (Zeile 22)
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import de.axxg.fxml.NumberTextField?>
<?import javafx.scene.text.*?>


<GridPane fx:id="grid" alignment="CENTER" hgap="10.0" vgap="10.0" xmlns:fx="http://javafx.com/fxml">
  <children>
    <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Hallo AxxG-Leser" GridPane.columnIndex="0" GridPane.rowIndex="0">
      <font>
        <Font name="Tahoma" size="20.0" />
      </font>
    </Text>
    <Label text="Alter:" GridPane.columnIndex="0" GridPane.rowIndex="1" />
    <Label text="Name:" GridPane.columnIndex="0" GridPane.rowIndex="2" />
    <NumberTextField fx:id="AlterTF" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
    <TextField fx:id="NameTF" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
    <HBox GridPane.columnIndex="1" GridPane.rowIndex="4">
      <children>
        <Button fx:id="addBtn" mnemonicParsing="false" text="eintragen" />
        <Button fx:id="okBtn" mnemonicParsing="false" text="Alle anzeigen" />
      </children>
    </HBox>
  </children>
  <padding>
    <Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />
  </padding>
</GridPane>

 

Download

Für Faule gibt es hier ein fertiges Projekt…

Java Version JDK 1.7.0_11 Inhalt gepacktes Projekt
JavaFX Version 2.2.4 Größe ~3.9 MB
IDE Eclipse IDE Version 4.2.2 Endung *.zip
Preis kostenlos Lizenz Creative Commons Lizenzvertrag

JavaFX eigene FXML Komponente

 

Quellen

 

Copyright © 2013 AxxG – Alexander Gräsel



7 Antworten : “JavaFX: Eigene Klasse/Komponente in FXML nutzen”

  1. Gustav sagt:

    Hallo Alexander!
    Suuuper! Danke für diesen tollen Beitrag! Genial!
    LG
    Gustav

  2. Sebastian Schön sagt:

    Auch von mir vielen Dank. Bin gerade am Lernen von JavaFX. Jetzt muss ich nur noch ein Custom Control in den Scene Builder integrieren. Hoffe, dass das geht. ^_^

  3. Schön, dass ich dir weiterhelfen konnte:)
    Viel Spaß noch beim experimentieren mit JavaFX!

    • Mukhtar A. sagt:

      hallo, ich brauche hlfe…
      moechte gerne meine eigene klasse ( ein Graph in javfx einbinden )

      Ich haben eine Klasse, die ist von JavaFX “Application” Klasse vererbt.
      ich habe in dieser Klasse eine Eigenschaft, und wir setzte diese Eigenschaft mit einem Wert.
      Das Problem aber ist, das sobald ich die Eigenschaft in @Override start(Stage stage) aufrufe, kriegen ich null zurück, obwohl ich den Wert vor dem Aufruf von “start” gesetzt haben.
      Können Sie mir sagen, wie ich den Wert in “Application.start(Stage stage)” beibehalte.

      Beispiel:
      public class XYZ extends Application{
      private String x;

      @Override
      public void start(Stage stage) throws Exception {
      System.out.println(x); //gibt null zurück
      }

      //getter und setter für x
      }

      In der Main Klasse x wurde gesetzt.
      falls sie den gesammten code sehen möchten sende ich Ihnen diese auch.

  4. Das “Problem”/Verhalten liegt an JavaFX. Theoretisch starten Java-Programme mit der

    public static void main(String[] args) {
    launch(args);
    }

    -Methode, jedoch nicht JavaFX-Programme! Ab Java 8 oder so wird diese Methode nicht mehr von JavaFX-Programmen aufgerufen. Der aller erste Einstieg/Aufruf passiert also in der

    @Override
    public void start(Stage primaryStage) {
    }

    -Methode. Daher muss die Variable in dieser Methode gesetzt werden. Theoretisch kann man die Main-Methode in JavaFX-Programmen auch weglassen….

  5. Programmer sagt:

    Ein tolles Beisiel, aber wie kann ich die motifizierte Control im Scene Builder sichtbar machen?

Kommentar verfassen