2017-06-28 2 views
2

J'essaie actuellement de créer une application qui se comporte comme un shell de commande. Je veux afficher un chemin que je lui donne (ou un caractère '>' au minimum) avant le texte d'entrée de l'utilisateur dans un champ de texte javaFX. comme ceci:Afficher le texte non-effaçable avant le texte de saisie dans le champ de texte JavaFX

enter image description here

Je l'ai pour que le champ de texte clair lorsque l'utilisateur soumet le texte. Après une soumission, elle définit le texte du champ comme mon chemin pour obtenir un effet similaire, mais l'utilisateur peut toujours supprimer ce chemin lors de la saisie de texte.

Comment faire en sorte que le texte de mon chemin apparaisse dans le champ mais que l'utilisateur ne puisse pas le supprimer?

J'ai essayé cela, mais il met à jour que la position de caret après la soumission:

 textField.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent event) { 
      textField.positionCaret(textField.getLength()); 
     } 
    }); 
+0

Cela devrait aider: https://stackoverflow.com/questions/19167750/control-keyboard-input-into-javafx-textfield – Oswald

+0

@Oswald Les réponses à cette question sont plutôt obsolètes, et n'incluent pas la façon de faire de ce genre actuellement supportée, en utilisant un 'TextFormatter'. –

Répondre

3

Vous pouvez utiliser un TextFormatter pour filtrer les opérations non valides sur le champ de texte. Un TextFormatter a un filtre qui filtre les modifications apportées au champ de texte; vous pouvez opposer votre veto à tout changement en renvoyant le filtre null. La mise en œuvre plus simple pour ce que vous décrivez serait tout simplement filtrer les changements où la position de caret ou l'ancre pour le champ de texte étaient avant la fin du texte fixe:

UnaryOperator<TextFormatter.Change> filter = c -> { 
    if (c.getCaretPosition() < prefix.length() || c.getAnchor() < prefix.length()) { 
     return null ; 
    } else { 
     return c ; 
    } 
}; 

textField.setTextFormatter(new TextFormatter<String>(filter)); 

Vous pouvez expérimenter avec d'autres logiques ici (par exemple si vous voulez que l'utilisateur puisse sélectionner le texte fixe).

Voici un SSCCE:

import java.util.function.UnaryOperator; 

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.control.TextFormatter; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class TextFieldFixedPrefix extends Application { 

    private TextField createFixedPrefixTextField(String prefix) { 
     TextField textField = new TextField(prefix); 

     UnaryOperator<TextFormatter.Change> filter = c -> { 
      if (c.getCaretPosition() < prefix.length() || c.getAnchor() < prefix.length()) { 
       return null ; 
      } else { 
       return c ; 
      } 
     }; 

     textField.setTextFormatter(new TextFormatter<String>(filter)); 

     textField.positionCaret(prefix.length()); 

     return textField ; 
    } 

    @Override 
    public void start(Stage primaryStage) { 

     TextField textField = createFixedPrefixTextField("/home/currentUser $ "); 
     StackPane root = new StackPane(textField); 
     Scene scene = new Scene(root, 300,40); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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