2015-01-08 53 views
0

目標是顯示一個類似於內容的表格,但在這種情況下,使用2組標籤,即標準垂直標籤和水平標籤,兩者必須能夠滾動並保留標籤隨時都可見。Javafx 8滾動窗格內容標題位置不正確

我以爲我弄明白了,它在一開始就起作用,但越滾越多的橫幅越位,它似乎積累了一些錯誤定位一個很長的路..不知道在這裏,否則我做錯事..

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

}

回答

0

它看起來LIK e你將一個BorderPane放入一個ScrollPane中。我猜這種組合可能無法按預期工作。請注意,ScrollPane是一個控件,而不是像BorderPane那樣的窗格。爲什麼它不起作用可能是關於這些類如何處理其大小調整等的技術細節,並且您可能很難搞清楚它。我會建議嘗試一些其他方法,從描述中不太清楚你想實現什麼。

+0

感謝您的反饋!我想過這個問題,但似乎沒有邏輯,但編程並不總是logic..Will也許嘗試一下另一個窗格這就是問題所在.. – sja

0

爲什麼不考慮開源項目?像fxcontrols enter image description here 上面的屏幕截圖是電子表格視圖,那是你想要的嗎?

+0

沒有什麼,我的需求更像是swing中的scrollpane,列和行標題..我在javafx中做了一個解決方案,但忘了在這裏發佈它,在我編寫的時候沒有那個函數的javafx等價物。 – sja

0

注意:由於一些有線原因,StackExchange coudn't顯示我的整個代碼。無論如何,訪問此處查看完整代碼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); 
     } 

    }