1.람다


람다식은 익명객체를 선언 할 경우 자주 쓰이는 형식을 간략화 시킨 식을 말한다.


자주 쓰이는 방법은 3가지의 방법이 있으며 람다를 사용하면 코드수가 줄어들고 오버라이드 할 메소드가 생략되어


좀 더 깔끔해진다.


다음 예제를 통해 일반 익명객체와 람다식을 비교해보자



package chap13.exam01.basic;

public class Main {
// 람다식은 다른 환경에서는 잘 쓰이지만 java에서는 잘 쓰이고 있지 않음
	public static void main(String[] args) {
		// 일반적인 익명객체 사용
		Runnable task1 = new Runnable() {
			
			@Override
			public void run() {
				for(int i = 1; i <= 3; i++) {
					System.out.println("익명 객체 스레드 실행");
				}
			}
		};
		// 1번 방법
		Thread th = new Thread(task1);
		th.start();
		
		// 2번 방법 (간소화)
		new Thread(task1).start();
		
		// 람다식 익명객체 사용 -> 강제하는 오버라이드 메소드 생략, 코드 수 절약
		// 강제 생략 할 메소드가 여러개면 안된다.
		// 3번 방법
		Runnable task2 =()->{
			for(int i = 1; i <= 3; i++) {
				System.out.println("람다식 객체 스레드 실행");
			}
		};
		
		new Thread(task2).start(); // 간소화
		
	}

}


람다식 인터페이스도 있는데 람다식의 특징으로 한 방식 정해진 방법을 강제하는 식이므로


메소드가 많으면 안되어 제한하는 코드를 따로 명시하며 메소드는 하나밖에 안쓰이기 때문에


왠만하면 잘 안쓰인다.


package chap13.exam02.lambdaInter;
@FunctionalInterface // 람다식 인터페이스를 만들 때 선언하여 1인터페이스 - 1메소드를 강제시킴
							   // 람다식을 사용 할 때에 메소드가 많으면 사용하기 애매하니 제한하는 코드
public interface LambdaInter {
	
	int operation(int a , int b); // 하나밖에 없기 때문에 사용 시 매개변수에 들어오는 값은
										 // 정해져 있어 자료형을 생략
	
//	void sayMsg(String msg);
}


람다식의 사용법은 3가지인데 객체화시


= new XXXX();


------------------------


= (a, b) -> { 내용 }


= a -> { 내용 }


= ( ) -> { 내용 }


과 같이 사용된다. 다음 예제를 확인해보자

package chap13.exam03.usage;

public class Main {

	public static void main(String[] args) {
		// 생략이 가능한 이유는 이미 인터페이스 내 메소드가 선언되어 있어서
		
		// 매개변수가 여러개 일 경우(매개변수 타입 생략 가능)
		OperationA lambdaA = (a, b)-> {
			int result = a + b;
			System.out.println("답은 : " + result);
		};
		lambdaA.plus(3, 4);
		
		// 매개변수가 하나일 경우(괄호와 타입이 생략)
		OperationB lambdaB = a ->{
			System.out.println("a의 제곱은 : " + (a * a));
		};
		lambdaB.square(50);
		
		// 매개변수가 없을 경우(생략 X) 기본 형태
		// 람다식 자체를 자주 사용하지 않기 때문에 일반적인 사용법인 이것정도만 기억하면 된다.
		OperationC lambdaC = () ->{
			System.out.println("매개변수 없이 실행");
		};
		lambdaC.process();
		
		//실험내용이 반환문 만 있을 경우(코드블록 생략, Return도 생략해주어야 함)
		OperationD lambdaD = msg -> msg;
		System.out.println(lambdaD.echo("반환만 한다."));

	}
	// 사용할 인터페이스 (내부 선언)
//	@FunctionalInterface // 써도 되고 안써도 된다.
	interface OperationA{ void plus(int a, int b); }
	interface OperationB{ void square(int a); }
	interface OperationC{ void process( ); }
	interface OperationD{ String echo(String msg); }
}


- 1 -


Main은 따로 변경할 사항이 없다.



BorderPane - Center에 Pane 추가


Pane위에 위와같이


Label (fx:id - label)


Slider (fx:id - slider)


TextArea (fx:id - area1)


TextArea (fx:id - area2)



Controller class 설정, 저장 후 코드


슬라이더의 콩을 움직일 때 글자의 크기도 바로바로 늘어나고


텍스트 area 1, 2의 글자가 동시에 입력되게끔



package app;

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

import javafx.beans.binding.Bindings;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextArea;
import javafx.scene.text.Font;

public class MainController implements Initializable{

	@FXML private Label label;
	@FXML private Slider slider;
	@FXML private TextArea area1;
	@FXML private TextArea area2;
	
	@Override
	public void initialize(URL location, ResourceBundle resources) {
		System.out.println("FXML Load Complete");
		// 실시간 감시, 값을 확인
		// 슬라이더 변경시 값을 확인
		// 아래는 그대로 쓰되 대부분 자동생성
		slider.setValue(12); // 글자 기본값 12랑 맞춰주기
		slider.valueProperty().addListener(new ChangeListener<Number>() {
		// 스스로를 감시하여 값이 변경 될 때마다 특정 이벤트 발생
			@Override
			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
				label.setFont(new Font(newValue.doubleValue()));
			}
		});
		/*
		 * 단방향 바인딩
		 * 대상1에 변경된 내용을 대상 2에 적용
		 * 대상2.xxxProperty().bind(대상1.XXXProperty))
		 * 양방향 바인딩
		 * 대상2. xxxProperty().bindBidrictional(대상1.xxxProperty)
		 */
		Bindings.bindBidirectional(area1.textProperty(), area2.textProperty());
	}
	
}





















- 2 -


Main의 Scene scene = new Scene(root,200,200); 부분에 숫자를 200, 200로 하여 창 크기를 줄이고





Border의 Center에 Pane을 올리고


Pane 위에 Slider와 Text Field를 올린다.


Slider - fx:id : slider


TextField - fx:id : field


그리고 Controller class를 설정 후 코딩


이 프로그램은 슬라이더를 움직이면 그에 알맞은 텍스트가 출력되는 프로그램


Bindings를 통해서 하나로 묶는것

package app;

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

import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;

public class MainController implements Initializable {

	@FXML private Slider slider;
	@FXML private TextField field;
	
	@Override
	public void initialize(URL arg0, ResourceBundle arg1) {
		System.out.println("FXML Load Complete");
		slider.setValue(50);
//		field.setText("50");
		field.setText(new Double(50).toString());
		Bindings.bindBidirectional(field.textProperty(), slider.valueProperty(), NumberFormat.getNumberInstance());
		// field, slider를 인자로 받음
	}
	
}








Menu바는 정말 간단한 작업


Main에는 건드릴게 따로 없고 Scene Builder에서 디자인과 Controller만 하면 된다.





BorderPane Top - MenuBar 추가 - Menu 포함 - MenuItem 포함


   - Menu 추가 - MenuItem 포함


    - MenuItem 추가


   - MenuItem 추가


   - SeparatorMenuItem 추가


   - MenuItem 추가 (Close로 명명)


   - Menu 포함 - MenuItem 포함


   - Menu 포함 - MenuItem 포함


Center - Pane 추가


추가는 Library에서 검색하여 넣은것. 포함은 기본값


처음 MenuBar을 추가하면 3가지 Menu가 들어있고


Library에서 Menu 항목 안에 Menu를 추가하면 위의 실행 이미지와 같이 하위 항목이 하나 더 생긴다.


이미지에서 Menu 옆에 흐른 글씨로 File과 같이 써있는데 더블 클릭하여 내용을 변경할 수 있다.


그 중 Close로 명명한 MenuItem의 Code 부분의 On Action을 closeApp으로  설정


Controller 클래스 등록 후 저장


그리고 등록한 클래스를 작성



package app; import javafx.application.Platform; public class MainController { // initialize는 따로 초기화할 것이 없으므로 안씀 public void closeApp() { Platform.exit(); // 앱 종료(main Thread) System.exit(0); // Jvm을 완전 종료 } }



위와같이 코드를 작성하고 실행하면 아까 디자인한 창이 나오는데


상단 메뉴바에서 Close를 선택하면 프로그램이 종료된다.

+ Recent posts