(JavaFX) - Event Handler

2021. 6. 20. 21:31프로그래밍/개인프로젝트

한빛미디어-이것이자바다 강의를 들으며 작성했습니다.

 

Button을 눌렀을때 Action Event가 발생한다
-> Button에 등록되어있는 EventHandler이벤트를 처리한다

-> EventHandler는 이벤트를 처리하기 위해 handle이라는 메서드를 실행한다

-> handle()에서 {이벤트처리코드}가 실행된다

ex1)
Button btn1 = new Button()
	//
	btn1.setOnAction(new EventHandler<ActionEvent>(){
		@override
        public void handle (ActionEvent event){...}
    	});
	// '액션이벤트가 발생했을때 액션을 처리해줄 핸들러는 new EventHandler<ActionEvent>이다' 라는 뜻
	// 람다식으로 구현
	btn1.setOnAction(event->{...});
	//

ex2)
TableView tableView = new TableView();
	//	
    tableView.setOnMouseClicked(new EventHandler<MouseEvent>(){
    	@override
    	public void handle(MouseEvent event) {...}
    	});
    //
    //람다식으로 구현
    tableView.setOnMouseClicked(event -> {...});
    //
//버튼1클릭, 버튼2클릭 출력예제

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Event_Handler_Exam2 extends Application {
	
	public void start(Stage primaryStage) throws Exception {
		HBox root = new HBox();
		root.setPrefSize(200, 50);
		root.setAlignment(Pos.CENTER);
		root.setSpacing(20);
		
		Button btn1 = new Button("버튼1");
        //
		btn1.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				System.out.println("버튼1 클릭");
			}
		});
		//
		//람다식으로 작성
		Button btn2 = new Button("버튼2");
		btn2.setOnAction(event -> System.out.println("버튼2 클릭")); 
		//람다식으로 작성
		
		root.getChildren().addAll(btn1, btn2);
		Scene scene = new Scene(root);
		
		primaryStage.setScene(scene);
		primaryStage.setTitle("AppMain");
		primaryStage.show();
		
	}

	public static void main(String[] args) {
		launch(args);
	}
}

버튼생성

//종료클릭메세지 추가

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Event_Handler_Exam3 extends Application {
	
	public void start(Stage primaryStage) throws Exception {
		HBox root = new HBox();
		root.setPrefSize(200, 50);
		root.setAlignment(Pos.CENTER);
		root.setSpacing(20);
		
		Button btn1 = new Button("버튼1");
		//
		btn1.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				System.out.println("버튼1 클릭");
			}
		});
		//
		//람다식으로 작성
		Button btn2 = new Button("버튼2");
		btn2.setOnAction(event -> System.out.println("버튼2 클릭")); 
		//람다식으로 작성
		
		root.getChildren().addAll(btn1, btn2);
		Scene scene = new Scene(root);
		primaryStage.setScene(scene);
		primaryStage.setTitle("AppMain");
		//
		primaryStage.setOnCloseRequest(event -> System.out.println("종료클릭"));
		//
		primaryStage.show();
		
	}
	public static void main(String[] args) {
		launch(args);
	}
}

 

 

fxml레이아웃의 사용이유

 

자바코드(이벤트처리코드)와 레이아웃 코드를 분리한다

-> 이벤트 처리를 위한 java클래스 파일인 컨트롤러가 필요하다

 

컨트롤러 지정법 

 

루트컨테이너 안에 fx:controller = "패키지명.컨트롤러명"을 넣어준다.

ex) <AnchorPane xmlns = "..." xmlns = "..." fx:controller = "패키지명.컨트롤러명">
      </AnchorPane>

 

fxml파일에 각각 1개의 컨트롤러를 지정할 수 있다.

 

컨트롤러 객체는 fxml파일이 로딩될 때 자동으로 생성된다.

이때 이 컨트롤러는  반드시 클래스로 선언되어있어야하고 initializable인터페이스를 구현해야한다

public class RootController implements Initializable { ... }

 

fxml파일에 fx:id속성을 추가해야 컨트롤러에서 참조가 가능하다 (@FXML을 통해서)

 

컨트롤러에서 fxml에 선언된 컨트롤의 참조를 컨트롤러가 필드로 가지고 있다면 initialize라는 메서드에서 이벤트 처리코드를 작성할 수 있다.

initialize메서드는 컨트롤러 생성시 자동실행하는 메서드다

fxml에 직접 onAction을 작성하면 컨트롤러에@FXML을 넣을 필요 없다.

ex)

<Button fx:id = "btn3" text="버튼3" onAction="#handleBtn3Action"/>

 

//메인클래스

package Exam_2;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Event_Handler_Exam_Main extends Application {
	
		@Override
		public void start(Stage primaryStage) throws Exception {
		Parent root = (Parent)FXMLLoader.load(getClass().getResource("root.fxml"));
		Scene scene = new Scene(root);
		
		primaryStage.setTitle("AppMain");
		primaryStage.setScene(scene);
		primaryStage.show();
	} 

	public static void main(String[] args) {
		launch(args);
	}
}
//fxml파일

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

<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>

<HBox xmlns:fx="http://javafx.com/fxml"
			prefHeight = "50.0" prefWidth = "200.0"
			alignment = "CENTER" spacing = "20.0" 
			fx:controller = "Exam_2.RootController">
			
		<children>
			<Button fx:id = "btn1" text="버튼1"/>
			<Button fx:id = "btn2" text="버튼2"/>
			<Button fx:id = "btn3" text="버튼3" onAction="#handleBtn3Action"/>
		</children>
</HBox>
//컨트롤러

package Exam_2;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;

public class RootController implements Initializable {
	//Main에서 root.fxml을 로딩할때 컨트롤러 객체가 생성되며 initialize가 호출된다
			@FXML private Button btn1;
			@FXML private Button btn2;
			//@FXML private Button btn3; fxml파일에 직접 작성해서 필요없음
			
		@Override
		public void initialize(URL location, ResourceBundle resources) {
				btn1.setOnAction(new EventHandler<ActionEvent>() {

					@Override
					public void handle(ActionEvent event) {
						handleBtn1Action(event);
					}
				});
				btn2.setOnAction(event -> handleBtn2Action(event));
			}
            
		//메서드를 따로 빼서 작성
		public void handleBtn1Action(ActionEvent event) {
			System.out.println("버튼1을클릭한다");
		}
		public void handleBtn2Action(ActionEvent event) {
			//람다식 이용
			System.out.println("버튼2을클릭한다");
		}
		public void handleBtn3Action(ActionEvent event) {
			//fxml파일에 직접 onAction작성
            System.out.println("버튼3을클릭한다");
		}
}