티스토리 뷰

FXML Loader를 이용해서 UI 구현하기


 이번 시간에는 여태껏 해왔던 커스텀 컨트롤의 UI 구현 방법 중에 다른 형태를 보여드리고자 합니다. 바로 FXML Loader를 이용해서 UI를 구현 하는 방법입니다.


 

 여태껏 커스텀 컨트롤을 구현 할때는 클래스 상에서 Java 코드로 UI를 구현했습니다. 아래와 같이 말이죠.


1
2
3
4
5
6
7
8
9
10
11
public class MyControl extends BorderPane{
  private final int FIXED_WIDTH = 450;
  private final int FIXED_HEIGHT = 300;
 
  public MyControl(){
    Button button = new Button();
    getChildren().add(button);
 
    ......
  }
}
cs


  

  이번시간에 사용할 방법은 Java 코드가 아닌 FXML 코드로 UI를 작성한뒤 클래스에서 적용하는 방식을 사용할 것입니다.



  테스트 용도로 아래와 같은 컨트롤을 구현해보겠습니다. 물론 디자인은 다듬을 필요가 있을것 같습니다... 


  



FXML, CSS


  FXML 코드 부터 작성해 보겠습니다. FXML은 간단하게 BorderPane을 중심으로 작성되어 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<fx:root type="BorderPane" minHeight="-Infinity" minWidth="500" nodeOrientation="LEFT_TO_RIGHT"
         xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" stylesheets="@epochselector.css">
    <top>
        <BorderPane>
            <padding>
                <Insets top="5" left="5" right="5" bottom="5"/>
            </padding>
            <left>
                <HBox alignment="CENTER">
                    <BorderPane.margin>
                        <Insets left="4"/>
                    </BorderPane.margin>
                    <Label text="Stack Data Source"/>
                    <ComboBox styleClass="epoch-combo-box" prefWidth="180" fx:id="epochStackDataComboBox">
                        <HBox.margin>
                            <Insets left="8"/>
                        </HBox.margin>
                    </ComboBox>
                </HBox>
            </left>
            <right>
                <HBox alignment="CENTER">
                    <BorderPane.margin>
                        <Insets right="4"/>
                    </BorderPane.margin>
                    <Label text="Coordinate Frame"/>
                    <ComboBox styleClass="epoch-combo-box" prefWidth="160" fx:id="epochCoordinateComboBox">
                        <HBox.margin>
                            <Insets left="8"/>
                        </HBox.margin>
                    </ComboBox>
                </HBox>
            </right>
        </BorderPane>
    </top>
    <center>
        <VBox>
            <padding>
                <Insets left="10" right="10"/>
            </padding>
            <ScrollPane prefHeight="200" styleClass="epoch-scroll-pane">
                <BorderPane style="-fx-background-color:white">
                    <top>
                        <GridPane prefHeight="25" styleClass="output-data-grid-header"
                                  alignment="CENTER_LEFT" prefWidth="800">
                            <Label text="Time" GridPane.columnIndex="1" GridPane.rowIndex="0"
                                   styleClass="table-data-grid-header-label"/>
                            <Label text="Semi-Major Axis" GridPane.columnIndex="2" GridPane.rowIndex="0"
                                   styleClass="table-data-grid-header-label"/>
                            <Label text="Eccentricity" GridPane.columnIndex="3" GridPane.rowIndex="0"
                                   styleClass="table-data-grid-header-label"/>
                            <Label text="Inclination" GridPane.columnIndex="4" GridPane.rowIndex="0"
                                   styleClass="table-data-grid-header-label"/>
                            <Label text="R.A.A.N" GridPane.columnIndex="5" GridPane.rowIndex="0"
                                   styleClass="table-data-grid-header-label"/>
                            <Label text="Arg. Perigee" GridPane.columnIndex="6" GridPane.rowIndex="0"
                                   styleClass="table-data-grid-header-label"/>
                            <Label text="Mean Anomaly" GridPane.columnIndex="7" GridPane.rowIndex="0"
                                   styleClass="table-data-grid-header-label"/>
                            <columnConstraints>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="2"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                            </columnConstraints>
                        </GridPane>
                    </top>
                    <center>
                        <GridPane fx:id="epochDataGridPane" vgap="1" prefWidth="998" style="-fx-background-color:white">
                            <BorderPane.margin>
                                <Insets left="10"/>
                            </BorderPane.margin>
                            <columnConstraints>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="14"/>
                                <ColumnConstraints hgrow="SOMETIMES" percentWidth="16"/>
                            </columnConstraints>
                        </GridPane>
                    </center>
                </BorderPane>
            </ScrollPane>
        </VBox>
    </center>
    <bottom>
        <HBox alignment="CENTER_RIGHT">
            <BorderPane.margin>
                <Insets top="10" bottom="10"/>
            </BorderPane.margin>
            <Button text="Apply" styleClass="form-button" prefWidth="100" fx:id="epochApplyButton">
                <HBox.margin>
                    <Insets right="10"/>
                </HBox.margin>
            </Button>
            <Button text="OK" styleClass="form-button" prefWidth="100" fx:id="epochOKButton">
                <HBox.margin>
                    <Insets right="10"/>
                </HBox.margin>
            </Button>
            <Button text="Cancel" styleClass="form-button" prefWidth="100" fx:id="epochCancelButton">
                <HBox.margin>
                    <Insets right="10"/>
                </HBox.margin>
            </Button>
        </HBox>
    </bottom>
</fx:root>
cs



 중간의 TableView는 편의를 위해서 GridPane으로 작성했습니다 !


 CSS 파일은 다운 받아 적용 하시면 됩니다.          

   

epochselector.css



Control Class

 이제 실제 컨트롤 클래스에서 FXML을 적용하는 방법을 알아보도록 하겠습니다. 방법은 이전에 resources 디렉터리에 위치한 CSS 파일을 가져오는 방법과 비슷합니다. getResource() 메소드에서 FXML 파일명을 명시 해주는 방법입니다. 

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class EpochSelectorPopup extends BorderPane{
  @FXML
  private ComboBox<String> epochStackDataComboBox;
  @FXML
  private ComboBox<String> epochCoordinateComboBox;
  @FXML
  private GridPane epochDataGridPane;
  @FXML
  private Button epochOKButton;
  @FXML
  private Button epochCancelButton;
  @FXML
  private Button epochApplyButton;
 
  public EpochSelectorPopup(){
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("EpochSelector.fxml"));
 
    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);
 
    try {
      fxmlLoader.load();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
 
cs



결과 화면 

그럼 아래와 같은 결과를 얻을수 있습니다. 



반응형
댓글