简体   繁体   中英

Reusable constants for FXML layouts?

This is somewhat a follow up to my previous question . Somehow, I got the solution for my question from here , but it never really answered my question for some reasons, which led me to ask this question.

Here's the reason why:

  • I found out that by using the FXMLLoader.namespace , the mapped values are only accessible for the layout (FXML file) which the FXMLLoader is being loaded. This doesn't met the desire of having reusable constants for other FXML files though.
  • Additionally, since these constants are defined in a Java code, it is considered an error by the IDE when used because they are not directly defined within the FXML file, which then becomes hard to track down other exceptional errors.

So the question now is, how to make constants reusable for FXML layouts?

Like in Android, a Color resource for example:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <color name="white">#FFFFFF</color>
</resources>

Can be applied to an XML layout's attribute:

android:textColor="@color/white"

Is there any other possible way in JavaFX? Thanks for all answer.

The closest you get is CSS via stylesheet.

Constants.css

* {
    -my-color: #FFFFFF;
    -my-width: 300;
    -my-height: 400;
}

Then you can use this anywhere via CSS. Bad news is you have to add that Constants.css in all the places you need to apply this.

In code:

pane.setStyle("-fx-background-color: -my-color;");

In FXML:

<Pane style="-fx-background-color: -my-color;" .... />

In another specific CSS file:

.my-pane {
    -fx-background-color: -my-color;
}

So I came up with a solution and thought of answering my own question. This is not the best, but I hope it'll be useful in the future.

This is pretty simple, we can define a getter method for each constant fields, in this case, we can easily access their value from FXML using Expression Binding . Here's an example:

Theme.class

package styles;

import javafx.scene.paint.Color;

public final class Theme {

  /** Constant field; use Theme.BASE_COLOR */
  public static final Color BASE_COLOR = Color.TEAL;

  /** Getter method for FXML; use ${theme.baseColor} */
  public Color getBaseColor() { return BASE_COLOR; }
}

layout.fxml

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

<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Text?>

<HBox xmlns="http://javafx.com/javafx"
      xmlns:fx="http://javafx.com/fxml"
      alignment="CENTER">

  <fx:define>
    <!--
        Define a reference to our Theme class.
        This is convenient because we only need a single
        instance of our Theme class for every FXML file.
    -->
    <styles.Theme fx:id="theme"/>
  </fx:define>

  <children>
    <!-- Now, we can simply use an expression binding here -->
    <Text text="Hello, World!" fill="${theme.baseColor}"/>
  </children>

</HBox>

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