2016-11-15 14 views
2

동일한 크기의 2 차원 배열에서 데이터를 나타내는 균일 한 크기의 사각형 20x20 GridPaneScrollPane에 배치하여 주변에서 사용할 수 있도록했습니다. GridPane의 너비와 높이 (픽셀)는 모두 ScrollPane의 각 치수보다 훨씬 큽니다.ScrollPane의 중심 GridPane 사각형 뷰포트

제 문제는 ScrollPane의 뷰포트를 지정된 좌표 집합에있는 GridPane 사각형에 센터링하는 기능적 방법을 만들 수 없었습니다. 내가 사용하려고 시도 된 scrollPane.setHvalue(double)scrollPane.setVvalue(double)

나의 이해는 그들에 전달 된 double 값이 스크롤로를 설정하는 축의 비율 것입니다.

private void centerViewOn(double x, double y){ 
    scrollPane.setHvalue(x/grid.getDimensionX()); 
    scrollPane.setVvalue(y/grid.getDimensionY()); 
} 

grid는 클래스의 인스턴스입니다 : 그 가정 코드를 작성할 때, 그것은 광장도 뷰포트의 아무 곳없는 때로는 의도 된 광장에보기를 중앙에 실패 이 질문과의 관련성은 그리드의 크기이며, double xdouble y은 가운데 맞춤을 위해 지정된 사각형의 GridPane에서 x, y 좌표입니다.

내가 뭘 잘못하고 있고, 어떻게 해결할 수 있습니까?

편집 : James_D의 제안에 따라 , 나는 내가, 최소를 완료하고 검증 가능한 예제로 만든 것을 포함하고 있습니다 :

private ScrollPane scrollPane; 
private GridPane gridPane; 
private double dimensionX; 
private double dimensionY; 

@Override 
public void start(Stage primaryStage) { 
    scrollPane = new ScrollPane(); 
    gridPane = new GridPane(); 
    dimensionX = 20; 
    dimensionY = 20; 

    Pane temp; 
    for(int x = 0; x < dimensionX; ++x){ 
     for(int y = 0; y < dimensionY; ++y){ 
      temp = new Pane(); 
      temp.setPrefSize(100, 100); 
      temp.setOnMouseClicked(e -> { 
       centerViewOn(GridPane.getColumnIndex((Pane)e.getSource()), GridPane.getRowIndex((Pane)e.getSource())); 
       ((Pane)e.getSource()).setStyle("-fx-background-color: blue"); 
      }); 
      gridPane.add(temp, x, y); 
     } 
    } 

    gridPane.setGridLinesVisible(true); 
    scrollPane.setContent(gridPane); 

    primaryStage.setScene(new Scene(scrollPane)); 
    primaryStage.show(); 
} 

private void centerViewOn(double x, double y){ 
    double viewportWidth = scrollPane.getViewportBounds().getWidth(); 
    double maxHscrollPixels = gridPane.getWidth() - viewportWidth; 
    double hscrollPixels = viewportWidth/2 - (x + 0.5) * dimensionX/20; 
    scrollPane.setHvalue(hscrollPixels/maxHscrollPixels); 

    double viewportHeight = scrollPane.getViewportBounds().getHeight(); 
    double maxVscrollPixels = gridPane.getHeight() - viewportHeight; 
    double vscrollPixels = viewportHeight/2 - (y + 0.5) * dimensionY/20; 
    scrollPane.setVvalue(vscrollPixels/maxVscrollPixels); 
} 
+0

그래서, 당신은 그들이 스크롤을 중지 할 때'ScrollPane'가'grid'에서보기를 가운데에 맞출 :

여기에 완벽한 예입니다? –

답변

3

스크롤 구획의 수평 스크롤 값은 scrollPane.getHmin()scrollPane.getHmax()에 따라 다릅니다. 그것들은 임의의 단위이며 픽셀 단위로 스크롤 된 양은 범위에서 선형으로 보간됩니다.

픽셀 단위로 표시 할 수있는 수평 스크롤의 크기는 0에서부터 (격자 팬 너비 - 스크롤 패널 뷰포트 너비)입니다.

그래서 당신이

(hvalue - hmin)/(hmax - hmin) = scrollPixels/(gridPaneWidth - viewportWidth) 

등 일부 대수 후 각 열은 같은 폭이며, dimensionX 열이있는 가정

hvalue = hmin + (hmax - hmin) * scrollPixels/(gridPaneWidth - viewportWidth) 

얻을 수 있고, x 열은 전체 폭 x * gridPaneWidth/dimensionX 픽셀이있을 것이다 . 셀의 가운데로 스크롤하려면 다른 반쪽 셀을 추가하고 셀 중심이 뷰포트의 중심에 있도록하려면 viewportWidth/2을 뺍니다. 따라서 당신은 다음과 같습니다 :

hscrollPixels = (x + 0.5) * gridPane.getWidth()/dimensionX - viewportWidth/2 

수직 스크롤은 정확히 유사합니다. hminhmax에 대한

기본 값은 각각 01이다, 그래서 당신이 변경되지 않는 가정하면 당신은 일을 조금 단순화 할 수 있습니다.

그래서 난 당신이 모든 세포가 중앙으로 스크롤 할 수

private void centerViewOn(double x, double y){ 
    double viewportWidth = scrollPane.getViewportBounds().getWidth(); 
    double maxHscrollPixels = gridPane.getWidth() - viewportWidth; 
    double hscrollPixels = (x + 0.5) * gridPane.getWidth()/dimensionX - viewportWidth/2; 
    scrollPane.setHvalue(hscrollPixels/maxHscrollPixels); 

    double viewportHeight = scrollPane.getViewportBounds().getHeight(); 
    double maxVscrollPixels = gridPane.getHeight() - viewportHeight; 
    double vscrollPixels = (y + 0.5) * gridPane.getHeight()/dimensionY - viewportHeight/2; 
    scrollPane.setVvalue(vscrollPixels/maxVscrollPixels); 
} 

참고로 끝날 생각한다 : 그들은 가장자리에 너무 가까이있는 경우, 그들이 중심에 가능한 한 가깝게 스크롤됩니다 스크롤 창은 빈 공간을 허용하지 않습니다 (내용이 뷰포트보다 작지 않은 경우).

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.ScrollPane; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.Pane; 
import javafx.stage.Stage; 

public class ScrollToCenter extends Application { 

    private ScrollPane scrollPane; 
    private GridPane gridPane; 
    private double dimensionX; 
    private double dimensionY; 

    @Override 
    public void start(Stage primaryStage) { 
     scrollPane = new ScrollPane(); 
     gridPane = new GridPane(); 
     dimensionX = 20; 
     dimensionY = 20; 

     for(int x = 0; x < dimensionX; ++x){ 
      for(int y = 0; y < dimensionY; ++y){ 
       Pane temp = new Pane(); 
       temp.setPrefSize(100, 100); 
       temp.setOnMouseClicked(e -> { 
        centerViewOn(GridPane.getColumnIndex(temp), GridPane.getRowIndex(temp)); 
        temp.setStyle("-fx-background-color: blue"); 
       }); 
       gridPane.add(temp, x, y); 
      } 
     } 

     gridPane.setGridLinesVisible(true); 
     scrollPane.setContent(gridPane); 

     primaryStage.setScene(new Scene(scrollPane)); 
     primaryStage.show(); 
    } 

    private void centerViewOn(double x, double y){ 
     double viewportWidth = scrollPane.getViewportBounds().getWidth(); 
     double maxHscrollPixels = gridPane.getWidth() - viewportWidth; 
     double hscrollPixels = (x + 0.5) * gridPane.getWidth()/dimensionX - viewportWidth/2; 
     scrollPane.setHvalue(hscrollPixels/maxHscrollPixels); 

     double viewportHeight = scrollPane.getViewportBounds().getHeight(); 
     double maxVscrollPixels = gridPane.getHeight() - viewportHeight; 
     double vscrollPixels = (y + 0.5) * gridPane.getHeight()/dimensionY - viewportHeight/2; 
     scrollPane.setVvalue(vscrollPixels/maxVscrollPixels); 
    } 

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

이것이 도움이되었지만 궁극적으로는 효과가 없었습니다. 나는 이것이'grid.getDimensionX()'를 설명하는 일이 좋지 않았기 때문이라고 생각한다. 명확하게하기 위해이 메서드는 그리드의 열 수를 반환합니다.이 예제에서는 20입니다. (그것은 결국 격자의 크기를 조절하는 기능을 구현할 것이기 때문에 하드 코드 된 숫자가 아닌 메서드입니다. 그래서 어떤 행과 열의 격자에서도 작동하는 솔루션을 찾고 있습니다) – narf0708

+0

@ narf0708 아마도 가장 좋은 방법 일 것입니다 [MCVE]를 만들고 질문을 편집하여 포함 시키십시오. –

+0

'hmin'과'hmax'를 기본값으로 남겨두고 있기 때문에, 올바르게 읽으면 마지막 줄은'scrollPane.setHvalue (hscrollPixels/maxHscrollPixels); '로 단순화되어야합니다. 또한 나는 당신의 번호 중 일부가 어디서 오는지 혼란 스러워요. 'viewportWidth/2 - (x + 0.5)'에서 2와 0.5의 목적은 무엇입니까? – narf0708