2017-02-10 3 views
1

Я использую TextField, чтобы отобразить путь к каталогу, который открыл пользователь в моем приложении.JavaFX TextField: как «автоматически прокручивать» вправо при переполнении текста

В настоящее время, если путь не может поместиться внутри TextField, при фокусировке далеко/щелкает от этого контроля, он выглядит так, как будто путь стал усеченным:

file path text overflowing and looks as if it's truncated

Я хочу поведение TextField установлено таким образом, что, когда я фокусируюсь от него, путь, показанный внутри, автоматически прокручивается вправо, и пользователь может видеть каталог, который они открыли. То есть что-то вроде этого:

file path text auto scrolling and we can see the innermost directory

Как я могу добиться этого? Я попытался адаптировать ответ, данный от here

следующим образом в initialize() метода в моем классе FXML Controller:

// Controller class fields 
@FXML TextField txtMoisParentDirectory; 
private String moisParentDirectory; 

// ... 

txtMoisParentDirectory.textProperty().addListener(new ChangeListener<String>() { 

       @Override 
       public void changed(ObservableValue<? extends String> observable, String oldStr, String newStr) { 
        moisParentDirectory = newStr; 
        txtMoisParentDirectory.selectPositionCaret(moisParentDirectory.length()); 
        txtMoisParentDirectory.deselect(); 

       } 
      }); 

Однако это не работает.

ответ

1

Ваша проблема основана на двух событиях, длина вводимого текста и потере фокуса, так чтобы решить ее, я использовал свойства textProperty() и focusedProperty() и вот результат:

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.Pane; 
import javafx.stage.Stage; 

public class Launcher extends Application{ 

private Pane root = new Pane(); 
private Scene scene; 
private TextField tf = new TextField(); 
private TextField tft = new TextField(); 

private int location = 0; 

@Override 
public void start(Stage stage) throws Exception { 


    scrollChange(); 
    tft.setLayoutX(300); 
    root.getChildren().addAll(tft,tf); 
    scene = new Scene(root,400,400); 
    stage.setScene(scene); 
    stage.show(); 

} 

private void scrollChange(){ 


    tf.textProperty().addListener(new ChangeListener<String>() { 

     @Override 
     public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 

      location = tf.getText().length(); 

     } 
    }); 


    tf.focusedProperty().addListener(new ChangeListener<Boolean>() { 

     @Override 
     public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { 

      if(!newValue){ 

       Platform.runLater(new Runnable() { 
        @Override 
        public void run() { 

         tf.positionCaret(location); 

        } 
       }); 


      } 


     } 
    }); 



} 


public static void main(String[] args) { 

    launch(args); 

} 


} 

А по поводу Platform.runLater Я добавил его после этого ответа Here Я не знаю, почему он не работает без него, удачи!

+0

Благодарим за помощь - любая конкретная причина, по которой вы использовали «Ярлык»? В моем 'ChangeListener' (см. Вопрос) я добавил' location = newStr.length(); 'где' location' - поле, указанное точно так же, как в вашем коде. Я также добавил 'сфокусированныйProperty'' ChangeListener', как и у вас, но во время работы он, похоже, не работает. Вы можете попробовать с помощью «TextField» вместо «Label»? Я знаю, что это не должно иметь значения, и все, но это просто для ясности. –

+0

Я удалил «Ярлык», не нужно было выглядеть, я обновил свой код, и он не работает в вашем коде, поэтому я добавил 'Platform.runLater()'! –

+0

Правильно, это работает как шарм! Спасибо :) –

Смежные вопросы