이론
자바FX
***혹시 RUN하는데 targetException이 뜬다면, 각 모듈의 id와 UI멤버 변수들이 일치하는지 확인할 것 ***
단위작업 : 하나의 통합된 작업을 세부단위로 분해하여, 가장 작은 단위의 직업을 말한다.
javafx에서의 스레드 핸들링
1.Platform.runLater()( == handler.post)
2.Task(바인딩 개념 : Runnable 인터페이스를 상속)
call() -> 스레드를 핸들링한다(진짜 스레드가 해야하는 일)
successed() -> UI처리 -> Update()/UI값 바인딩
cancle()
service()
3.Service
안드로이드에서 Thread가 safe한가?
safe하지 않다. 안드로이드 자체에서는, UI Thread를 기본 스레드로 핸들링 했을 때 과부하가 걸릴 수 있기 때문.
Thread UI Handler와 Thread 안에서 handler.post를 이용해 handler와 통신하는 방법이 있고, 두번째로 AsynchTask가 있다.
모델 == 안드로이드의 베이스어댑터
실습
stackpandemo0525.FXMLDocumentController.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 | package stackpandemo0525; import java.net.URL; import java.util.ResourceBundle; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.StackPane; public class FXMLDocumentController implements Initializable { @FXML private Label label; //UI멤버 @FXML private Button nextBtn,prevBtn; @FXML private StackPane rootP; private ObservableList<Node> childs; private Node firstNode, secondNode, tableNode; @Override public void initialize(URL url, ResourceBundle rb) { childs = this .rootP.getChildren(); firstNode = childs.get(childs.size()- 1 ); secondNode = childs.get(childs.size()- 2 ); } @FXML private void nextButtonAction(ActionEvent event) { firstNode.setVisible( false ); firstNode.toBack(); secondNode.setVisible( true ); } @FXML private void prevButtonAction(ActionEvent event) { secondNode.setVisible( false ); secondNode.toBack(); firstNode.setVisible( true ); } } |
stackpaneex.FXMLDocumentController.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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | package stackpaneex; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ListView; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.StackPane; public class FXMLDocumentController implements Initializable { @FXML private Button listBtn; @FXML private Button tableBtn; @FXML private Button tablePreBtn; @FXML private Button listPreBtn; @FXML private StackPane rootP; @FXML private ListView listview; @FXML private TableView tableview; Node firstNode; Node secondNode; Node threeNode; @FXML private void handleButtonAction(ActionEvent event) { System.out.println( "You clicked me!" ); } @FXML private void listViewButtonAction(ActionEvent event) { System.out.println( "listViewButtonAction clicked!" ); firstNode.setVisible( false ); firstNode.toBack(); threeNode.toBack(); //다음 node를 활성화 시킨다. secondNode.setVisible( true ); List<String> listData = new ArrayList<>(); for ( int i = 0 ; i < 20 ; i++){ listData.add( "My data : XData" +i); } listview.setItems(FXCollections.observableArrayList(listData)); } @FXML private void tableViewButtonAction(ActionEvent event) { System.out.println( "tableViewButtonAction clicked!" ); firstNode.setVisible( false ); firstNode.toBack(); secondNode.toBack(); threeNode.setVisible( true ); List<Phone> pList = new ArrayList<>(); for ( int i = 0 ; i < 20 ; i++){ pList.add( new Phone(( "갤럭시노트" +i), "phone" +i+ ".png" )); } ObservableList phoneList = FXCollections.observableArrayList(pList); TableColumn smartPhone = (TableColumn) tableview.getColumns().get( 0 ); smartPhone.setCellValueFactory( new PropertyValueFactory( "smartPhone" )); TableColumn smartImage = (TableColumn) tableview.getColumns().get( 1 ); smartImage.setCellValueFactory( new PropertyValueFactory( "Image" )); tableview.setItems(phoneList); } @FXML private void tablePreButtonAction(ActionEvent event) { System.out.println( "tablePreButtonAction clicked!" ); threeNode.setVisible( false ); threeNode.toBack(); firstNode.toFront(); firstNode.setVisible( true ); } @FXML private void listPreButtonAction(ActionEvent event) { System.out.println( "listPreButtonAction clicked!" ); secondNode.setVisible( false ); secondNode.toBack(); firstNode.toFront(); firstNode.setVisible( true ); } @Override public void initialize(URL url, ResourceBundle rb) { // TODO //StackPane의 자식노드를 모두 가져온다. ObservableList<Node> childs = this .rootP.getChildren(); //첫번째 node : 제일 처음 보이는 pane(next) System.out.println( "test childs size ======= : " + childs.size()); firstNode = childs.get(childs.size()- 1 ); //두번째 node : 숨겨진 pane(prev) secondNode = childs.get(childs.size()- 2 ); threeNode = childs.get(childs.size()- 3 ); } } |
stackpaneex.Phone.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 | package stackpaneex; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleStringProperty; public class Phone { //SimpleXXPreperty : FX자료형 private SimpleStringProperty smartPhone; private SimpleStringProperty image; private SimpleIntegerProperty price; public Phone(String smartPhone, String image){ this .smartPhone = new SimpleStringProperty(smartPhone); this .image = new SimpleStringProperty(image); this .price = new SimpleIntegerProperty( 100000 ); } public String getSmartPhone(){ return smartPhone.get(); } public void setSmartPhone(String smartPhone){ this .smartPhone.set(smartPhone); } public String getImage(){ return image.get(); } public void setImage(String image){ this .image.set(image); } public int getPrice(){ return price.get(); } public void setPrice( int price){ this .price.set(price); } } |
threaduidemo0525.FXMLDocumentController.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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | package threaduidemo0525; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Platform; import javafx.concurrent.Service; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Label; public class FXMLDocumentController implements Initializable { @FXML private Label label; boolean flag; private CustomService service; @FXML private void handleButtonAction(ActionEvent event) { System.out.println( "You clicked me!" ); label.setText( "Hello World!" ); } @FXML private void startButtonAction(ActionEvent event){ SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-mm-dd HH:mm:ss" ); flag = false ; Thread th = new Thread( new Runnable() { @Override public void run() { while (!flag){ String times = sdf.format( new Date()); System.out.println(times); //Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4 Platform.runLater( new Runnable() { @Override public void run() { label.setText(times); } }); try { Thread.sleep( 200 ); } catch (InterruptedException ex) { ex.printStackTrace(); } } } }); th.setDaemon( true ); th.start(); } @FXML private void stopButtonAction(ActionEvent event){ flag = true ; System.out.println( "stopButtonAction clicked" ); } @Override public void initialize(URL url, ResourceBundle rb) { // TODO service = new CustomService(); } @FXML private void startButtonAction2(ActionEvent event){ service.start(); } @FXML private void stopButtonAction2(ActionEvent event){ flag = true ; service.cancel(); } class CustomService extends Service<String>{ @Override protected Task<String> createTask(){ System.out.println( "Clicked Task" ); SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); flag = false ; // step 2) task Task<String> task = new Task<String>(){ @Override protected String call() throws Exception { System.out.println( "Clicked call" ); String times = null ; while (!flag){ System.out.println( "Clicked flag" + flag); times = sdf.format( new Date()); //updateMessage(times) : call()가 호출되는 값을 bind를 통해서 //succeeded() 전달한다. updateMessage(times); try { Thread.sleep( 200 ); } catch (InterruptedException ex){ if (isCancelled()){ break ; } ex.printStackTrace(); } } return times; } }; //라벨에 값을 전달하기 위해서 bind 한다. label.textProperty().bind(task.messageProperty()); return task; } //성공적으로 call()의 값이 전달 되었을 때 //cancelled() -> cancle()호출 시 , failed() : 예외발생시 @Override public void succeeded(){ System.out.println( "value : " + getValue()); label.setText( "value : " + getValue()); } } } |
threaduidemo0525.threaduidemo0525.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 | package threaduidemo0525; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class ThreadUIDemo0525 extends Application { @Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource( "TreadFXML.fxml" )); Scene scene = new Scene(root); //StyleSheet 추가 scene.getStylesheets().add(getClass().getResource( "app.css" ).toString()); stage.setTitle( "ThreadDemo" ); stage.setScene(scene); stage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } |
threaduidemo0525.app.css
1 2 3 4 5 6 7 8 9 | Label{ -fx- padding : 5 ; -fx- color : red ; } .button:hover{ -fx- border-width : 1 ; -fx-border-radius: 20 ; -fx- background-color : linear-gradient( #2A5058 , #61a2b1 ) } |
'학원수업 > 자바' 카테고리의 다른 글
학원 46일차 복습(5/23) (0) | 2018.05.23 |
---|---|
학원 13일차 복습(3/30) (0) | 2018.03.30 |
학원 12일차 복습(3/29) (0) | 2018.03.30 |
학원 11일차 복습(3/28) (0) | 2018.03.28 |
학원 10일차 복습(3/27) (0) | 2018.03.27 |