8

JavaFX でスケーリング変換を使用しようとしてきましたが、頭を包むことができませんでした。基本的に、複雑なグラフを含むペインがあり、それを再スケーリングできるようにしたいと考えています。スケーリング部分自体は正常に機能しますが、囲んでいるスクロール ペインはグラフに適応しません。

簡単にするために、グラフをラベルに置き換えた短い例を投稿します。

public class TestApp extends Application {
    @Override public void start(final Stage stage) throws Exception {
        final Label label = new Label("Hello World");
        label.getTransforms().setAll(new Scale(0.5, 0.5));

        label.setStyle("-fx-background-color:blue");
        label.setFont(new Font(200));

        final ScrollPane scrollPane = new ScrollPane();
        scrollPane.setContent(label);

        stage.setScene(new Scene(scrollPane));
        stage.setWidth(200);
        stage.setHeight(100);
        stage.show();
    }

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

ラベルは正しくスケーリングされますが、囲んでいるスクロール ペインのバーは、元のサイズのコンポーネントに引き続き対応します。

私はこれまでに試しました:

  • 最小サイズと優先サイズのラベルをいじる
  • ラベルをグループ内にラップします (スクロールバーは一切表示されません)
  • ラベルではなく囲んでいるグループをスケーリングする

私は何が欠けていますか?ScrollPane をコンテンツ ビューに適応させるにはどうすればよいですか?

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

4

2 に答える 2

12

ScrollPane ドキュメントによると、Pane を Group でラップしようとする可能性があるため、ScrollPane は実際のレイアウト バウンドではなく、ビジュアル バウンドによってスクロールされます。

ScrollPane layout calculations are based on the layoutBounds rather than the
boundsInParent (visual bounds) of the scroll node. If an application wants the
scrolling to be based on the visual bounds of the node (for scaled content etc.),
they need to wrap the scroll node in a Group. 
于 2013-07-13T13:18:38.843 に答える
4

JavaFX でのスクロールペインのビューポート、変換、およびレイアウト境界のこの例では、Graphs およびその他のノードの ScrollPane にスケーリングを実装しました 。

コードは私が最初に JavaFX を学習したときに実装されたので、確かにコードはよりきれいになる可能性があり、おそらくこれを達成するためのより簡単な方法があります (たとえば、ScrollPane のドキュメントで提案されているように、スケーリングされたノードのコンテナーとしてグループを使用します)。

私が望んでいた解決策 (ズームインし、ノードが表示されているビューポートよりも大きい場合にのみスクロールバーが表示される) を実現するための鍵の 1 つは、次のコードでした。

// create a container for the viewable node.
final StackPane nodeContainer = new StackPane();
nodeContainer.getChildren().add(node);

// place the container in the scrollpane and adjust the pane's viewports as required.
final ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(nodeContainer);
scrollPane.viewportBoundsProperty().addListener(
  new ChangeListener<Bounds>() {
  @Override public void changed(ObservableValue<? extends Bounds> observableValue, Bounds oldBounds, Bounds newBounds) {
    nodeContainer.setPrefSize(
      Math.max(node.getBoundsInParent().getMaxX(), newBounds.getWidth()),
      Math.max(node.getBoundsInParent().getMaxY(), newBounds.getHeight())
    );
  }
});

...

// adjust the view layout based on the node scalefactor.
final ToggleButton scale = new ToggleButton("Scale");
scale.setOnAction(new EventHandler<ActionEvent>() {
  @Override public void handle(ActionEvent actionEvent) {
    if (scale.isSelected()) {
      node.setScaleX(3); node.setScaleY(3);
    } else {
      node.setScaleX(1); node.setScaleY(1);
    }
    // runlater as we want to size the container after a layout pass has been performed on the scaled node.
    Platform.runLater(new Runnable() { 
      @Override public void run() {
        nodeContainer.setPrefSize(
          Math.max(nodeContainer.getBoundsInParent().getMaxX(), scrollPane.getViewportBounds().getWidth()),
          Math.max(nodeContainer.getBoundsInParent().getMaxY(), scrollPane.getViewportBounds().getHeight())
        );
      }
    });
  }
});
于 2012-09-12T19:45:38.173 に答える