4

使用 JavaFX 2,我有一个ScrollPane包含 a HBoxof Labels 的基本示例。我希望能够将 a 添加LabelHBox, 并同时滚动到 the 的右边缘,ScrollPane以便新添加Label的内容可见。我当前的方法使用setHvalue()来设置滚动位置并getHmax()获得允许的最大滚动距离。

问题是,当我使用 设置滚动位置时getHmax(),就好像刚刚添加Label的不是在ScrollPanel的滚动宽度中计算的一样。有没有办法在尝试之前更新这个内部宽度setHvalue

请参阅这个显示问题的简单示例代码。

特别是,请注意该addChatItem(String item)方法,其中包含滚动到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));
            }
        }
    }

这是一个问题的图像,注意ScrollPane它没有滚动到右边缘。

图片

编辑:

我想出了一个解决方法,但它远非理想。我的解决方案是启动一个计时器,该计时器将setHvalue()在经过足够的时间后用于ScrollPane发现其内容的真实宽度。我的addChatItem()方法现在看起来像这样:

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);
}

不幸的是,该方法中的数字 50 需要大于ScrollPane更新其内部内容宽度所需的时间,这似乎远不能保证。

4

2 回答 2

4

您可以绑定到 Hbox widthproperty chnages 。

示例代码:

   //in start method add this code
    DoubleProperty wProperty = new SimpleDoubleProperty();
    wProperty.bind(chatBox.widthProperty()); // bind to Hbox width chnages
    wProperty.addListener(new ChangeListener() {
        @Override
        public void changed(ObservableValue ov, Object t, Object t1) {
           //when ever Hbox width chnages set ScrollPane Hvalue
         chatBoxScrollPane.setHvalue(chatBoxScrollPane.getHmax()); 
        }
    }) ;

 // remove below line from your addChatItem() method   
 chatBoxScrollPane.setHvalue(chatBoxScrollPane.getHmax());

结果:是的,添加编号很有趣;)

在此处输入图像描述

于 2013-06-09T03:21:30.223 回答
1

在我的情况下,我需要在一个名为 msgs 的 ScrollPane 中包含一个名为标签的 HBox,这是我处理自动滚动的方式。

注意:添加到标签 HBox 的 changeListener 是通过 Lambda 语法实现的(在 JDK8 中可用)

labels.heightProperty().addListener((observable, oldVal, newVal) ->{
        msgs.setVvalue(((Double) newVal).doubleValue());
    });
于 2015-07-08T01:52:55.427 回答