Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 768
devoured elysium Avatar asked Aug 29 '16 20:08

devoured elysium


People also ask

Do something when button is pressed JavaFX?

To make a button do something in JavaFX you need to define the executable code usually by using a convenience method like setOnAction() . Then, when the button is clicked, JavaFX does the heavy lifting of fetching that pre-defined code, and executing it on the JavaFX Application thread.

How do you align buttons in flutter?

How to create Flutter Align Widget. To create align widget you have to just wrap the child widget with the Align() class. For example, I want a TextButton to align to the center then I will wrap the button widget with the Align().


2 Answers

Sample Solution

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

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

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

  • hBox.setAlignment(Pos) (align all nodes within the VBox)
  • AnchorPane.setRightAnchor(Node, Double) (anchor a given node in an AnchorPane).
  • stackPane.setAlignment(Pos) (align all nodes within a StackPane)
  • StackPane.setAlignment(Node, Pos) (align a specific node within a StackPane)

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.

like image 198
jewelsea Avatar answered Nov 14 '22 21:11

jewelsea


enter image description here

Although Jewelsea's answer is complete and correct, it's a java-based solution and I would like to provide a fxml-based one that might be helpful for some developers. It is a fxml port of Jewelsea's answer.

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>


<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
   <padding>
      <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
   </padding>
   <children>
      <Button mnemonicParsing="false" text="Left" />
      <Pane HBox.hgrow="ALWAYS" />
      <Button mnemonicParsing="false" text="Right" />
   </children>
</HBox>
like image 37
Elyas Hadizadeh Avatar answered Nov 14 '22 23:11

Elyas Hadizadeh