2017-01-08 12 views
0

私のアプリケーションでは、VBoxを持つScrollPaneを持っています。各ペインには、VBoxをクリアするボタンから読み込まれた関連項目があり、その子を「結果に戻る」ボタンと共に追加して、前のリストを読み込んでScrollPaneの同じ場所に戻す必要があります。ただし、setVvalue()は動作していないようです。ペインとその子供たちは同じクラスです。JavaFX ScrollPane setVvalue()が意図したとおりに動作しない

package application; 

import java.util.ArrayList; 
import java.util.List; 

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.geometry.Pos; 
import javafx.stage.Stage; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.ScrollPane; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.VBox; 


public class Main extends Application { 

    public VBox resultsBox; 
    public ScrollPane scroll; 
    public List<CustomClass> results = new ArrayList<CustomClass>(); 
    public Button returnToResults; 

    public class CustomClass extends HBox { 
     public List<CustomClass> items; 

     public boolean hasItems() { 
      return items != null && !items.isEmpty(); 
     } 

     public CustomClass(String text, boolean hasItems) { 
      setMinHeight(90); 
      setPrefHeight(90); 
      setMaxHeight(90); 
      setMaxWidth(Double.MAX_VALUE); 
      setAlignment(Pos.CENTER); 
      setStyle("-fx-border-color: red"); 

      Button children = new Button("View Children "+text); 
      children.setDisable(!hasItems); 
      getChildren().add(children); 
      children.setOnAction(e -> { 
       viewChildren(this); 
      }); 

      if(hasItems) { 
       items = new ArrayList<CustomClass>(); 
       for(int i=0; i<10; i++) { 
        items.add(new CustomClass(text+"."+i, false)); 
       } 
      } 
     } 
    } 

    public double vValue = 0.0; 

    public void viewChildren(CustomClass cc) { 
     Platform.runLater(() -> { 
      vValue = scroll.getVvalue(); 
      System.out.println("0. "+vValue); 
      resultsBox.getChildren().clear(); 
      resultsBox.getChildren().addAll(cc.items); 
      returnToResults.setDisable(false); 
     }); 
    } 

    public void returnToResults() { 
     Platform.runLater(() -> { 
      resultsBox.getChildren().clear(); 
      resultsBox.getChildren().addAll(results); 
      System.out.println("1. "+vValue+" "+scroll.getVvalue()); 
      scroll.setVvalue(vValue); 
      System.out.println("2. "+vValue+" -> "+scroll.getVvalue()); // Sets correctly. 
      returnToResults.setDisable(true); 
     }); 
    } 

    public void start(Stage stage) throws Exception { 

     resultsBox = new VBox(5); 
     resultsBox.setFillWidth(true); 
     resultsBox.setAlignment(Pos.TOP_CENTER); 

     scroll = new ScrollPane(resultsBox); 
     scroll.setMaxWidth(Double.MAX_VALUE); 
     scroll.setFitToWidth(true); 

     for(int i=0; i<100; i++) { 
      results.add(new CustomClass("#"+i, true)); 
     } 

     resultsBox.getChildren().addAll(results); 

     returnToResults = new Button("Return to Results"); 
     returnToResults.setStyle("-fx-base: green"); 
     returnToResults.setDisable(true); 
     returnToResults.setOnAction(e -> { 
      returnToResults(); 
     }); 

     BorderPane root = new BorderPane(); 
     root.setCenter(scroll); 
     root.setBottom(returnToResults); 

     Scene scene = new Scene(root,400,400); 
     stage.setScene(scene); 
     stage.show(); 
    } 

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

setVvalue()が動作し、それをプリントアウト時に元の値に戻すのScrollPaneを変更しますが、ScrollPaneの自体はどこにでも行くと一番上にとどまるものではありません。ノードを削除してVBoxに追加する必要がありますか? Vvalueを設定するときにScrollPaneが動かないのはなぜですか?

答えて

1

scroll.setVvalue(vValue)と呼んだとき、その内容が変更されているため、スクロールペインはレイアウトを実行していないため、コンテンツのサイズを「再測定」していません。したがって、スクロールバー「サム」は、以前のレイアウトの文脈でvvalueを解釈することによって再配置されています。これを修正するには

public void returnToResults() { 
    Platform.runLater(() -> { 
     vbox.getChildren.clear(); 
     vbox.getChildren.addAll(results); 

     scroll.layout(); 

     scroll.setVvalue(vValue); 
     returnToResults.setDisable(true); 
    }); 
} 

脇に:これらのメソッドはバックグラウンドスレッドから呼び出されていますか?なぜ内容がPlatform.runLater(...)に包まれていますか?

+0

問題を再現するための例を追加しましたが、これで問題は解決しました。ありがとう。まあ、私はそれが必要だと思ったが、 'Platform.runLater'を削除したので何もハングしないので削除した。長い間Swingに慣れていれば、JavaFXにはまったく新しいものです。 –

+0

@Matthewこれは、あなたがやることに非常に敏感です。それぞれの独自のスクロールペインにラップされた異なる 'VBox'を用意し、スクロールペインを完全に置き換える方が、 vboxを開き、自分でスクロール位置を管理します。 –

+0

私は実際に投稿した後にそれをやろうと考えていましたが、後で試してみる必要があります。 –

関連する問題