1. 경로 참조


파일 경로 참조시에는 getClass().getResource("경로")


와 같이 쓴다.


예를들어


src/app/Main.java


src/app/call.fxml


구조로 되있다면


Main에서 호출할 때 getClass().getResource("main.fxml") 와 같이 단순하게 써도 된다.


그리고 만약


src/app/Main.java


src/app/view/main.fxml


위와 같이 호출한 java파일의 하위에 있다면


getClass().getResource("view/main.fxml")와 같이 쓰면 인식이 된다


하지만 다른 폴더에 있을 경우는 달라지는데


src/app/Main.java


src/view/fxml/main.fxml


위와 같이 소스폴더는 같지만 그 다음 경로가 완전히 다르다면


getClass().getResource("../view/fxml/main.fxml")과 같이 ".."을 통해서 한번 상위폴더로 이동 후 경로를 입력해야 한다.


여담으로 getClass().getResource("경로")는 이 코드를 입력한 java파일이 담겨있는 폴더의 경로를 의미한다.


고로 "..", 점 두번으로 유도리있게 입력해야 한다.





2.fxml파일과 컨트롤러 클래스의 관계


프로젝트는 기본적으로 화면을 하나만 쓰는게 아니라 여러개를 사용하게 되는데


fxml파일에 함수를 붙이고 싶다면 Controller 클래스를 붙이게 된다.


그런데 가끔 같은 컨트롤러를 참조하게 되는데


이런 경우에는 main.fxml - funcController.java - sub.fxml과 같이 공유하는게 아니고


main.fxml - funcController.java / sub.fxml - funcController.java와 같이 새로 불러와 별개의 클래스를 사용한다.


따라서 main에서 변수에 1을 넣었다고 하더라도 sub에서 같은 변수를 불렀을 때 다른값이 나오게 되는 것.


이런 경우에는 따로 java파일을 만들어서 static 변수로 공유한다면 편하게 사용할 수 있다.






MVC 패턴이란 애플리케이션의 역할을 3가지로 나눈것으로


Model, View, Controller으로 구분, 여태껏 해온 소스 파일들로 나눠본다면


Model = Main.java


View = main.fxml


Controller = MainController


위와 같이 나눌 수 있다.


뷰의 경우는 레이아웃을 의미, 컨트롤러는 기능 구현, 모델은 완성품 같은 느낌이다.


사용자와 MVC와의 관계는 다음과 같다.






이 MVC와 같이 패키지를 구분하여 계산기를 한 번 직접 만들어보자


대략적인 프로젝트 구성은 다음과 같이 나올것이다.






24_Calculator.zip



위 파일은 완성본으로 


File - Import


General의 Archive File


From Archive File에 다운받은 압축 파일을 선택하면 Import된다.


몰론 Java FX가 설치되어 있어야 한다.











예전에 정리한 Static을 이용해서 Stage를 선언한다면


버튼을 통해서 현재 스테이지를 불러오는 귀찮은 작업을 줄이고 쉽게 참조할 수 있고


Main, Controller  두 개의 자바 파일에서 스테이지를 공유할 수 있고


전에 스테이지를 계속 새로 만들어 메모리가 낭비되는 반면


static으로 선언하면 클래스 영역에 저장되고 다같이 사용할 수 있어 효율적이다.


먼저 프로젝트를 생성하고 src에 StageStore라고 java 클래스 파일을 하나 만든다.


package app;

import javafx.stage.Stage;

public class StageStore {
	public static Stage stage = null;
}

스테이지를 Static으로 공유할거고 그 기능 외에는 사용 할 기능이 없다.


다음으로는 Main의 BorderPane과 size 변경 그리고 Static 공유 적용



package app;
	
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;


public class Main extends Application {
	@Override
	public void start(Stage primaryStage) {
		try {
			// Stage를 따로 class로 만들어 Static 변수로 선언하여 공용으로 사용한다.
			StageStore.stage = primaryStage;
			
			Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
			Scene scene = new Scene(root,200,100);
			// 여기까지 변경
			
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			primaryStage.setScene(scene);
			primaryStage.show();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}


다음으로 main fxml을 열어 수정




Border Pane 삭제 후 Anchor Pane Layout Size (200, 100)으로 추가


AnchorPane - Code : fx:id - mainPage


Button - Code : fx:id - mainBtn


      On Action - move


Label



컨트롤러 등록 후 메인 위에 띄울 서브 레이아웃을 만든다.





AnchorPane으로 생성하고 사이즈는 메인과 똑같이 (200, 100)으로 만든다.


AnchorPane - Code : fx:id - subPage


Button - Code : fx:id - subBtn


      On Action - closeWin


Label


위와 같이 생성 후 컨트롤러를 연결하는데


이번에는 새로운 클래스를 만들어 컨트롤러를 새로 만들어본다.


Java class 파일로 하나 만들어서 Scene Builder에 입력해보자.


Scene Builder를 연채로 클래스를 만들면 리스트에 안나오므로 한 번 껏다 키면 해결된다.


마지막으로 main fxml 파일과 sub fxml 파일의 Anchor Pane의 색상을 변경한다.







AnchorPane에 색깔을 입히는 이유는 레이아웃의 기본 색상이 투명이라


Main 위에 sub를 띄우면 다음과 같이 레이아웃이 겹쳐서 보인다.




그러므로 레이아웃 바탕에 색깔을 입혀 아래에 있는 레이아웃을 감춰서 띄운다.





다음은 Main fxml의 컨트롤러 클래스다.


package app;

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

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class MainController implements Initializable {
	// Stage를 따로 class로 만들어 Static 변수로 선언하여 공용으로 사용한다.
	private Stage stage = StageStore.stage;

	@FXML private Button mainBtn;
	
	@Override
	public void initialize(URL location, ResourceBundle resources) {
		System.out.println("FXML 완");
		
	}
	
	public void move() {
		
		try {
			// 서브페이지 불러오기
			Parent sub = FXMLLoader.load(getClass().getResource("move.fxml"));
			
			// 메인창 지정
			AnchorPane root = (AnchorPane)stage.getScene().getRoot();
			
			// 서브페이지 추가(메인 레이아웃위에 서브 레이아웃을 덮어쓴다.
			root.getChildren().add(sub);
			
		} catch (IOException e) {
			System.out.println("서브페이지 오류");
		}

	}
}






다음은 메인 위에 띄울 sub 컨트롤러다.


package app;

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

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;

public class SubController implements Initializable{

	@FXML private Button subBtn;
	@FXML private AnchorPane subPage;
	
	@Override
	public void initialize(URL location, ResourceBundle resources) {
		System.out.println("FXML 완");
	}
	
	public void closeWin() { // 메인 위에 띄운 레이아웃을 닫는다.
		// 레이아웃을 가져 와서
		// 스테이지를 가져와서 - 씬 추출 - 레이아웃 추출
		AnchorPane root = (AnchorPane) StageStore.stage.getScene().getRoot();
		// 올려놓은 요소를 삭제 한다.
		root.getChildren().remove(subPage);
		
	}

}


Main 사이즈 조절


Scene scene = new Scene(root,200,100);




Pane(200, 100)


Button - Code : fx:id - btn


      On Action - movePage



또 하나 fxml, second라고 명명해서 만든다.





따로 올릴 때 어려운점이 없다고 생각하므로 바로 코드


주석을 자세히 보자


package app;

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

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class MainController implements Initializable{
	@FXML private Button btn;

	@Override
	public void initialize(URL location, ResourceBundle resources) {
		// TODO Auto-generated method stub

	}

	public void movePage() {
		// 새 스테이지 추가
		Stage newStage = new Stage();
		Stage stage = (Stage)btn.getScene().getWindow();

		try {
			/*
			// 1. 새 스테이지 + 새 레이아웃
			// 새 스테이지 생성 -> 새레이아웃 추가 -> 기존 스테이지 닫기

			// 새 레이아웃 추가
			Parent second = FXMLLoader.load(getClass().getResource("second.fxml"));

			// 씬에 레이아웃 추가
			Scene sc = new Scene(second);

			// 씬을 스테이지에서 상영
			newStage.setScene(sc);
			newStage.show();

			// 기존 페이지 삭제
			stage.close();
//			stage.hide(); // 닫지 않고 잠시 숨김, .show()를 통해 다시 볼 수 있음
			 */


			// 2. 기존 스테이지 + 새 레이아웃
			/* 새로만든 레이아웃을 기존 스테이지에 띄움 */
			Parent second = FXMLLoader.load(getClass().getResource("second.fxml"));

			// 씬에 레이아웃 추가
			Scene sc = new Scene(second);
			stage.setScene(sc);
			stage.show();

		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}


















Main은 size만 조정하겠습니다.


Scene scene = new Scene(root,200,200);





fxml을 열어 캡처와 같이 수정


BorderPane Center 위에 AnchorPane


그 위에 Button, Code 부분은 캡쳐와 같이 설정


그리고 나서 fxml을 이름만 custom으로 설정해 새로 만들어서




AnchorPane 위에


Button - Code : fx:id - closebtn


    On Action - close


Label - Code : fx:id - label


위와 같이 추가하고 저장, 닫기 기능을 구현하기 때문에 Controller class 등록을 해준다.


이번에는 컨트롤러 클래스에서 방법 2를 이용해 스테이지를 불러오고


새로운 스테이지를 생성해서 그 위에 팝업을 띄우는 작업을 한다.



package app;

import java.io.IOException;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class MainController {
	@FXML private Button btn;
	@FXML private Button closebtn;
	@FXML private Label label;

	private Stage pop; // 스테이지가 들어갈 변수
	
	public void popup() {
		// 메인 스테이지 취득, 전의 두가지 방법 중 두번째 방법
		Stage mainStage = (Stage)btn.getScene().getWindow(); 
		
		// 새로운 스테이지 생성 (옵션 추가, 스타일)
		Stage pop = new Stage(StageStyle.DECORATED); // 스테이지 옵션
		pop.initModality(Modality.WINDOW_MODAL); // 그 위에 뜨는 모달의 옵션
		pop.initOwner(mainStage); // 메인 스테이지 부여
		
		try {
			// 새로운 스테이지에 custom 레이아웃 불러오기
			Parent root = FXMLLoader.load(getClass().getResource("custom.fxml"));
			
			// 씬에 추가
			Scene sc = new Scene(root);
			pop.setScene(sc);
			pop.setTitle("팝업 띄우기");
			pop.setResizable(false); // 창 사이즈 조절 차단
			
			// 보여주기
			pop.show();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void close() { // 현재의 스테이지를 받아서 close를 해주어야 함
		pop = (Stage)closebtn.getScene().getWindow(); // 버튼을 통해서 현재 스테이지를 알아냄
		pop.close();
	}
}




팝업창을 새로 띄우기 위해서는 여태껏 별로 건들지 않았던 Main을 수정해야 한다.


BorderPane root = (BorderPane)FXMLLoader.load(getClass().getResource("main.fxml"));


기존의 BorderPane인데 이것을 주석 처리하고 다음 코드처럼 추가해준다.


package app;
	
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;


public class Main extends Application {
	@Override
	public void start(Stage primaryStage) {
		try {
//			BorderPane root = (BorderPane)FXMLLoader.load(getClass().getResource("main.fxml"));
//			FXMLLoader.load() <- static, 복사 ㄴㄴ
			// 기존 방식과 다르게 instance 방식을 사용, 복사 가능, 복수의 화면 사용이 가능해진다.
			// 여기부터
			FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
			BorderPane root = loader.load();
			
			/* Stage 취득방법1 (화면제어방법) - Controller에 Stage 전달
			MainController con = loader.getController();
			con.setStage(primaryStage);
			*/
			
			// 여기까지 추가
			
			Scene scene = new Scene(root,200,200); // 창 크기는 마음대로
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			primaryStage.setScene(scene);
			primaryStage.show();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}



다음으로는 main.fxml을 씬 빌더로 열어 다음과 같이 수정한다.


Stage를 받는 방법이 두가지가 있는데 주석 부분을 통해서 확인해보자. (2번째 방법은 Controller 클래스에서)


다음으로 씬 빌더를 열어 fxml 파일을 수정하자







Border Pane Center에 Pane을 올리고


버튼 하나 추가


버튼의 코드는 사진과 같이 설정





이번에는 FXML 파일을 하나 더 추가하여 그걸 팝업으로 띄운다.


추가하는 방법은 다음과 같다.





사진 순서대로 따라서 진행하고 


마지막 화면에서


Source folder는 저장될 경로


Package는 소스 폴더 안의 파일을 만들 패키지


Name은 파일 이름


Root Element는 디자인 할 때 어떤 Pane을 사용할건지 정한다.


Dynamic Root는 생략


Finish를 눌러 생성하고 Scene Builder로 열어서 수정 (필자는 popup이라고 이름을 설정)






popup.fxml을 다음과 같이 배치


HBox - Layout size pref 를 200, 40


Label - Layout size pref 를 200, 40


  - Properties를 아래로 내리면 CSS를 수정할 수 있는데 첫번째 스타일을 캡쳐와 같이 수정


컨트롤러 클래스는 따로 기능을 넣지 않으므로 설정하지 않아도 된다.


원래 CSS는 다루지 않지만 이번에만 색깔 입히는식으로 해보자.


다음으로는 처음 수정한 fxml 파일의 컨트롤러 클래스이다.


컨트롤러에서는 버튼을 눌렀을때 팝업창이 뜨게끔 하고 다른 곳을 눌렀을때 사라지는 설정을 추가한다.


특히 Stage의 정보를 얻는 방법 2번째가 나오니 주의깊게 보자.



package app;

import java.io.IOException;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.stage.Popup;
import javafx.stage.Stage;

public class MainController {
	private Stage Stage;
	@FXML private Button btn;
	
	/* Main에서 Stage 가져오는 방법
	public void setStage(Stage Stage) {
		this.Stage = Stage;
	}
	*/
	
	public void popUp() {
		/* Stage 취득방법2 - Control로 부터 소속 스테이지 취득
		 * 여기서는 버튼을 통해서
		 */
		Stage = (Stage)btn.getScene().getWindow();
		
		
		// 팝업 객체
		Popup pop = new Popup(); // 투명한 틀을 하나 선언한다고 이해하면 된다.
		
		// 레이아웃 생성(팝업)
		try {
			// 아래 코드를 입력하면 try catch문이 필요하다고 나온다.
			Parent root = FXMLLoader.load(getClass().getResource("popup.fxml")); // 저번에 설명한 경로 땡겨오기
			
			// 팝업 객체에 레이아웃 추가
			pop.getContent().add(root);
			pop.setAutoHide(true); // 포커스 이동시 창 숨김
			
			// 팝업 객체에서 스테이지를 보여줌
			pop.show(Stage);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}
}




'JavaFX > 01.Node 추가' 카테고리의 다른 글

[JAVA FX]01-18.여러가지 레이아웃 전환 방법  (2) 2018.09.12
[JAVA FX]01-17.Popup 띄우기2 (방법2)  (0) 2018.09.12
[JAVA FX]01-15.AudioPlayer  (0) 2018.09.12
[JAVA FX]01-14.Media Player  (0) 2018.09.11
[JAVA FX]01-13.BarChart  (0) 2018.09.11

이번에는 음악 플레이어를 만들기 때문에 크기를 조금 줄인다.


Main의 


Scene scene = new Scene(root,400,200);


400, 200 으로 수정




BorderPane Center 부분에 Pane을 올려 사용


Slider - Code : fx:id - seekBar


MediaView - Code : fx:id - mediaView  (모습이 드러나지 않는 노드이기 때문에 아무대나 배치하면 된다.)


Label - Code : fx:id - playList


Label - Code : fx:id - playTime


Button - Code : On Action - open


Button - Code : On Action - play


Button - Code : On Action - pause


Button - Code : On Action - fast


Button - Code : On Action - slow


Button - Code : On Action - start


Button - Code : On Action - last



이번에 만들 Audio Player는 전과 같이 MediaView를 사용하지만 mediaview는 재생하여 소리를 나게 하기 위한 ui로 


따로 모습이 필요없다.


고로 아무대나 배치하면 되고 각 버튼을 통해서 선택한 음악의 재생관리를 구현한다.


특별한것은 예전에 배웠던 split이나 (long)과 같은 명시적 형변환 등 쓰이는게 많다.


그리고 버튼 play에 거의 모든 기능이 쓰이므로 play 함수를 유심히 보자.



package app;

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

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;

public class MainController implements Initializable{

	@FXML private Slider seekBar;
	@FXML private Label playList;
	@FXML private Label playTime;
	@FXML private MediaView mediaView;
	Media media;
	MediaPlayer player;

	String mediaPath;
	long totalTime, currentTime;

	@Override
	public void initialize(URL location, ResourceBundle resources) {
		System.out.println("FXML 완");
		seekBar.setValueChanging(true); // 외부에서 슬라이더바 조작 가능
		seekBar.setValue(0);
	}

	public void open() {
		FileChooser fc = new FileChooser();
		fc.setTitle("음악 파일 선택");
		fc.setInitialDirectory(new File("C:/")); // 기본 경로
		// 확장자 필터링(선택)
		ExtensionFilter filter = new ExtensionFilter("audio", "*.mp3");
		fc.getExtensionFilters().add(filter);


		File selectedFile = fc.showOpenDialog(null); // 창 위치 및 불러운 파일 삽입
		mediaPath = selectedFile.toURI().toString();
		System.out.println("선택한 경로 : " + mediaPath);

		// playList에 재생할 파일명 출력
		String[] token = mediaPath.split("/");
		// 공백의 경우 %20으로 표시되어 공백으로 바꿔주고 넣는다.
		String musicName = token[token.length-1].replaceAll("%20",  " ");
		// 리스트에 삽입
		playList.setText(musicName);

		// 미디어 등록 - 플레이어 등록 - 뷰에 등록
		media = new Media(mediaPath);
		player = new MediaPlayer(media);
		player.setAutoPlay(false); // 자동실행 false, play 버튼을 누를 시 음악이 재생되게끔
		mediaView = new MediaView(player);
	}

	public void play() {
		currentTime = 0;
		totalTime = 0;
		player.play();
		player.setRate(1); // 재생속도 기본 (1), 디폴트값
		totalTime = (long) player.getTotalDuration().toSeconds(); // 노래가 몇초짜리인지 반환
		System.out.println(totalTime);

		// 슬라이더를 움직이기 위한 스레드 생성
		// 스레드가 별개로 돌아가기 때문에 재생하고 창을 종료하면 계속 재생되는 상태이다.
		Thread th = new Thread(()-> {
			while(currentTime < totalTime) { // 재생시간에 따라 스레드 종료
				currentTime = (long)player.getCurrentTime().toSeconds();
				Platform.runLater(()->{
					seekBar.setValue((double)currentTime/totalTime*100);
					playTime.setText(currentTime + "/" + totalTime);
				});
				// sleep 0.3초를 주어서 좀 더 안정감있게 slidebar를 제어
				// 없다면 계산이 너무 빠르기 때문에 불안정
				try {
					Thread.sleep(300);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} 
			}
			player.stop();
		});
		th.start();
	}

	public void pause() {
		player.pause();
	}

	public void fast() { // 0.5배 빠르거나 느리게, 숫자를 변수로 받아 선언하여 활용 가능 
		player.setRate(1.5);
	}

	public void slow() {
		player.setRate(0.5);
	}

	public void start() { // 첫 시간대로 이동
		player.seek(player.getStartTime());
	}

	public void last() { // 마지막 시간대로 이동
		player.seek(player.getTotalDuration());
	}

}












token[token.length-1].replaceAll("%20",  " ");


위의 코드에 replaceAll을 사용하지 않으면 띄어쓰기가 %20처럼 이상하게 출력되는것을 방지 할 수 있다.




슬라이더를 통해서 조절하는 여러가지 기능은 직접 만들어보시길... 어렵지않다.









'JavaFX > 01.Node 추가' 카테고리의 다른 글

[JAVA FX]01-17.Popup 띄우기2 (방법2)  (0) 2018.09.12
[JAVA FX]01-16.Popup 띄우기 (방법 1,2)  (0) 2018.09.12
[JAVA FX]01-14.Media Player  (0) 2018.09.11
[JAVA FX]01-13.BarChart  (0) 2018.09.11
[JAVA FX]01-12.Line Chart, Random  (0) 2018.09.11

Main은 그대로 냅두고 





Border Pane Center 위에 Pane(400, 400)


Pane 위에 


MediaView - Code : fx:id - mediaView


Button - Code : On Action - fileOpen


Controller class 설정으로 마치고 코딩



package app;

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

import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;

public class MainController implements Initializable{
	
	@FXML private MediaView mediaView;
	
	Media media;
	MediaPlayer player;

	@Override
	public void initialize(URL location, ResourceBundle resources) {
		System.out.println("FXML 완");
	}
	
	public void fileOpen() {
		// 파일 선택창
		FileChooser fc = new FileChooser();
		fc.setTitle("미디어 선택");
		fc.setInitialDirectory(new File("C:/"));
		
		// 확장자 필터링(선택 사항)
		ExtensionFilter audioType = new ExtensionFilter("오디오", "*.mp3");
		ExtensionFilter videoType = new ExtensionFilter("비디오", "*.mp4", "*.avi");
		fc.getExtensionFilters().addAll(audioType, videoType);
		
		// 띄우기
		File selectedFile = fc.showOpenDialog(null); // 창위치 null은 최상단 좌측을 의미
//		System.out.println(selectedFile.toString());
		System.out.println(selectedFile.toURI().toString());
		String path = selectedFile.toURI().toString();
		
		// 미디어 생성 -> 플레이어 등록 -> 뷰에 등록
		media = new Media(path);
		player = new MediaPlayer(media);
		mediaView.setMediaPlayer(player);
		mediaView.setLayoutX(media.getWidth());
		mediaView.setLayoutY(media.getHeight());
		player.setAutoPlay(true);
		
		// 크기 조정, 창의 크기에 따라서 영상 사이즈 변경
		DoubleProperty width = mediaView.fitWidthProperty();
		DoubleProperty height = mediaView.fitHeightProperty();
		
		width.bind(Bindings.selectDouble(mediaView.sceneProperty(), "width"));
		height.bind(Bindings.selectDouble(mediaView.sceneProperty(), "height"));
	}	
}



설명은 코드의 주석


'JavaFX > 01.Node 추가' 카테고리의 다른 글

[JAVA FX]01-16.Popup 띄우기 (방법 1,2)  (0) 2018.09.12
[JAVA FX]01-15.AudioPlayer  (0) 2018.09.12
[JAVA FX]01-13.BarChart  (0) 2018.09.11
[JAVA FX]01-12.Line Chart, Random  (0) 2018.09.11
[JAVA FX]01-11.PieChart  (0) 2018.09.11

Main은 터치 하지 않고 FXML





BoderPane Center위에 Pane(400, 400) 추가


BarChart - Code : fx:id - chart


   상황에 따라서 Properties에서 Animate를 끄면 더 자연스러울 수 있음


BarChart의 + 버튼을 눌러 펼치면 나오는 CategoryAxis - Code : fx:id - Xaxis


Button - Code : fx:id - style1


Button - Code : fx:id - style2




package app;

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

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.XYChart;

public class MainController implements Initializable{
	// Number은 다른 숫자형의 최상위, Integer, Long, Float, Double 다 사용가능, 다형성
	@FXML private BarChart<String, Number> chart; // 제네릭은 X, Y축
	@FXML private CategoryAxis Xaxis; // X축
	
	// 카테고리의 레이블을 담을 자료 구조
	String[] cates = {"속도", "평점", "주행거리", "안정성"};
	
	// 시리즈를 담을 자료 구조
	XYChart.Series<String, Number> series = null; // 그래프의 값을 담을 series 변수
	private ObservableList<String> xLables = FXCollections.observableArrayList(); // 카테고리를 만들 xLables 배열 변수 
	
	@Override
	public void initialize(URL location, ResourceBundle resources) {
		System.out.println("FXML 완");
		xLables.addAll(Arrays.asList(cates)); // 한번에 다 넣기, add로 하나씩 넣어도 됨
		Xaxis.setCategories(xLables);
	}
	
	public void style1() { // 바 하나짜리 차트
		// 바 추가
		series = new XYChart.Series<String, Number>();
		// 기존 차트 초기화
		chart.getData().clear(); 
		// 바의 이름 설정
		series.setName("자동차");
		// 데이터 생성
		for(int i = 0; i < cates.length; i++) {
			series.getData().add(new XYChart.Data<String, Number>(xLables.get(i), random()));
		}
		// 차트에 추가
		chart.getData().add(series);
	}
	
	// 여러개의 바 추가
	public void style2() {
		// 시리즈를 여러개(4개) 생성
		chart.getData().clear(); // 차트 초기화, 안하면 바가 계속 추가됨 
		String[] names = {"코인", "떡락", "열차", "뿜붐"};
		for(int i = 0; i < names.length; i++) {
			// 시리즈를 여러개(4개) 생성
			series = new XYChart.Series<String, Number>();
			// 시리즈의 이름(4개) 생성
			series.setName(names[i]);
			// 시리즈별 데이터 생성(4개)
			for(int j = 0; j < cates.length; j++) {
				series.getData().add(new XYChart.Data<String, Number>(xLables.get(j), random()));
			}
			// 차트에 추가
			chart.getData().add(series);
		}
	}
	
	// 임의의 값을 추출
	public int random() {
		Random rand = new Random();
		return rand.nextInt(9) + 1; // 1~100의 랜덤값
	}
}


스타일 1을 누를 경우 각 카테고리에 바가 1가지 생성되며


스타일 2를 누르면 4개씩 생성된다.


'JavaFX > 01.Node 추가' 카테고리의 다른 글

[JAVA FX]01-15.AudioPlayer  (0) 2018.09.12
[JAVA FX]01-14.Media Player  (0) 2018.09.11
[JAVA FX]01-12.Line Chart, Random  (0) 2018.09.11
[JAVA FX]01-11.PieChart  (0) 2018.09.11
[JAVA FX]01-10.Progress Bar, Progress Indicator, Thread  (0) 2018.09.11

Main에는 따로 터치없이 Scene Builder




BorderPane의 Center 위에 Pane(400, 400)을 하나 배치


그 위에


LineChart - Code : fx:id - linechart


Button - code : On Action - multiChart


Controller class 설정 후 코딩



package app;

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

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.XYChart;

public class MainController implements Initializable{

	@FXML LineChart<String, Integer> lineChart; // Generic은 차트의 X축과 Y축을 의미 
	XYChart.Series<String, Integer> series = null;

	
	@Override
	public void initialize(URL location, ResourceBundle resources) {
		System.out.println("FXML 완");
		drawChart();
	}
	
	// 차트 그리기
	public void drawChart() {
		series = new XYChart.Series<String, Integer>();
		series.getData().add(new XYChart.Data<String, Integer>("1차", 30)); // 특징으로 무엇을 할 때마다 getData
		series.getData().add(new XYChart.Data<String, Integer>("2차", 50));
		series.getData().add(new XYChart.Data<String, Integer>("3차", 20));
		series.getData().add(new XYChart.Data<String, Integer>("4차", 70));
		series.setName("Month Pay");
		// 라인차트에 시리즈 추가
		lineChart.getData().add(series); // 다른 라인을 추가하고 싶으면 다른 series 만들면 된다.
		
		series = new XYChart.Series<String, Integer>();
		series.getData().add(new XYChart.Data<String, Integer>("1차", 150)); // 특징으로 무엇을 할 때마다 getData
		series.getData().add(new XYChart.Data<String, Integer>("2차", 120));
		series.getData().add(new XYChart.Data<String, Integer>("3차", 140));
		series.getData().add(new XYChart.Data<String, Integer>("4차", 180));
		series.setName("Year Pay");
		// 라인차트에 시리즈 추가
		lineChart.getData().add(series); // 다른 라인을 추가하고 싶으면 다른 series 만들면 된다.
		
		
	}
	
	public void multiChart() {
		 // 기존 라인 제거
		lineChart.getData().clear();
		series = null;
		for(int i = 0; i < 4; i++) {
			// 새로운 시리즈 만들기
			series = new XYChart.Series<String, Integer>();
			// 새로운 데이터 추가(5개)
			for(int j = 1; j < 6; j++) {
				series.getData().add(new XYChart.Data<String, Integer>(j + "차", 30 + random()));
			}
			series.setName("pay " + i);
			// 라인 차트에 추가
			lineChart.getData().add(series);
		}
	}
	
	// 임의의 값을 추출
	public int random() {
		Random rand = new Random();
		return rand.nextInt(100); // 1~100의 랜덤값
	}
}


랜덤 값을 얻을때엔 Random을 객체화하여 nextInt(범위) 메소드를 사용


결과는 LineChart 하나가 나올것이고 버튼을 누르면 새로운 차트 항목이 추가된다

+ Recent posts