JavaFX를 사용해서 간단한 계산기를 만들어 보겠습니다.
자료 구조는 다음과 같습니다.
Main.java
Main.fxml
MainController.java
Model.java
1. Main.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 | package application; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage primaryStage) { try { Parent root = FXMLLoader.load(getClass().getResource("/application/Main.fxml")); Scene scene = new Scene(root,400,400); 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); } } | cs |
이 파일은 Application 을 상속 받아 구성되었습니다. 기본적으로 생성된 소스에서 14번 라인만 수정했습니다.
2. Main.fxml
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 | <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.text.*?> <?import javafx.scene.control.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.layout.AnchorPane?> <VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="300.0" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController"> <children> <StackPane prefHeight="50.0" prefWidth="300.0"> <children> <Label fx:id="result" prefHeight="19.0" prefWidth="339.0"> <font> <Font name="System Bold" size="18.0" /> </font> </Label> </children></StackPane> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="300.0" spacing="10.0"> <children> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="50.0" text="7"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="50.0" text="8"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="50.0" text="9"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processOperators" prefWidth="50.0" text="/"> <font> <Font size="18.0" /> </font> </Button> </children> </HBox> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="300.0" spacing="10.0"> <children> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="50.0" text="4"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="50.0" text="5"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="50.0" text="6"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processOperators" prefWidth="50.0" text="*"> <font> <Font size="18.0" /> </font> </Button> </children> </HBox> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="300.0" spacing="10.0"> <children> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="50.0" text="1"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="50.0" text="2"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="50.0" text="3"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processOperators" prefWidth="50.0" text="-"> <font> <Font size="18.0" /> </font> </Button> </children> </HBox> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="300.0" spacing="10.0"> <children> <Button mnemonicParsing="false" onAction="#processNumbers" prefWidth="110.0" text="0"> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processOperators" prefWidth="50.0" text="="> <font> <Font size="18.0" /> </font> </Button> <Button mnemonicParsing="false" onAction="#processOperators" prefWidth="50.0" text="+"> <font> <Font size="18.0" /> </font> </Button> </children> </HBox> </children> </VBox> | cs |
fxml 파일에서 핵심은 VBox 와 HBox 를 사용해서 버튼들을 규칙적으로 배치하였다는 것입니다. 이외에는 그냥 버튼을 배치하는 것과 다름이 없습니다.
Scene Builder 로 보면 위와 같이 버튼을 배치 하였습니다. 컨트롤러는 MainController 로 설정해 놓았으며, 숫자 버튼과 연산자 버튼을 따로 묶어서 On Action 을 일괄 적용했습니다. 하나씩 적용해도 상관없지만 일괄적으로 처리하니까 편해서 좋았습니다.
3. Model.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 | package application; public class Model { public float calculate(long number1, long number2, String operator) { switch (operator) { case "+": return number1 + number2 ; case "-": return number1 - number2 ; case "*": return number1 * number2 ; case "/": if(number2 == 0){ return 0; } return number1 / number2 ; default: return 0; } } } | cs |
모델 클래스에서는 연산자들의 기능을 정의하였습니다. float 타입을 반환하는 메소드 calculate 를 만들었습니다. calculate 메소드는 long 타입의 숫자 2개와 String 타입의 연산자 1개를 매개변수로 작동하는 메소드 입니다. switch 구문을 사용하여 입력된 연산자의 종류에 따라서 입력된 숫자들이 처리됩니다. 나누기의 경우 0으로 나눌수 없기 때문에 0을 리턴하도록 코드를 짰습니다.
4. MainController.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 | package application; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.Label; public class MainController { @FXML private Label result; private long number1 = 0; private String operator = ""; private boolean start = true; private Model model = new Model(); @FXML public void processNumbers(ActionEvent event) { if(start){ result.setText(""); start = false; } String value = ((Button)event.getSource()).getText(); result.setText(result.getText() + value); } @FXML public void processOperators(ActionEvent event) { String value = ((Button)event.getSource()).getText(); if(!value.equals("=")){ if(!operator.isEmpty()){ return; } operator = value; number1 = Long.parseLong(result.getText()); result.setText(""); }else{ if(operator.isEmpty()){ return; } long number2 = Long.parseLong(result.getText()); float ouput = model.calculate(number1, number2, operator); result.setText(String.valueOf(ouput)); operator = ""; start = true; } } } | cs |
(라인 23) 숫자 버튼을 누르면 버튼의 text 값을 가져와서 value 변수에 저장 합니다.
(라인 24) 라벨에 입력되어 있는 값에 value 값을 붙여서 라벨에 입력합니다.
(라인 30~) 연산자 버튼을 눌렀을때 해당 연산자가 '=' 이 아니면 operator 변수에 해당 연산자를 입력합니다.
(라인 38~) '=' 버튼을 눌렀다면, 라벨에 입력되어 있는 값을 number2에 저장하고, 모델클래스의 calculate 메소드를 호출합니다. 그리고 그 결과값을 라벨에 표시합니다.
'Java > JavaFx' 카테고리의 다른 글
JavaFx 11. ImageView 사용하기 (0) | 2016.08.17 |
---|---|
JavaFx 10. 로그인 기능 만들기 (0) | 2016.08.17 |
JavaFx 07. CSS 스타일 하기 (0) | 2016.08.12 |
JavaFx 06. Scene Builder 로 events 설정하기 (0) | 2016.08.12 |
JavaFx 05. Scene Builder 설치 및 사용하기 (2) | 2016.08.12 |