ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] JavaFX - 컨테이너(Container)
    CSE/Java 2015. 12. 14. 17:44

    JavaFX는 여러 절로 구성되어 있습니다.





    Intro

    JavaFX 레이아웃(Layout)

    JavaFX 컨테이너(Container)

    JavaFX 이벤트 처리 & 속성 감시, 바인딩

    JavaFX 컨트롤(Control)

    JavaFX 메뉴바와 툴바 & 다이얼로그

    JavaFX 스레드 동시성





    JavaFX 컨테이너(Container)

     레이아웃을 작성할 때 컨트롤들을 쉽게 배치할 수 있도록 도와주는 클래스가 컨테이너입니다. javafx.scene.layout 패키지에는 다양한 컨테이너 클래스들이 존재합니다. 




     









     AnchorPane 컨테이너

      AnchorPane 컨테이너는 좌표를 이용하여 AnchorPane의 좌상단(0, 0)을 기준으로 컨트롤을 배치합니다. 컨트롤 좌표는 좌상단(layoutX, layoutY) 값을 말하는데 (0, 0)에서 떨어진 거리입니다.








      AnchorPane에서 사용할 수 있는 주요 설정은 다음과 같습니다.










      AnchorPane 컨테이너는 JavaFX Scene Builder를 사용해서 디자인하는 것이 좋습니다. 눈으로 거리를 확인해서 컨트롤을 할 수 있기 때문입니다. 다음은 AnchorPane 루트 컨테이너를 사용해서 로그인 레이아웃을 정의한 것 입니다.




     * root.fxml

      

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.TextField?>
    <?import javafx.scene.control.PasswordField?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.chart.BubbleChart?>
     
    <AnchorPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="150.0" prefWidth="300.0">
        <children>
            <Label layoutX="42.0" layoutY="28.0" text="아이디" />
            <Label layoutX="42.0" layoutY="66.0" text="패스워드" />
            <TextField layoutX="120.0" layoutY="24.0" />
            <PasswordField layoutX="120.0" layoutY="62.0" />
            <Button layoutX="97.0" layoutY="106.0" text="로그인" />
            <Button layoutX="164.0" layoutY="106.0" text="취소" />
        </children>
    </AnchorPane>
     
     
    cs








      AnchorPane에 포함된 컨트롤은 <children> 태그의 자식 태그로 선언되는데, <children>은 AnchorPane의 setChild() 메소드를 호출하는 것이 아니라, getChildren() 메소드가 리턴하는 ObservableList 컬렉션에 <children>의 자식 태그로 정의된 컨트롤을 추가하는 역할을 합니다. 


      AnchorPane을 사용해서 컨트롤을 좌표로 배치하면 윈도우 창이 줄거나 늘어날 경우 컨트롤의 재배치가 일어나지 않습니다. 따라서 AnchorPane으로 재배치할 경우에는 윈도우 창의 크기를 변경할 수 없도록 Stage의 setResizable(false) 메소드를 호출하는 것이 좋습니다.






     HBox와 VBox 컨테이너

      HBox와 VBox는 수평과 수직으로 컨트롤을 배치하는 컨테이너입니다. HBox와 VBox는 자식 컨트롤의 크기를 재조정하는데, HBox는 컨트롤의 높이를 확장하고, 컨트롤의 폭은 유지합니다. VBox는 컨트롤의 폭을 확장하고 컨트롤의 높이는 유지합니다. 단, 크기 조정이 가능한 컨트롤만 자동 확장 됩니다. Button의 경우는 크기 조정이 되지 않는데, 그 이유는 maxWidth와 maxHeight가 -1.0을 가지기 때문입니다. 크기 조정이 가능하도록 하려면 다음과 같이 maxWidth와 maxHeight를 변경하면 됩니다.


    1
    2
    3
    4
    <Button text="Button">
        <maxWidth><Double fx:constant="MAX_VALUE"/></maxWidth>
        <maxHeight><Double fx:constant="MAX_VALUE"/></maxHeight>
    </Button>
    cs




      HBox에서 컨트롤의 높이를 확장하고 싶지 않다면 fillHeight 속성을 false를 설정하면 되고, VBox에서 컨트롤의 폭을 확장하고 싶지 않다면 fillWidth 속성을 false로 설정하면 됩니다. HBox와 VBox에서 사용할 수 있는 주요 설정은 다음과 같습니다.



     




      다음 예제는 VBox로 ImageView 컨트롤과 HBox 컨테이너를 수직으로 배치하고, HBox 안에는 두 개의 버튼을 수평으로 배치했습니다. [Next] 버튼은 HBox의 남은 폭을 채우도록 HBox의 hgrow 속성을 설정했습니다.





     * root.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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import javafx.scene.layout.VBox?>
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.image.ImageView?>
    <?import javafx.scene.image.Image?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.layout.Priority?>
    <?import java.lang.Double?>
     
    <VBox xmlns:fx="http://javafx.com/fxml/1">
        <padding>
            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
        </padding>
        
        <children>
            <ImageView fitWidth="200.0" preserveRatio="true">
                <image>
                    <Image url="@images/pal.png" />
                </image>
            </ImageView>
            
            <HBox alignment="CENTER" spacing="20.0">
                <children>
                    <Button text="이전" />
                    <Button text="다음">
                        <HBox.hgrow><Priority fx:constant="ALWAYS"/></HBox.hgrow>
                        <maxWidth><Double fx:constant="MAX_VALUE"/></maxWidth>
                    </Button>
                </children>
                <VBox.margin>
                    <Insets top="10.0" />
                </VBox.margin>
            </HBox>
        </children>
    </VBox>
     
     
    cs















     BorderPane 컨테이너

      BorderPane은 top, bottom, left, right, center 셀에 컨트롤을 배치하는 컨테이너입니다. 컨트롤만 배치하는 것이 아니라 다른 컨테이너도 배치할 수 있기 때문에 다양한 레이아웃을 만들어 낼 수 있습니다. 주의할 점은 각 셀에는 하나의 컨트롤 또는 컨테이너만 배치할 수 있습니다. 다음은 BorderPane에서 사용할 수 있는 태그 및 속성들입니다.



     






     


      BorderPane의 특징은 top, bottom, left, right에 컨트롤을 배치하지 않으면 center에 배치된 컨트롤이 top, bottom, left, right까지 확장됩니다. 


      다음은 BorderPane의 top에는 ToolBar를 배치하고, center에는 TextArea를 bottom에는 다시 BorderPane을 배치합니다.



     * root.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
    29
    30
    31
    32
    33
    34
     
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import javafx.scene.layout.BorderPane?>
    <?import javafx.scene.control.ToolBar?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.TextArea?>
    <?import javafx.scene.control.TextField?>
     
    <BorderPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="200" prefWidth="300">
        <top>
            <ToolBar>
                <items>
                    <Button text="Button" />
                    <Button text="Button" />
                </items>
            </ToolBar>
        </top>
        <center>
            <TextArea />
        </center>
        <bottom>
            <BorderPane>
                <center>
                    <TextField />
                </center>        
                <right>
                    <Button text="Button" />
                </right>
            </BorderPane>
        </bottom>
    </BorderPane>
     
     
    cs









     GridPane 컨테이너

      GridPane은 그리드로 컨트롤을 배치하되 셀의 크기가 고정적이지 않고 유동적인 컨테이너 입니다. 셀 병합이 가능하기 때문에 다양한 입력폼 화면을 만들 때 매우 유용하게 사용할 수 있습니다. 각 컨트롤은 자신이 배치될 행 인덱스와 컬럼 인덱스를 속성으로 가지며, 몇 개의 셀을 병합할 것인지도 지정할 수 있습니다.


      다음은 GridPane에 적용 가능한 속성들입니다.










      다음은 로그인 화면을 GridPane으로 배치한 것입니다.



     * root.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
    29
    30
    31
    32
    33
     
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import javafx.scene.layout.GridPane?>
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.TextField?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.control.Button?>
     
    <GridPane xmlns:fx="http://javafx.com/fxml/1" prefWidth="300" hgap="10" vgap="10">
        <padding>
            <Insets topRightBottomLeft="10"/>
        </padding>
        <children>
            <Label text="아이디" GridPane.rowIndex="0" GridPane.columnIndex="0" />
            <TextField GridPane.rowIndex="0" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" />
            
            <Label text="비밀번호" GridPane.rowIndex="1" GridPane.columnIndex="0" />
            <TextField GridPane.rowIndex="1" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" />
            
            <HBox GridPane.rowIndex="2" GridPane.columnIndex="0"
                GridPane.columnSpan="2" GridPane.hgrow="ALWAYS"
                alignment="CENTER" spacing="20">
                <children>
                    <Button text="로그인" />
                    <Button text="취소" />
                </children>    
            </HBox>
        </children>
    </GridPane>
     
     
    cs

















     


     



     * 이 포스트은 서적 '이것이 자바다' 를 참고하여 작성한 포스트입니다.


    댓글

Designed by Tistory.