diff --git a/ch_31/exercise31_02/Exercise31_02.java b/ch_31/exercise31_02/Exercise31_02.java index 964cdf9..e3bafda 100644 --- a/ch_31/exercise31_02/Exercise31_02.java +++ b/ch_31/exercise31_02/Exercise31_02.java @@ -15,7 +15,10 @@ public class Exercise31_02 extends Application { @Override public void start(Stage primaryStage) throws Exception { System.out.println("##-_-_--_--_--__-_-- Starting: Exercise31_02 --_-__--__--__--_--_--##"); - Platform.runLater(() -> new Exercise31_02Server().start(new Stage())); - Platform.runLater(() -> new Exercise31_02Client().start(new Stage())); + new Thread(() -> { + Platform.runLater(() -> new Exercise31_02Server().start(new Stage())); + Platform.runLater(() -> new Exercise31_02Client().start(new Stage())); + }).start(); + } } diff --git a/ch_31/exercise31_02/Exercise31_02Client.java b/ch_31/exercise31_02/Exercise31_02Client.java index a0b44a1..0deccd3 100644 --- a/ch_31/exercise31_02/Exercise31_02Client.java +++ b/ch_31/exercise31_02/Exercise31_02Client.java @@ -1,106 +1,92 @@ package ch_31.exercise31_02; import javafx.application.Application; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.geometry.HPos; import javafx.geometry.Pos; -import javafx.geometry.VPos; import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TextArea; -import javafx.scene.control.TextField; +import javafx.scene.control.*; +import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.stage.Stage; -import java.io.*; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.net.Socket; - public class Exercise31_02Client extends Application { - private TextField weightTextInput = new TextField(); - private TextField heightTextInput = new TextField(); - private TextArea displayResultTextArea = new TextArea(); + DataOutputStream toServer = null; + DataInputStream fromServer = null; - private Button submitButton = new Button("Submit"); + // Text fields for BMI information + private TextField tfWeight = new TextField(); + private TextField tfHeight = new TextField(); - // Host name or ip - String host = "localhost"; + @Override // Override the start method in the Application class + public void start(Stage primaryStage) { + // Main pane + BorderPane pane = new BorderPane(); - private ObjectOutputStream toServer; - private DataInputStream fromServer; + // Set text field alignment right + tfWeight.setAlignment(Pos.BASELINE_RIGHT); + tfHeight.setAlignment(Pos.BASELINE_RIGHT); - public Exercise31_02Client() { - System.out.println("##-_-_--_--_--__-_-- Starting: Exercise31_02Client --_-__--__--__--_--_--##"); - } + // Create button to send BMI info to server + Button btSubmit = new Button("Submit"); - @Override - public void start(Stage primaryStage) { - Stage stage = new Stage(); - GridPane pane = new GridPane(); - pane.add(new Label("Weight in pounds"), 0, 0); - pane.add(weightTextInput, 1, 0); - pane.add(new Label("Height in inches"), 0, 1); - pane.add(heightTextInput, 1, 1); - pane.add(submitButton, 1, 3); - pane.add(displayResultTextArea, 1, 4); - GridPane.setHalignment(submitButton, HPos.RIGHT); - GridPane.setValignment(displayResultTextArea, VPos.BOTTOM); - pane.setAlignment(Pos.CENTER); - weightTextInput.setPrefColumnCount(15); - heightTextInput.setPrefColumnCount(15); - submitButton.setOnAction(new ButtonListener()); - - Scene scene = new Scene(pane, 450, 200); - stage.setTitle("BMI Client"); - stage.setScene(scene); - stage.show(); - - try (Socket socket = new Socket(host, 8000)) { - // Create an output stream to the server - toServer = new ObjectOutputStream(socket.getOutputStream()); - // Create an input stream from the server - fromServer = new DataInputStream(socket.getInputStream()); - } catch (IOException ex) { - System.out.println("##----------- Client Error: IOException: " + ex.getMessage() + " -----------##"); - } - } + // Pane to hold BMI information and submit button + GridPane paneForBmiInfo = new GridPane(); + paneForBmiInfo.add(new Label("Weight in pounds"), 0, 0); + paneForBmiInfo.add(tfWeight, 1, 0); + paneForBmiInfo.add(new Label("Height in inches"), 0, 1); + paneForBmiInfo.add(tfHeight, 1, 1); + paneForBmiInfo.add(btSubmit, 2, 1); + + // Text Area to display contents + TextArea ta = new TextArea(); + pane.setTop(paneForBmiInfo); + pane.setCenter(new ScrollPane(ta)); - /** - * Custom event handler for the submit button - */ - private class ButtonListener implements EventHandler { - @Override - public void handle(ActionEvent e) { + // Create a scene and place it in the stage + Scene scene = new Scene(pane, 400, 200); + primaryStage.setTitle("Exercise31_01Client"); // Set the stage title + primaryStage.setScene(scene); // Place the scene in the stage + primaryStage.show(); // Display the stage + + btSubmit.setOnAction(e -> { try { - // Get weight and height from the text fields - double weight = Double.parseDouble(weightTextInput.getText().trim()); - double height = Double.parseDouble(heightTextInput.getText().trim()); - // Create a BmiDto and send to the server - BmiDto s = new BmiDto(weight, height); - toServer.writeObject(s); + // Get the weight and height from the text fields + double weight = Double.parseDouble(tfWeight.getText().trim()); + double height = Double.parseDouble(tfHeight.getText().trim()); + + // Send the BMI information to the server + toServer.writeDouble(weight); + toServer.writeDouble(height); toServer.flush(); - // Get resulting BMI from the server - double bmi = fromServer.readDouble(); - // Display to the text area - displayResultTextArea.setText("Weight: " + weight + "\nHeight: " + height + "\nBMI is: " + bmi - + "\n" + getCategory(bmi)); - } catch (IOException ex) { - System.out.println("##----------- Client Error: IOException: " + ex.getMessage() + " -----------##"); + + // Get string from the server + String bmi = fromServer.readUTF(); + + // Display to text area + ta.appendText("Weight: " + weight + '\n'); + ta.appendText("Height: " + height + '\n'); + ta.appendText(bmi + '\n'); } - } - } + catch (IOException ex) { + System.err.println(ex); + } + }); - private String getCategory(double bmi) { - if (bmi < 18.5) { - return "Underweight"; - } else if (bmi < 25) { - return "Normal"; - } else if (bmi < 30) { - return "Overweight"; - } else { - return "Obese"; + try { + // Create a socket to connect to the server + Socket socket = new Socket("localhost", 8000); + + // Create an input stream to receive data from the server + fromServer = new DataInputStream(socket.getInputStream()); + + // Create an output stream to send data to the server + toServer = new DataOutputStream(socket.getOutputStream()); + } + catch (IOException ex) { + ta.appendText(ex.toString() + '\n'); } } - } \ No newline at end of file diff --git a/ch_31/exercise31_02/Exercise31_02Server.java b/ch_31/exercise31_02/Exercise31_02Server.java index 6cf501c..362b0cc 100644 --- a/ch_31/exercise31_02/Exercise31_02Server.java +++ b/ch_31/exercise31_02/Exercise31_02Server.java @@ -11,20 +11,12 @@ import java.net.ServerSocket; import java.net.Socket; import java.util.Date; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; + public class Exercise31_02Server extends Application { private static final double KILOGRAMS_PER_POUND = 0.45359237; private static final double METERS_PER_INCH = 0.0254; - private AtomicBoolean isRunning = new AtomicBoolean(true); - - public Exercise31_02Server() { - System.out.println("##-_-_--_--_--__-_-- Starting: Exercise31_02Server --_-__--__--__--_--_--##"); - } - - @Override public void start(Stage primaryStage) { TextArea displayLogTextArea = new TextArea(); @@ -32,46 +24,51 @@ public void start(Stage primaryStage) { primaryStage.setTitle("TicTacToeServer"); primaryStage.setScene(scene); primaryStage.show(); - new Thread(() -> runServer(displayLogTextArea)).start(); - } + new Thread(() -> { + try { + ServerSocket serverSocket = new ServerSocket(8000); + Platform.runLater(() -> + displayLogTextArea.appendText("Exercise31_02Server started at " + + new Date() + '\n')); - private void runServer(TextArea displayLogTextArea) { - /* Create a server socket. Use try with resources to close the socket automatically */ - try (ServerSocket serverSocket = new ServerSocket(8000)) { - // Listen for a connection request - Socket socket = socket = serverSocket.accept(); - // Create data input and output streams - try (ObjectInputStream inputFromClient = new ObjectInputStream( - socket.getInputStream())) { - try (DataOutputStream outputToClient = new DataOutputStream( - socket.getOutputStream())) { + Socket socket = serverSocket.accept(); + DataInputStream inputFromClient = new DataInputStream( + socket.getInputStream()); + DataOutputStream outputToClient = new DataOutputStream( + socket.getOutputStream()); - Platform.runLater(() -> displayLogTextArea.appendText(new Date() + - ": Server started at socket 8000\n")); - while (true) { - if (!isRunning.get()) { - break; - } - if (inputFromClient.available() > 0) { - // Receive Object from the client - Object object = inputFromClient.readObject(); - if (Objects.nonNull(object) && object instanceof BmiDto) { - BmiDto bmiDto = (BmiDto) object; - double weight = bmiDto.getWeight(); - double height = bmiDto.getHeight(); - double bmi = calculateBmi(weight, height); - // Send area back to the client - outputToClient.writeDouble(bmi); - } - } + while (true) { + Date date = new Date(); + double weight = inputFromClient.readDouble(); + double height = inputFromClient.readDouble(); + double weightInKilograms = weight * KILOGRAMS_PER_POUND; + double heightInMeters = height * METERS_PER_INCH; + double bmi = calculateBmi(weightInKilograms, heightInMeters); + StringBuilder bmiString = new StringBuilder("BMI is " + + String.format("%.2f", bmi) + ". "); + if (bmi < 18.5) { + bmiString.append("Underweight"); + } else if (bmi < 25) { + bmiString.append("Normal"); + } else if (bmi < 30) { + bmiString.append("Overweight"); + } else { + bmiString.append("Obese"); } + outputToClient.writeUTF(bmiString.toString()); + + Platform.runLater(() -> { + displayLogTextArea.appendText("Connected to a client at " + date + '\n'); + displayLogTextArea.appendText("Weight: " + weight + '\n'); + displayLogTextArea.appendText("Height: " + height + '\n'); + displayLogTextArea.appendText(bmiString.toString() + '\n'); + }); } + } catch (IOException ex) { + ex.printStackTrace(); } - - } catch (ClassNotFoundException | IOException ex) { - System.out.println("##----------- Server Error: Exception: " + ex.getMessage() + " -----------##"); - } + }).start(); } private double calculateBmi(double weight, double height) {