Search code examples
javacssxmljavafxfxml

JavaFX: How to give more than one Circle the same size?


my question seems simple, but I didn't find a good way yet. I want to have several Circles defined in my FXML, 10 circles should have a radius of 10px, 20 others should have one of 6px. I want to declare the size at one point, so that I could change it easily.

I didn't find out if/how it's possible to declare a variable in FXML, which would be the easiest way. So I hoped CSS would help me, which would be even nicer: I tried to give the circles two styleClasses and set the size for those in a CSS, but it seems that there isn't a property to scale the circle.

<Circle fx:id="c00" centerX="100" centerY="100" styleClass="circle10" /> 

Another thought was overriding the Circle class and set the radius to the wanted value. But I don't think that's a clean code, because layout should be made in FXML and CSS, not in Java.

There must be a way to do it without messing with Java code at that place.

Thanks in advance for every help! mismyl


Solution

  • In FXML, if you want to define a single variable that you can use in multiple places use fx:define. From Introduction to FXML:

    The <fx:define> element is used to create objects that exist outside of the object hierarchy but may need to be referred to elsewhere.

    For example, when working with radio buttons, it is common to define a ToggleGroup that will manage the buttons' selection state. This group is not part of the scene graph itself, so should not be added to the buttons' parent. A define block can be used to create the button group without interfering with the overall structure of the document:

    <VBox>
        <fx:define>
            <ToggleGroup fx:id="myToggleGroup"/>
        </fx:define>
        <children>
            <RadioButton text="A" toggleGroup="$myToggleGroup"/>
            <RadioButton text="B" toggleGroup="$myToggleGroup"/>
            <RadioButton text="C" toggleGroup="$myToggleGroup"/>
        </children> 
    </VBox>
    

    Elements in define blocks are usually assigned an ID that can be used to refer to the element's value later. IDs are discussed in more detail in later sections.

    And here's an example for defining the radius of a Circle:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import java.lang.Double?>
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.shape.Circle?>
    
    <VBox xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" spacing="10.0" alignment="CENTER">
    
        <padding>
            <Insets topRightBottomLeft="10.0"/>
        </padding>
    
        <fx:define>
            <Double fx:id="smallRadius" fx:value="50.0"/>
            <Double fx:id="largeRadius" fx:value="100.0"/>
        </fx:define>
    
        <Circle radius="$smallRadius"/>
        <Circle radius="$largeRadius"/>
        <Circle radius="$smallRadius"/>
        <Circle radius="$largeRadius"/>
    
    </VBox>