JavaFX 2: Fabrication d'un composant ScrollPane faire défiler automatiquement le bord après l'ajout de contenu

À l'aide de JavaFX 2, j'ai un exemple de base d'un ScrollPane qui contient un HBox de Labels. Je veux être en mesure d'ajouter un Label à la HBox, et, simultanément, de faire défiler le bord droit de la ScrollPane de sorte que le nouveau Label est visible. Ma méthode actuelle utilise le setHvalue() pour définir la position de défilement et getHmax() pour obtenir le maximum de défilement de la distance autorisée.

Le problème est que lorsque j'ai mis la position de défilement à l'aide de getHmax(), c'est comme si la juste ajouté Label n'est pas calculé dans le ScrollPanel's défiler largeur. Est-il possible que je puisse mettre à jour cette largeur intérieure avant d'essayer setHvalue?

Consultez cet exemple simple de code qui expose le problème.

En particulier, notez le addChatItem(String item) méthode, qui contient la logique de défilement vers le bord de la ScrollPane.

    import java.util.Timer;
import java.util.TimerTask;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class ScrollPaneTest extends Application {   
static int defaultFontSize = 30;
ScrollPaneTest scrollPaneTest = this;
ScrollPane chatBoxScrollPane = new ScrollPane();
HBox chatBox = new HBox();
Chatter chatter = new Chatter();
public static void main(String[] args) {
launch(args);//default
}
@Override
public void stop() throws Exception {
super.stop();
System.exit(0);
}
@Override
public void start(Stage primaryStage) {
BorderPane borderPane = new BorderPane();       
StackPane chatBoxStackPane = new StackPane();
chatBoxScrollPane.setContent(chatBox);
//chatBoxScrollPane.setHbarPolicy(ScrollBarPolicy.NEVER);
chatBoxScrollPane.setMaxHeight(50);
chatBoxStackPane.getChildren().add(chatBoxScrollPane);
borderPane.setCenter(chatBoxStackPane);
Scene scene = new Scene(borderPane, 800, 600);
primaryStage.setScene(scene);
primaryStage.setTitle("Scroll Demo");
primaryStage.show(); 
new Thread("mainGameControlThread") {
public void run() {
chatter.chatLoop(scrollPaneTest);
}
}.start();
}
public void addChatItem(String chatString) {
Label title = new Label(chatString);        
title.setFont(new Font("Verdana", defaultFontSize));
chatBox.getChildren().add(title);
chatBoxScrollPane.setHvalue(chatBoxScrollPane.getHmax());
}
class Chatter {
public void chatLoop(final ScrollPaneTest test) {
Timer closingCeremonyTimer = new Timer();
closingCeremonyTimer.schedule(new TimerTask() {
public void run() {
Platform.runLater(new Runnable() {
@Override 
public void run() {
test.addChatItem("Hello World. ");
}
});
chatLoop(test);
}
}, (long) (0.5*1000));
}
}
}

Voici une image de l'émission, remarquez comment le ScrollPane n'a pas défiler vers le bord droit.

JavaFX 2: Fabrication d'un composant ScrollPane faire défiler automatiquement le bord après l'ajout de contenu

Edit:

Je suis venu avec une solution de contournement, mais il est très loin d'être idéale. Ma solution est de lancer un timer qui va utiliser setHvalue() après assez de temps a passé pour la ScrollPane de découvrir la véritable largeur de son contenu. mon addChatItem() méthode ressemble maintenant à ceci:

public void addChatItem(String chatString) {
Label title = new Label(chatString);        
title.setFont(new Font("Verdana", defaultFontSize));
chatBox.getChildren().add(title);
Timer closingCeremonyTimer = new Timer();       
closingCeremonyTimer.schedule(new TimerTask() {
public void run() {
chatBoxScrollPane.setHvalue(chatBoxScrollPane.getHmax());
}
}, (long) 50);
}

Malheureusement, le nombre de 50 dans cette méthode doit être supérieur au temps qu'il prend la ScrollPane de mettre à jour son contenu intérieur de la largeur, et qui semble être loin d'être garanti.

OriginalL'auteur user1298572 | 2013-06-07