JavaFX - ScrollPane с StackPane - дочерние элементы StackPane не размещаются при изменении viewportBounds - PullRequest
0 голосов
/ 05 июня 2018

Так что основная проблема, которую я имею, - это когда я нажимаю кнопку прокрутки.Изменяется видовой экран области прокрутки, но не дочерние элементы (узел) панели.Я должен либо запросить фокус на панели, либо щелкнуть значок в меню задач, чтобы содержимое Viewport обновилось.Swing делает это автоматически при перемещении полос прокрутки.

Есть ли другой способ заставить эту функциональность работать, как описано выше и с помощью кода?Запрос вызова Focus () мне кажется странным.Кстати: он подсвечивает каждый раз, когда надоедает.

Вот что я получил до сих пор:

public class ScrollPaneTest extends Application {
private ScrollPane scrollPane;
private StackPane stackPane;
private Pane pane;
private Button button;

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

    scrollPane = new ScrollPane();
    stackPane = new StackPane();
    pane = new Pane();
    button = new Button();

    scrollPane.setPrefHeight(400.0);
    scrollPane.setPrefWidth(600.0);

    stackPane.setPrefHeight(1000.0);
    stackPane.setPrefWidth(1000.0);

    pane.setPrefHeight(200.0);
    pane.setPrefWidth(200.0);

    button.setMnemonicParsing(false);
    button.setText("Button");

    pane.getChildren().add(button);
    stackPane.getChildren().add(pane);        

    scrollPane.setContent(stackPane);      

    scrollPane.viewportBoundsProperty().addListener(new ChangeListener() {
        @Override
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {
            Bounds oldViewportBounds = (Bounds) oldValue;
            Bounds newViewportBounds = (Bounds) newValue;       

            double x = newViewportBounds.getMinX() * -1;
            double y = newViewportBounds.getMinY() * -1;

            button.setLayoutX(x);
            button.setLayoutY(y);

            // Working if focus is requested ...
            //pane.requestFocus();
            // ... or when clicked on the application icon in the taskmenu of windows

            // Doesn't work
            //pane.requestLayout();

        }
    });

    VBox vbox = new VBox();
    vbox.setPrefHeight(400.0);
    vbox.setPrefWidth(600.0);

    vbox.getChildren().add(scrollPane);

    Scene scene = new Scene(vbox);
    primaryStage.setScene(scene);
    primaryStage.show();        

}

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

Для иллюстрации:

Кнопка полосы прокрутки не нажата

Нажатие кнопки полосы прокрутки дважды

1 Ответ

0 голосов
/ 06 июня 2018

Спасибо Stackoverflow за эту замечательную статью: Обновление JavaFX ScrollPane viewportBounds on scroll

С этим я смог найти решение, в котором я нуждался.См. Ниже:

public class ScrollPaneTest extends Application {

private ScrollPane scrollPane;
private StackPane stackPane;
private Pane pane;
private Button button;

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

    scrollPane = new ScrollPane();
    stackPane = new StackPane();
    pane = new Pane() {
        @Override
        protected void layoutChildren(){              
            super.layoutChildren();
            // System.out.println("layout children");  
            // more ToDo's if neccessary...
        }
    };

    // so that the Pane can be smaller than (potentionally) other Panes inside of the StackPane        
    pane.setManaged(false);
    // set the dimension of the ScrollPane
    pane.setPrefHeight(400.0);
    pane.setPrefWidth(600.0);        

    button = new Button();
    button.setLayoutX(25);
    button.setLayoutY(25);

    scrollPane.setPrefHeight(400.0);
    scrollPane.setPrefWidth(600.0);

    stackPane.setPrefHeight(1000.0);
    stackPane.setPrefWidth(1000.0);

    button.setMnemonicParsing(false);
    button.setText("Button");

    pane.getChildren().add(button);
    stackPane.getChildren().add(pane);        

    scrollPane.setContent(stackPane);

    scrollPane.hvalueProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
            //System.out.println("observable " + observable + " oldValue " + oldValue + " " + "newValue " + newValue);
            double hmin = scrollPane.getHmin();
            double hmax = scrollPane.getHmax();
            double hvalue = scrollPane.getHvalue();
            double contentWidth = scrollPane.getContent().getLayoutBounds().getWidth();
            double viewportWidth = scrollPane.getViewportBounds().getWidth();

            double hoffset = 
            Math.max(0, contentWidth - viewportWidth) * (hvalue - hmin) / (hmax - hmin);

            pane.setLayoutX(hoffset);
            pane.requestLayout();                
        }
    });        

    scrollPane.vvalueProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
            //System.out.println("observable " + observable + " oldValue " + oldValue + " " + "newValue " + newValue);
            double vmin = scrollPane.getVmin();
            double vmax = scrollPane.getVmax();
            double vvalue = scrollPane.getVvalue();
            double contentHeight = scrollPane.getContent().getLayoutBounds().getHeight();
            double viewportHeight = scrollPane.getViewportBounds().getHeight();

            double voffset = 
            Math.max(0, contentHeight - viewportHeight) * (vvalue - vmin) / (vmax - vmin);

            pane.setLayoutY(voffset);
            pane.requestLayout();
        }
    });

    VBox vbox = new VBox();
    vbox.setPrefHeight(400.0);
    vbox.setPrefWidth(600.0);

    vbox.getChildren().add(scrollPane);

    Scene scene = new Scene(vbox);
    primaryStage.setScene(scene);
    primaryStage.show();        

}

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

К сожалению, я не смог опротестовать решение г-на Джеймса_Д, но я пытаюсь связать оба варианта использования.

Надеюсь, этот поможет и другим.Ура!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...