JAVA chapter17. javaFX. 17.11 JavaFX 스레드 동시성
JAVA/CONCEPT 2018. 1. 16. 16:34 |JAVA chapter17. javaFX.
17.11 JavaFX 스레드 동시성
17.11.1 Platform.runLater() 메소드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.*?> <?import javafx.scene.control.*?> <AnchorPane xmlns:fx="http://javafx.com/fxml" prefHeight="100.0" prefWidth="200.0" fx:controller="sec11.exam01_runlater.RootController"> <children> <Label fx:id="lblTime" alignment="CENTER" layoutX="25.0" layoutY="15.0" prefHeight="35.0" prefWidth="150.0" style="-fx-background-color: black; -fx-text-fill: yellow; -fx-font-size: 20; -fx-background-radius: 10;" text="00:00:00" /> <Button fx:id="btnStart" layoutX="46.0" layoutY="63.0" text="시작" /> // 여기에 onaction 메소드를 넣어서 지정해도됨 <Button fx:id="btnStop" layoutX="110.0" layoutY="63.0" text="멈춤" /> </children> </AnchorPane> | cs |
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 41 42 43 44 45 46 47 48 49 50 | package sec11.exam01_runlater; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.ResourceBundle; import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.Label; public class RootController implements Initializable { // Controller 클래스를 구현하려면 Initializable 인터페이스를 구현해야함 @FXML private Label lblTime; @FXML private Button btnStart; @FXML private Button btnStop; private boolean stop; @Override public void initialize(URL location, ResourceBundle resources) { btnStart.setOnAction(event->handleBtnStart(event)); btnStop.setOnAction(event->handleBtnStop(event)); } public void handleBtnStart(ActionEvent e) { // 시간이 흘러가는 java Application thread가 해버리면 다른 작업이 안된다 stop = false; // 계속적으로 무언가를 해야할경우에는 작업자 thread를 만들어서 해야한다 Thread thread = new Thread() { @Override public void run() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); while(!stop) { String strTime = sdf.format(new Date()); Platform.runLater(()->{ // UI 변경 작업 lblTime.setText(strTime); }); try { Thread.sleep(100); } catch (InterruptedException e) {} // 너무빨리돌면안되니까 1초에 한번씩 쉬는걸로 } }; }; thread.setDaemon(true); thread.start(); } public void handleBtnStop(ActionEvent e) { stop = true; } } | cs |
17.11.2 Task 클래스
1. cancel() 메소드를 호출 했을 때
2. 일시정지 상태에서 Interrupt()를 호출 했을 때
AppMain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package sec11.exam02_task; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class AppMain 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); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.*?> <?import javafx.scene.control.*?> <AnchorPane xmlns:fx="http://javafx.com/fxml" prefHeight="129.0" prefWidth="233.0" fx:controller="sec11.exam02_task.RootController"> <children> <ProgressBar fx:id="progressBar" layoutX="17.0" layoutY="23.0" prefWidth="200.0" progress="0.0" /> <Label fx:id="label" layoutX="18.0" layoutY="57.0" text="진행정도:" /> <Label fx:id="lblWorkDone" layoutX="77.0" layoutY="57.0" /> <Button fx:id="btnStart" layoutX="66.0" layoutY="91.0" text="시작" /> <Button fx:id="btnStop" layoutX="130.0" layoutY="91.0" text="멈춤" /> </children> </AnchorPane> | cs |
RootController.java
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | package sec11.exam02_task; import java.net.URL; import java.util.ResourceBundle; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ProgressBar; public class RootController implements Initializable { @FXML private ProgressBar progressBar; @FXML private Label lblWorkDone; @FXML private Button btnStart; @FXML private Button btnStop; private Task<Void> task; @Override public void initialize(URL location, ResourceBundle resources) { btnStart.setOnAction(event->handleBtnStart(event)); btnStop.setOnAction(event->handleBtnStop(event)); } public void handleBtnStart(ActionEvent e) { task = new Task<Void>() { @Override protected Void call() throws Exception { for(int i=0; i<=100; i++) { if(isCancelled()) { updateMessage("취소됨"); break; } updateProgress(i, 100); // Task의 progress 속성 업데이트 updateMessage(String.valueOf(i)); // Task의 message 속성 업데이트 try {Thread.sleep(100); } catch(InterruptedException e) { if(isCancelled()) { updateMessage("취소됨"); break; } } } return null; } }; progressBar.progressProperty().bind(task.progressProperty()); // 속성 바인딩 lblWorkDone.textProperty().bind(task.messageProperty()); Thread thread = new Thread(task); // 작업 스레드 시작 thread.setDaemon(true); thread.start(); } public void handleBtnStop(ActionEvent e) { task.cancel(); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.control.*?> <AnchorPane xmlns:fx="http://javafx.com/fxml" prefHeight="129.0" prefWidth="233.0" fx:controller="sec11.exam03_task_callback.RootController"> <children> <ProgressBar fx:id="progressBar" layoutX="17.0" layoutY="23.0" prefWidth="200.0" progress="0.0" /> <Label layoutX="18.0" layoutY="57.0" text="진행정도:" /> <Label fx:id="lblWorkDone" layoutX="77.0" layoutY="57.0" /> <Label layoutX="118.0" layoutY="57.0" text="작업결과:" /> <Label fx:id="lblResult" layoutX="175.0" layoutY="57.0" /> <Button fx:id="btnStart" layoutX="66.0" layoutY="91.0" text="시작" /> <Button fx:id="btnStop" layoutX="130.0" layoutY="91.0" text="멈춤" /> </children> </AnchorPane> | cs |
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | package sec11.exam03_task_callback; import java.net.URL; import java.util.ResourceBundle; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ProgressBar; public class RootController implements Initializable { @FXML private ProgressBar progressBar; @FXML private Label lblWorkDone; @FXML private Label lblResult; @FXML private Button btnStart; @FXML private Button btnStop; private Task<Integer> task; @Override public void initialize(URL location, ResourceBundle resources) { btnStart.setOnAction(event->handleBtnStart(event)); btnStop.setOnAction(event->handleBtnStop(event)); } public void handleBtnStart(ActionEvent e) { task = new Task<Integer>() { @Override protected Integer call() throws Exception { int result = 0; for(int i=0; i<=100; i++) { if(isCancelled()) { break; } result += i; updateProgress(i, 100); // Task의 progress와 message 속성을 업데이트 updateMessage(String.valueOf(i)); try {Thread.sleep(100); } catch(InterruptedException e) { if(isCancelled()) { break; } } } return result; } @Override protected void succeeded() { lblResult.setText(String.valueOf(getValue())); } @Override protected void cancelled() { lblResult.setText("취소됨"); } @Override protected void failed() { lblResult.setText("실패"); } }; progressBar.progressProperty().bind(task.progressProperty()); // 속성 바인딩 lblWorkDone.textProperty().bind(task.messageProperty()); // 속성 바인딩 lblResult.setText(""); Thread thread = new Thread(task); thread.setDaemon(true); thread.start(); } public void handleBtnStop(ActionEvent e) { task.cancel(); // 작업 취소 } } | cs |
17.11.3 Service 클래스
'JAVA > CONCEPT' 카테고리의 다른 글
JAVA chapter18. IO 기반 입출력 및 네트워킹. 18.1 IO 패키지 소개, 18.2 입력 스트림과 출력 스트림 (0) | 2018.01.16 |
---|---|
JAVA chapter17. javaFX. 17.12 화면 이동과 애니메이션 (0) | 2018.01.16 |
JAVA chapter17. javaFX. 17.10 JavaFX CSS 스타일(1) (0) | 2018.01.16 |
JAVA chapter17. javaFX. 17.9 JavaFX 다이얼로그 // 다시 (0) | 2018.01.16 |
JAVA chapter17. javaFX. 17.8 JavaFX 메뉴바와 툴바 (0) | 2018.01.16 |