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 Label
s. 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.
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
Vous devez vous connecter pour publier un commentaire.
vous pouvez lier à Hbox widthproperty chnages .
Exemple De Code :
et
Résultat :oui ajoutée de numérotation pour le fun 😉
OriginalL'auteur invariant
Dans mon cas, j'avais besoin de joindre une HBox appelé étiquettes à l'intérieur d'un composant ScrollPane appelé msgs et voici la façon dont j'ai géré de défilement automatique.
REMARQUE: Le changeListener ajouté des étiquettes HBox est mis en œuvre par Lambda syntaxe(disponible dans le JDK8)
OriginalL'auteur Pedram Esmaeeli