Java의 라이브러리 중 JavaFX 설치와 사용 방법에 대해 알아보자.
JavaFX는 Java의 GUI 라이브러리이다.
이전에는 Swing이라는 GUI 라이브러리를 주로 사용했지만, 요즈음은 JavaFX를 많이 쓴다고 한다.
참고로, C의 GUI 라이브러리 변천사는
MFC -> WinFrame -> WPF 이렇게 라고 하며,
시중에 있는 대부분의 키오스크 화면은 C의 GUI 라이브러리로 제작되었다고 한다.
그렇다면 ! JavaFX를 설치해보자.
우선 라이브러리 다운로드가 필요하다.
https://gluonhq.com/products/javafx/
사이트에 방문해서, 본인에게 맞는 Java version을 선택하고(만약 안보인다면 체크박스 Include older versions를 클릭하면 된다) 다운받는다.
다운받은 후에는 압축을 푼 폴더를
Java가 위치한 폴더>Amazon Corretto 안에 위치시킨다.
나의 경우에는
/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/javafx-sdk-11.0.2
와 같이 위치했다.
이후에는 IDE와 JavaFX를 연동시켜주면 된다.
Eclipse를 시도했다가 잘 안되서 IntelliJ로 넘어갔지만.. 혹시 몰라 둘 다 기록을 남긴다.
참고로 체감 난이도 IntelliJ >>>> Eclipse였다.
Project Explorer에서 해당 프로젝트 우클릭 > Properties > Java Build Path를 클릭하고,
Library 탭을 누르면 다음과 같은 화면이 나온다.
여기서 Modulepath를 클릭하면 오른쪽 버튼들이 활성화되는데, Add External JARS...를 클릭하여 위에서 다운받은 javafx/lib에 접속하고, jar파일들만 선택한다(총 8개)
파일을 불러오면 다음과 같이 jar 파일들이 나타나게 된다.
Apply를 하면 Project Explorer의 Referenced Libraries에서도 다음과 같이 확인할 수 있다.
설치 후에는 Run Configurations에 들어가서 Arguments 탭을 클릭하고, VM arguments: 밑에 다음과 같이 입력한다. ""안에는 본인의 경로를 입력하면 된다.
--module-path "/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/javafx-sdk-11.0.2/lib"
--add-modules javafx.controls,javafx.fxml
이제 라이브러리 설치가 완료되었고, 작동하는지 확인해보자.
public class hello extends Application{
//여기까지 했을 떄 hello에 error가 뜨는 이유: 추상 메소드를 구현하지 않아서
@Override
public void start(Stage arg0) throws Exception {
System.out.println(2);
arg0.show();
System.out.println(3);
}
public static void main(String[] args) {
System.out.println(1);
launch();
System.out.println(4);
}
}
위 코드에서 class hello가 extends하는 Application이 JavaFX의 class이다. 따라서, Application을 작성했을 때
import javafx.application.Application;
코드가 연동된다면 올바르게 설치한 것이다.
그리고 위의 코드를 실행했을 때 새 GUI 창이 나온다면 성공 !
그러나 나의 맥북에서는 실행이 되지 않았다 ㅠㅠ
아래의 Document를 따라하면 3분만에 설치하고 실행할 수 있다 !!
IntelliJ에서 JavaFX 설치
public class hello extends Application{
//여기까지 했을 떄 hello에 error가 뜨는 이유: 추상 메소드를 구현하지 않아서
@Override
public void start(Stage arg0) throws Exception {
System.out.println(2);
arg0.show();
System.out.println(3);
}
public static void main(String[] args) {
System.out.println(1);
launch();
System.out.println(4);
}
}
위 코드를 실행했을 때 새 GUI 창이 나온다면 성공 !!
public class HelloApplication extends Application{ //여기까지 했을 떄 hello에 error가 뜨는 이유: 추상 메소드를 구현하지 않아서
@Override
public void start(Stage arg0) throws Exception {
System.out.println(2);
arg0.show();
arg0.setTitle("Hello Jihu");
System.out.println(3);
}
public static void main(String[] args) {
System.out.println(1);
launch();
System.out.println(4);
}
}
위 코드를 실행하면 아래와 같은 결과가 나온다.
이제 전체적인 구현을 한번 살펴보자.
JavaFX는 기본적으로 stage로 구성되며, 1개의 stage 안에는 1개의 scene이 존재할 수 있다.
그리고 Scene은 VBox 혹은 HBox를 활용하여 크기를 구성할 수 있다.
VBox = Vertical Box, HBox = Horizontal Box
public class HelloApplication extends Application{
@Override
public void start(Stage arg0) throws Exception {
VBox root = new VBox();
root.setPrefSize(400, 300); //px단위, 가로, 세로
// --------------------
//응용 프로그램이 들어 가는 영역
// --------------------
//적용하기 위해서는 scene을 만들어서 등록해야 한다.
Scene scene = new Scene(root);
//scene과 arg0 연결
arg0.setScene(scene);
arg0.setTitle("Hello Jihu");
arg0.show();
}
public static void main(String[] args) {
launch();
}
}
위 코드에서는 VBox를 활용하여 Scene을 구성하였다. 이를 실행하면 가로 400px, 세로 300px의 GUI가 생성된다.
다음으로는 화면에 버튼을 추가해보자.
버튼을 추가하는 방법은 두가지가 있는데,
첫번째는 root.getChildren().add(btn1);
를 통해 각 버튼의 객체를 추가하는 것이고,
두번째는 root.getChildren().addAll(btn1, btn2);
을 통해 여러 버튼의 객체를 한번에 추가하는 것이다.
다음의 코드를 실행해보자.
public class HelloApplication extends Application{
@Override
public void start(Stage arg0) throws Exception {
//V(ertical)Box, H(orizontal) Box
VBox root = new VBox();
root.setPrefSize(400, 300); //px단위, 가로, 세로
root.setSpacing(5); //버튼과 버튼 사이의 간격
// --------------------
//버튼 추가 방법 1
// Button btn1 = new Button("첫번째 버튼" );
// root.getChildren().add(btn1);
// Button btn2 = new Button("두번째 버튼" );
// root.getChildren().add(btn2);
//방법 2
Button btn1 = new Button("첫번째 버튼" );
Button btn2 = new Button("두번째 버튼" );
root.getChildren().addAll(btn1, btn2);
// --------------------
//적용하기 위해서는 scene을 만들어서 등록해야 한다.
Scene scene = new Scene(root);
//scene과 arg0 연결
arg0.setScene(scene);
arg0.setTitle("Hello Jihu");
arg0.show();
}
public static void main(String[] args) {
launch();
}
위 코드를 실행하면 아래와 같은 결과가 나온다.
위에서는 단순히 버튼만 만들고 끝났지만, 사실상 버튼을 눌렀을 때 아무런 Event가 발생하지 않는다.
이번에는 각 버튼마다 Action을 부여해보자.
btn1.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
System.out.println("클릭");
}
});
위 코드의 setOnAction 메도스를 작성함으로써 Event를 발생시킬 수 있게 된다.
코드를 실행하고 첫번째 버튼을 클릭하면 Console 창에 "클릭"이라고 결과가 출력된다.
만약 버튼 2를 클릭했을 때 버튼 1을 제어하고 싶다면 다음과 같이 코드를 작성하면 된다.
btn2.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
btn1.setText("앵무새"); //버튼1의 내용을 바꿈
//btn1.setVisible(false); //버튼1이 안보이게 만듦
//btn1.setDisable(true); //버튼1을 누르지 못하게 만듦
btn1.setDisable(!btn1.isDisable()); //버튼1 활성화 토글
}
});
그리고 Text Field, Text Area를 추가하고 싶다면 버튼과 비슷하게 객체를 아래와 같이 생성하면 된다.
TextField textField = new TextField();
TextArea textArea = new TextArea();
이에 Event 처리를 해주고 싶다면, 버튼과 비슷하게 setOnAction()을 통하여 아래와 같이 작성하면 된다.
textField.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
System.out.println(textField.getText()); //textField에 입력된 값을 가져옴
String s = textField.getText();
textArea.appendText(s + "\n"); //밑의 TextArea에 값 전달
textField.setText(""); //엔터 누르면 값 지워짐
}
});
text와 관련하여 getTest()를 활용하면 입력된 값을 가져올 수 있다.
마지막으로 아래의 코드를 실행하며 각 컴포넌트를 생성하고 제어해보자!
public class HelloApplication extends Application{
@Override
public void start(Stage arg0) throws Exception {
//V(ertical)Box, H(orizontal) Box
VBox root = new VBox();
root.setPrefSize(400, 300); //px단위, 가로, 세로
root.setSpacing(5); //버튼과 버튼 사이의 간격
// --------------------
Button btn1 = new Button("첫번째 버튼" );
Button btn2 = new Button("두번째 버튼" );
//action 처리
//익명 함수 생성
btn1.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
System.out.println("클릭");
}
});
//버튼 2를 눌렀을 때 버튼 1을 제어
btn2.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
btn1.setText("앵무새"); //버튼1의 내용을 바꿈
//btn1.setVisible(false); //버튼1이 안보이게 만듦
//btn1.setDisable(true); //버튼1을 누르지 못하게 만듦
btn1.setDisable(!btn1.isDisable()); //버튼1 활성화 토글
}
});
TextField textField = new TextField();
TextArea textArea = new TextArea();
textField.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
System.out.println(textField.getText()); //textField에 입력된 값을 가져옴
String s = textField.getText();
textArea.appendText(s + "\n"); //밑의 TextArea에 값 전달
textField.setText(""); //엔터 누르면 값 지워짐
}
});
root.getChildren().addAll(btn1, textField, textArea);
// --------------------
//적용하기 위해서는 scene을 만들어서 등록해야 한다.
Scene scene = new Scene(root);
//scene과 arg0 연결
arg0.setScene(scene);
arg0.setTitle("Hello Jihu");
arg0.show();
}
public static void main(String[] args) {
launch();
}
}