web-dev-qa-db-ja.com

JavaFXでボタンを正しく配置するにはどうすればよいですか?

このウィンドウの「右」(2番目)ボタンを右揃えにするにはどうすればよいですか?

class HelloApp extends Application {
  override def start(primaryStage: Stage): Unit = {
    val root = new FlowPane(Orientation.VERTICAL) {
      setPadding(new Insets(10, 10, 10, 10))
      setVgap(10)
      getChildren.add(new Button("Left"))
      getChildren.add(new Button("Right") { setAlignment(Pos.CENTER_RIGHT) }) // this doesn't seem to be working
    }

    primaryStage.setScene(new Scene(root, 400, 400))
    primaryStage.show()
  }
}

ありがとう

6

サンプルソリューション

左揃えと右揃えのボタンを提供する例を次に示します。

alignment

_import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class HelloApp extends Application {
  public static void main(String[] args) {
    launch(args);
  }

  @Override
  public void start(Stage primaryStage) throws Exception {
    HBox root = new HBox();
    root.setPadding(new Insets(10, 10, 10, 10));

    final Button left = new Button("Left");
    left.setMinSize(Button.USE_PREF_SIZE, Button.USE_PREF_SIZE);
    final Pane spacer = new Pane();
    HBox.setHgrow(spacer, Priority.ALWAYS);
    spacer.setMinSize(10, 1);
    final Button right = new Button("Right");
    right.setMinSize(Button.USE_PREF_SIZE, Button.USE_PREF_SIZE);

    root.getChildren().addAll(left, spacer, right);

    primaryStage.setScene(new Scene(root, 400, 400));
    primaryStage.show();
  }
}
_

このソリューションは、Javaではなく、Scalaコードで提供されました。これは、Scalaでプログラムしないためです。しかし、同等のScalaコード。

説明

HBoxを選んだのは、私にとって、HBoxが、何かを左右に揃えたいという最も一般的な例だったからです。しかし、ここには本当の正誤はありません。AnchorPaneなどの他のレイアウトタイプを使用して目的の結果を達成することも、優れたソリューションを得ることができます。

HBoxで右揃えを実現するには、左揃えのノードと右揃えのノードの間に可変幅の間隔ペインを挿入します。これにより、右揃えのすべてのノードが右にプッシュされます。最小サイズにさまざまな制約を追加して、ボタンのテキスト全体が常に表示されるようにし、ウィンドウを小さくしたときに左右に配置されたノードの間に常に小さなギャップがあるようにしました。

setAlignment()

button.setAlignment() メソッドが機能していないように見える理由は、それが期待どおりに機能しないためです。 setAlignmentは、ボタンが希望の幅を超えて大きくなるときに、ボタン内のテキストを揃えるためのものです。 setAlignmentjavadocを参照してください。

ラベル内に空のスペースがある場合に、ラベル内のテキストとグラフィックをどのように配置するかを指定します。

ボタンのデフォルトの最大幅はその優先幅であるため、button.setMaxWidth(Double.MAX_VALUE)を使用して最大幅を明示的に設定しない限り、ボタンのサイズは大きくなりません。これは、デフォルトでは、ボタンの内部コンテンツを内部に配置するための追加のスペースがボタン内にないため、setAlignmentメソッドは何も実行しないことを意味します。

これをさらに理解するには、以下をお読みください。 ノードのサイズ変更と整列のヒント (強くお勧めします)。

他のペインタイプの位置合わせについて

他にも多数の レイアウトペイン (AnchorPane、GridPaneなど)があり、これらを使用して同様のレイアウトを実現できます。レイアウトペインが異なれば、機能とAPIも異なります。これは、配置などの一般的なレイアウトの問題に対処する方法がそれらの間で異なることを意味します(各レイアウトペインタイプでそれを行う方法を理解するには、APIを参照する必要があります)。

レイアウトペイン内の配置を制御する場合は、上で示したようにスペーサーを使用するか、ノードに追加のペインレベルの制約を設定する必要があります。さまざまなレイアウトタイプに制約を設定する例は、次の方法です(一部は静的です)。

上記は単なる例です。たとえば、 BorderPane のtop、center、またはrightプロパティを設定するなど、ノードを整列させる方法は他にもたくさんあります。

FlowPaneがあなたが達成しようとしていることに本当に良くない理由

FlowPane's Orientation を垂直に設定し、 flowPane.setColumnHalignment(Pos.CENTER_RIGHT) を呼び出すことにより、FlowPane内のノードを右揃えにできます。ただし、その右はFlowPane内のすべてを整列させ、1つを左に、もう1つを右に整列させます。これがあなたがやろうとしていることです。

14
jewelsea

FlowPaneが実際にこれをサポートしているかどうかはわかりません。 GridPaneを使用すると、2つの列を作成し、最初の列を使用してすべてのスペースを消費できます。このようなもの:

    GridPane pneButtons = new GridPane();

    ColumnConstraints col1 = new ColumnConstraints();
    col1.setHgrow(Priority.ALWAYS);
    pneButtons.getColumnConstraints().add(col1);

    Button btnRight = new Button("RIGHT");
    pneButtons.getChildren().add(btnRight);

    GridPane.setColumnIndex(btnRight, 1);
1
Bob Flannigon