Javafx 8 Scrollpane内容标头未正确定位

时间:2015-01-08 23:31:42

标签: javafx-8 scrollpane

目标是显示一个像内容一样的表格,但在这种情况下有两组标签,正常的垂直标签和水平标签,两者必须能够滚动并始终保持标签可见。

我以为我弄明白了,它起初工作但滚动的越多,横幅越位,它似乎在定位很长的路上累积了一些错误..不知道在这里,或者如果我做错了什么..

在Win7上运行javafx 8.25

我的代码:

package com.hdk.tests;

import javafx.application.Application;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;



public class TestScrollPaneBanners extends Application {

boolean photoYInited = false;
boolean photoHInited = false;

ImageView photoY ;
ImageView photoX;
@Override
public void start(Stage primaryStage) {
    ScrollPane scrollPane = new ScrollPane();
    scrollPane.setPrefSize(400, 400);
    scrollPane.setMaxSize(400, 400);

    BorderPane panel = new BorderPane();
    panel.setPrefSize(600, 600);
    HBox horizontalStripp= new HBox();
     horizontalStripp.setPrefHeight(35);
     horizontalStripp.setMaxWidth(Double.MAX_VALUE);
    horizontalStripp.getChildren().add(new Label("Vertical"));
    HBox header = new HBox();
    HBox.setHgrow(header, Priority.ALWAYS);
     header.setMaxWidth(Double.MAX_VALUE);
    header.setStyle("-fx-background-color:red;");
    Label tl = new Label("This is the top label.....");
    tl.setMaxWidth(Double.MAX_VALUE);
    header.getChildren().add(tl);
    horizontalStripp.getChildren().add(header);


    panel.setTop(horizontalStripp);
    scrollPane.setContent(panel);
    VBox verticalStripp = new VBox();
    verticalStripp.setStyle("-fx-background-color:blue;");
    verticalStripp.getChildren().add(new Label("Vertical"));
    verticalStripp.getChildren().add(new Label("Vertical"));
    verticalStripp.getChildren().add(new Label("Vertical"));
    verticalStripp.getChildren().add(new Label("Vertical"));
    verticalStripp.getChildren().add(new Label("Vertical"));
    verticalStripp.getChildren().add(new Label("Vertical"));
    panel.setLeft(verticalStripp);



    Label infoX = new Label();
    Label infoY = new Label();
    scrollPane.vvalueProperty().addListener( new InvalidationListener(){

        @Override
        public void invalidated(Observable observable) {

            double visibleHeight = panel.getHeight()-scrollPane.getPrefHeight();             
            double posX = visibleHeight*scrollPane.getVvalue();
            boolean visible = posX<header.getHeight();
              String tx ="VisibleY ="+ visible+ " V ="+scrollPane.getVvalue() ;               
            if(!visible){
                //take photo
                if(!photoYInited){
                    //init image
                      WritableImage sns = header.snapshot(new SnapshotParameters(), null);
                        photoY = new ImageView(sns);
                        photoYInited = true;
                        panel.getChildren().add(photoY);
                }
               //position image in borderpane               
                   photoY.setLayoutY(posX);              
                   photoY.setLayoutX(header.getLayoutX());
                   tx+=" Cx "+header.getLayoutX()+" Cy "+posX;
            }else{
                //its visible
                //remove photo if present
                if(photoYInited){
                    panel.getChildren().remove(photoY);
                    photoYInited = false;
                }
            }
             infoY.setText(tx);

        }

    });
    scrollPane.hvalueProperty().addListener( new InvalidationListener(){

        @Override
        public void invalidated(Observable observable) {      

            double visibleWidth = panel.getWidth()-scrollPane.getWidth();

            double posX = visibleWidth*scrollPane.getHvalue();
            boolean visible = posX < verticalStripp.getWidth();
              String tx ="VisibleX ="+ visible+ " H ="+scrollPane.getHvalue() ;

            if(!visible){
                //take photo
                if(!photoHInited){
                    //init image
                      WritableImage sns = verticalStripp.snapshot(new SnapshotParameters(), null);
                        photoX = new ImageView(sns);
                        photoHInited = true;
                        panel.getChildren().add(photoX);
                }               
                   photoX.setLayoutX(posX);
                   photoX.setLayoutY(verticalStripp.getLayoutY());                    
                   tx+=" Cx "+posX+" Cy "+verticalStripp.getLayoutY();
            }else{
                //its visible
                //remove photo if present
                if(photoHInited){
                    panel.getChildren().remove(photoX);
                    photoHInited = false;
                }
            }
             infoX.setText(tx);

        }

    });       
    VBox all = new VBox();
    all.getChildren().add(scrollPane);
    all.getChildren().add(infoX);
    all.getChildren().add(infoY);     

    Scene scene = new Scene(all, 400, 500);

    primaryStage.setTitle("Hello Banner!");
    primaryStage.setScene(scene);
    primaryStage.show();
}

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

}

3 个答案:

答案 0 :(得分:0)

看起来你正在将一个BorderPane放在ScrollPane中。我猜这个组合可能无法按预期工作。请注意,ScrollPane是一个Control而不是像BorderPane那样的Pane。为什么它不起作用可能是关于这些类如何处理它们的大小调整等的技术细节,你可能很难搞清楚它。我建议尝试其他一些方法,从你的描述中你不清楚你想要实现的目标。

答案 1 :(得分:0)

为什么不考虑开源项目?像fxcontrols enter image description here 上面的屏幕截图是电子表格视图,这是你想要的吗?

答案 2 :(得分:0)

注意:由于某些有线原因,StackExchange coudn不显示我的整个代码。无论如何,访问此处查看完整代码http://pastebin.com/87rsNyAA

添加BorderPane。在BorderPane的中心,添加ScrollPane。在BorderPane的顶部和左侧,添加两个“水平和垂直”窗格规则。现在,从ScrollPane的HValue和VValue属性中,获取那些HValue和VValue,并相应地更改顶部或左侧的水平/垂直窗格位置。

Application Preview



    import javafx.application.Application;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.ScrollPane;
    import javafx.scene.effect.DropShadow;
    import javafx.scene.layout.Background;
    import javafx.scene.layout.BackgroundFill;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.CornerRadii;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    import javafx.stage.Screen;
    import javafx.scene.text.Text;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.scene.shape.Line;

    /**
     *
     * @author Zunayed Hassan
     */
    public class ScrollPaneWithRuler extends Application {

        final static double DPI = Screen.getPrimary().getDpi();
        final static double THICKNESS_OF_RULER = DPI * 0.5;
        final static int WINDOW_WIDTH = 1024;
        final static int WINDOW_HEIGHT = 768;
        final static int CONTENT_WIDTH = 2500;
        final static int CONTENT_HEIGHT = 2500;

        @Override
        public void start(Stage primaryStage) {        
            BorderPane root = new BorderPane();

            // Inside of the scroll pane
            ScrollPane scrollPane = new ScrollPane();
            scrollPane.setStyle("-fx-background: gray;");
            scrollPane.setPrefViewportWidth(800);
            scrollPane.setPrefViewportHeight(600);
            root.setCenter(scrollPane);

            Pane artBoard = new Pane();
            artBoard.setPrefSize(CONTENT_WIDTH, CONTENT_HEIGHT);
            scrollPane.setContent(artBoard);

            Pane canvas = new Pane();
            canvas.setBackground(new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)));
            canvas.setPrefSize(600, 500);
            canvas.setEffect(new DropShadow(5, 1, 1, Color.BLACK));
            canvas.setTranslateX(50);
            canvas.setTranslateY(50);
            artBoard.getChildren().add(canvas);

            // ----------------------------------------------------------------


            // Row Header
            Pane verticalRulePane = new Pane();
            verticalRulePane.setBackground(new Background(new BackgroundFill(Color.web("#F4F4F4"), CornerRadii.EMPTY, Insets.EMPTY)));
            root.setLeft(verticalRulePane);

            Pane vRule = new Pane();
            vRule.setPrefWidth(THICKNESS_OF_RULER);
            verticalRulePane.getChildren().add(vRule);

            for (int i = 0; i  changeListenerForHorizontalScroll = new ChangeListener() {
                @Override
                public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                    hRule.setTranslateX(-((CONTENT_WIDTH - WINDOW_WIDTH) * scrollPane.getHvalue()));
                }
            };

            scrollPane.hvalueProperty().addListener(changeListenerForHorizontalScroll);

            ChangeListener changeListenerForVerticalScroll = new ChangeListener() {
                @Override
                public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                    vRule.setTranslateY(-((CONTENT_HEIGHT - WINDOW_HEIGHT) * scrollPane.getVvalue()));
                }
            };

            scrollPane.vvalueProperty().addListener(changeListenerForVerticalScroll);

            // ----------------------------------------------------------------

            Scene scene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT);

            primaryStage.setTitle("ScrollPane with Ruler");
            primaryStage.setScene(scene);
            primaryStage.show();
        }

        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }

    }