2016-10-10 10 views
0

私はJavaFXで画像ビューアを作成しています。 私の現在の問題は以下の通りです:JavaFX - 中央のImageViewを調整する

ImageViewerはそのParentノードにrecentered得るもの(ユーザが「前」または「次へ」をクリックしたときに)新しいImageImageViewerに表示されるたびに、この場合はHBoxです。私はsetTranslateメソッドを使用していますが、それは正常に動作していますが、新しいImageがロードされるたびにImageViewが異なる位置を取っているため、正常に動作しません。

私はImageViewを更新したりするために、このメソッドを使用しています:

public void adjustImageViewBounds() 
{ 
    double windowWidth = MAIN.getWindow().getScene().getWidth(); 
    double windowHeight = MAIN.getWindow().getScene().getHeight(); 
    double imageWidth = GUI.getImageView().getImage().getWidth(); 
    double imageHeight = GUI.getImageView().getImage().getHeight(); 
    boolean isFullScreen = MAIN.getWindow().isFullScreen(); 

    GUI.getImageView().setFitWidth(windowWidth - 50 > imageWidth ? imageWidth : windowWidth - 50); 

    // 50 ~ 25px space on the left and right side 

    boolean scrollBarVisible = false; 
    Set<Node> nodes = GUI.getImageViewScrollPane().lookupAll(".scroll-bar"); 
    for(Node currentNode : nodes) 
    { 
     if(currentNode instanceof ScrollBar) 
      if(((ScrollBar) currentNode).getOrientation() == Orientation.VERTICAL) 
       if(currentNode.isVisible()) 
        scrollBarVisible = true;  
    } 
    if(!scrollBarVisible && !isFullScreen) 
    { 
     // 80 ~ GUI.getInfoBoxAndImageView().getLayoutY() -> The Y position within the window of my whole ImageView container (HBox) 
     // 65 ~ GUI.getLowerControl().getHeight() -> The height of the controlbar under the ImageView 
     double newTranslateY = (windowHeight/2) - 80 - (VISIBLE_IMAGE_HEIGHT.divide(2).doubleValue()); 
     GUI.getInfoBoxAndImageView().setTranslateY(newTranslateY >= 0 && (newTranslateY + 80 + VISIBLE_IMAGE_HEIGHT.doubleValue()) < (windowHeight - 65) ? newTranslateY : 0); 
    } 
    else if(scrollBarVisible) 
    { 
     GUI.getInfoBoxAndImageView().setTranslateY(0); 
    } 
    else if(isFullScreen) 
    { 
     double newTranslateY = (windowHeight/2) - 80 - (VISIBLE_IMAGE_HEIGHT.divide(2).doubleValue()); 
     GUI.getInfoBoxAndImageView().setTranslateY(newTranslateY >= 0 && (newTranslateY + 80 + VISIBLE_IMAGE_HEIGHT.doubleValue()) < (windowHeight - 65) ? newTranslateY : 0); 
    } 
} 

の方法の限りImageが読み込まれた後、私はそれを呼び出すが、私は後にそれを呼んでいるとき、それは動作しませんとして働い新しいImageを設定してください。私はListeners別のを使用しようとしてきた

public void nextClicked() 
    { 
     if(PICTURE_INDEX < picturePaths.size() - 1) 
     { 
      String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString(); 
      GUI.getImageView().setImage(new Image(path)); 
      adjustImageViewBounds(); 
      PICTURE_INDEX += 1; 
     } 
    } 

この問題を解決するには:

GUI.getImageViewer().imageProperty().addListener(newImage -> 
{ 
    while(newImage.getProgress() < 1.0) 
    { 
     //Do nothing until the Image is completely loaded 
    } 
    adjustImageViewBounds(); 
    System.out.println("End reached"); 
}); 

端が実際に達したが、この方法はdidnのたここ は新しいImageが設定されている場合の例です。 ImageViewの位置に影響しませんか? も機能していない:

public void nextClicked() 
{ 
    if(PICTURE_INDEX < picturePaths.size() - 1) 
    { 
     String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString(); 
     Image newImage = new Image(path); 
     newImage.progressProperty().addListener((obs, oldV, newV) -> 
     { 
     if(newV.doubleValue() == 1.0) 
      adjustImageViewBounds(); 
     }); 
     GUI.getImageView().setImage(newImage); 
     PICTURE_INDEX += 1; 
    } 
} 

楽しみのためだけに私はこれを試してみました、それが働いていたが、それは当然の合理的な解決策ではありません。すべてが混乱の情報を要約すると

GUI.getImageView().setOnMouseClicked(event -> adjustImageViewBounds()); 

: 私は私のImageViewにしたいですadjustImageViewBounds()の方法で書き直してください。 RecenterはSceneの中にXYのいずれかの位置に自分のImageViewを配置することを意味します。

ご協力いただきありがとうございます。

+0

これはあまりにも多くの作業をやっているようです。構造は何ですか? HBox内のScrollPane内のImageView?そして、画像の自然なサイズが利用可能なスペースよりも大きい場合、画像はその自然のサイズを取り、スクロール可能でなければならないという要件がありますか? –

+0

おそらくJames_D、おそらく。私は基本的なJavaを使って1年間プログラミングをしています。私はそれほど経験はありません。私は今JavaFXを約6ヶ月学んでいます。私のコードに関するヒントをありがとう! 構造は次のとおりです:ImageViewとHBoxのVBoxとScrollPaneのHBox – Rouman

+0

そしてImageはシーンの幅と高さの幅と高さを取ります。 preserveRatioはtrueに設定されます。 – Rouman

答えて

1

setTranslateY(...)を使用して親が決定する位置からImageViewを移動する代わりに、最初の場所に配置する親を選択して構成するほうがよいでしょう。例えば、HBoxVBoxは両方とも、親内の子ノードの全体的な位置合わせを決定する方法を有する。最も一般的な(すなわちフレキシブルな)予め定義されたレイアウトは、GridPaneであり、子ノードはグリッド内に配置され、グリッド内の複数のセルに及ぶことができる。グリッド内のさまざまな列と行の幅と高さが異なる場合があります。割り当てられたセルのノードの優先サイズよりも大きい場合、子ノードの動作を設定できます。

いくつかの便利なリンク:

すべてのレイアウトペインの概要はtutorialに与えられています。若干古くて便利ですが、全体的なレイアウトの仕組みはparleys.com(登録が必要です)でご覧いただけます。

関連する問題