JavaFX Textfields: Fortschritt als ProgressBar und Progressindicator

Blah123

Mitglied
Hallo zusammen,

ich arbeite mich gerade etwas in Java und JavaFx ein.
Ich will einfach eine kleine GUI entwickeln mit zwei Textfeldern, einem Progressbar sowie einem Progressindicator. Darauf soll dargestellt werden wieviel % meiner Textfelder ausgefüllt wurden.
D.h. wenn ein Textfeld mit Text befüllt ist 50%, wenn 2 befüllt sind, dann 100%.

Ich habe das über einen Button gelöst. Der ruft dann eine Methode auf, die Checkt, ob ein TF leer ist und wenn nicht, dann wird der Fortschritt erhöht.

Java:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.scene.control.*;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.Cursor;
import javafx.scene.paint.Color;
import javafx.geometry.Insets;
import javafx.scene.layout.*;

/**
  *
  * Beschreibung
  *
  * @version 1.0 vom 16.11.2017
  * @author
  */

public class fxtest extends Application {
  // Anfang Attribute
  private TextField tf_weight = new TextField();
  private TextField tf_size = new TextField();
  private Button button1 = new Button();
  private ProgressBar progressBar1 = new ProgressBar();
  private ProgressIndicator progressIndicator1 = new ProgressIndicator();
 
  //Fortschritt für die Progressindicators
  double fortschritt=0;
 
  // Ende Attribute
 
  public void start(Stage primaryStage) {
  
    Pane root = new Pane();
    Scene scene = new Scene(root, 604, 678);
    // Anfang Komponenten
  
    tf_weight.setLayoutX(152);
    tf_weight.setLayoutY(32);
    tf_weight.setPrefHeight(49);
    tf_weight.setPrefWidth(193);
    root.getChildren().add(tf_weight);
    tf_size.setLayoutX(152);
    tf_size.setLayoutY(96);
    tf_size.setPrefHeight(49);
    tf_size.setPrefWidth(193);
    root.getChildren().add(tf_size);
    button1.setLayoutX(160);
    button1.setLayoutY(176);
    button1.setPrefHeight(41);
    button1.setPrefWidth(169);
    root.getChildren().add(button1);
    button1.setOnAction(
      (event) -> {button1_Action(event);}
    );
    progressBar1.setLayoutX(96);
    progressBar1.setLayoutY(288);
    progressBar1.setPrefHeight(41);
    progressBar1.setPrefWidth(225);
  
    root.getChildren().add(progressBar1);
    progressIndicator1.setLayoutX(384);
    progressIndicator1.setLayoutY(264);
    progressIndicator1.setPrefHeight(97);
    progressIndicator1.setPrefWidth(129);
    root.getChildren().add(progressIndicator1);
    progressIndicator1.setProgress(0);
  
    tf_weight.setPromptText("weight");
    tf_weight.setText("");
    tf_size.setCursor(Cursor.DEFAULT);
    tf_size.setPromptText("size");
  
  
    // Ende Komponenten
  
    primaryStage.setOnCloseRequest(e -> System.exit(0));
    primaryStage.setTitle("fxtest");
    primaryStage.setScene(scene);
    primaryStage.show();
  } // end of public fxtest
 
  // Anfang Methoden
 
  public static void main(String[] args) {
    launch(args);
  } // end of main
 
  public void button1_Action(Event evt) {
    // TODO hier Quelltext einfügen
    progressCheck();
  
  
  } // end of button1_Action
  private Separator separator1 = new Separator();


  //Checkt, wie viele Textfelder einen Inhalt haben und passt Progressbar sowie ProgressIndicator an
  public void progressCheck(){
  
    //Je nachdem wie viele Textfelder ich habe, muss ich den Teiler anpassen
    //Bei zwei Textfeldern ist der teiler pro Textfeld 1/2. Bei Drei ist er bei 1/3
  
    double teiler=(double)1/2;
        
    if ((tf_weight.getText().trim().length()>0)) {
       fortschritt=fortschritt+teiler;
       
       progressBar1.setProgress(fortschritt);
       progressIndicator1.setProgress(fortschritt);
    } // end of if
  
    if ((tf_size.getText().trim().length()>0)) {
       fortschritt=fortschritt+teiler;
       
       progressBar1.setProgress(fortschritt);
       progressIndicator1.setProgress(fortschritt);
    } // end of if
  
    //progressIndicator1.setProgress(0.8);
    }
  // Ende Methoden
} // end of class fxtest


Dazu ein paar Fragen:
1. Im Moment muss ich immer den Umweg über den Button gehen. Wie stellt man denn sicher, dass immer wenn ich ein Textfeld verlasse, die Methode ProgressCheck() aufgerufen wird. Man benötigt sicher irgendeinen Listener?! Weiss aber nicht wie das geht.


2. Bei mir ist der Focus immer Standardmäßig auf dem Textfeld tf_weight und der PromptText ist deswegen nicht sicherbar. Kann man den Focus irgendwie entfernen (kenne nur .requestFocus(). Aber worauf soll ich den Focus setzen?


Vielen Dank schonmal
Robert
 
Zu 1. Du könntest dem textProperty des Textfeldes einen ChangeListener geben, sodass ProgressCheck() immer nach einem Verändern des Textes in diesem Feld aufgerufen wird.
Java:
textField.textProperty().addListener(e->{
        //Das wird immer ausgeführt, wenn der Text im Feld verändert wird.
});

Zum 2.: Wenn die TextFelder den Fokus nicht haben, kannst du in sie (soweit ich weiß) nichts schreiben, weshalb du ihn sowieso nicht dauerhaft auf ein anderes Objekt setzten kannst.
 
Das Beispiel (bzw. das Lambda) oben dürfte den InvalidationListener erfüllen, was hier gewollte ist ist eher
Java:
textField.textProperty().addListener((observable, oldValue, newValue) -> {
        //Das wird immer ausgeführt, wenn der Text im Feld verändert wird.
});
 
Was unterscheidet den InvalidationListener in diesem Fall vom ChangeListener? Ich habe die beiden noch nie so richtig auseinander halten können aber bei mir erfüllen beide den Zweck.
 
Naja, du willst eigentlich nicht wissen, wann ein ObservableValue invalid wird:
https://docs.oracle.com/javase/8/javafx/api/javafx/beans/InvalidationListener.html
Sondern stattdessen, wann er sich ändert:
https://docs.oracle.com/javase/8/javafx/api/index.html?javafx/beans/Observable.html
Eigentlich ist hier der Name entscheidend. Ich glaube mich zu erinnern, dass der erste Listener nicht unbedingt immer gefeuert werden muss. Wenn es bei dir klappt: Gut, aber es kann auch eben mal nicht funktionieren, daher würde ich eher einfach den dafür vorgesehenen und semantisch bereits korrekten ChangeListener verwenden.
 

Zurück
Oben