简体   繁体   中英

How to align a button right in JavaFX?

How can I make the "right" (second) button on this Window be right aligned?

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()
  }
}

Thanks

Sample Solution

Here is an example which provides a left aligned and right aligned button:

对准

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();
  }
}

This solution was provided in Java code rather than Scala as I don't program in Scala. But it should be easily translatable to equivalent Scala code.

Explanation

I chose a HBox because, for me, that has been the most common instance of wishing to have something left and right aligned. But there is no real right or wrong here and using other layout types such as AnchorPane to achieve the desired result can also get you a good solution.

To accomplish the right alignment with a HBox I insert a variable width spacing pane between the left aligned nodes and the right aligned nodes, which pushes all the right aligned nodes to the right. I added various additional constraints on min sizes so that the full button text is always visible and so that there is always a small gap between the left and right aligned nodes when you make the window small.

On setAlignment()

The reason why the button.setAlignment() method didn't appear to work for you is that it doesn't do what you think it will do. setAlignment is for aligning the text within the button as the button grows past its preferred width. See the setAlignment javadoc:

Specifies how the text and graphic within the Labeled should be aligned when there is empty space within the Labeled.

The default max width for a button is its preferred width, so the button won't grow in size unless you explicitly set its max width using button.setMaxWidth(Double.MAX_VALUE) . This means, by default, the setAlignment method will do nothing at all, as there will be no additional space available within the button for the button's internal content to be aligned inside.

To further understand this, read: Tips for Sizing and Aligning Nodes (highly recommended).

On aligning for other Pane Types

There are numerous other layout panes (such as AnchorPane, GridPane, etc), which could be used to accomplish similar layout. The different layout panes have different functionality and APIs. This means that the way you deal with common layout issues such as alignment differs between them (you need to consult their API to understand how to do it for each layout pane type).

If you want to control alignment within a layout pane, you have to use either a spacer as I demonstrated above, or set additional pane level constraints on the node. Examples of setting constraints on various layout types are the following methods (some of which are static):

The above are just examples, there are many more ways to align nodes, for example by setting the top, center or right properties of a BorderPane .

Why FlowPane isn't really good for what you are trying to accomplish

You can right align nodes in a FlowPane by setting the FlowPane's Orientation to vertical and invoking flowPane.setColumnHalignment(Pos.CENTER_RIGHT) . However, that right aligns everything in the FlowPane, not one thing to the left, and another thing to the right, which is what you are trying to do.

I'm not sure FlowPane really supports this. Using GridPane you can create two columns and consume all the space using the first column. Something like this:

    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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM