From ff550442622acb33df11a39223b6f575e06fdad4 Mon Sep 17 00:00:00 2001 From: Harry Dulaney Date: Sun, 19 Nov 2023 15:51:23 -0500 Subject: [PATCH] bug fix ex 31 02 --- README.md | 6 +- ch_18/exercise18_31/Exercise18_31.class | Bin 0 -> 3567 bytes ch_31/Exercise31_02.java | 58 ---------- ch_31/exercise31_02/BmiDto.java | 28 +++++ ch_31/exercise31_02/Exercise31_02.java | 21 ++++ ch_31/exercise31_02/Exercise31_02Client.java | 106 +++++++++++++++++++ ch_31/exercise31_02/Exercise31_02Server.java | 84 +++++++++++++++ 7 files changed, 242 insertions(+), 61 deletions(-) create mode 100644 ch_18/exercise18_31/Exercise18_31.class delete mode 100644 ch_31/Exercise31_02.java create mode 100644 ch_31/exercise31_02/BmiDto.java create mode 100644 ch_31/exercise31_02/Exercise31_02.java create mode 100644 ch_31/exercise31_02/Exercise31_02Client.java create mode 100644 ch_31/exercise31_02/Exercise31_02Server.java diff --git a/README.md b/README.md index e6418ce..d3fdd3e 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ header-img-book-cover -### This repo contains my solutions to the end-of-chapter exercise’s from Y. Daniel Liang’s Intro to Java Programming (10th Edition) +### This repo contains my solutions to the end-of-chapter exercise’s from Y. Daniel Liang’s Intro to Java Programming (10th Edition) -### I've included links below to all the freely accessible compainion material and quick links to navigate through my solutions by chapter. +### I've included links below to all the freely accessible companion material and quick links to navigate through my solutions by chapter. ### If you would like to contribute, please see: Ways to Contribute @@ -63,7 +63,7 @@ ____ ____ -

Exercise Solutions:

+

Exercise Solutions:

Quick Links to navigate these solutions by chapter
complete-check-img diff --git a/ch_18/exercise18_31/Exercise18_31.class b/ch_18/exercise18_31/Exercise18_31.class new file mode 100644 index 0000000000000000000000000000000000000000..e04c1b20bdcac1b0d323946694ab28bb78a154c0 GIT binary patch literal 3567 zcmcIn=~o-q75_bu^kA46B4d(?i#v9(4MJFe>zE2JDPU~5fL$PViQ77Z^aNw18F@4^ z&^E2pHcOW*-QzB4nlA3%*loefIX?Z=4?X=G`iJC0-TP)nFhbO){m>(hX1MRZyZr9& z-TUCW_A;CPBbt(qJ+3qpa04@nT(<=Y+=ABN7*VwT5DhhVUsRS$sY zg9O9g?BeBtp_B+EJdg^fKR^*V zqEs-l;v(fwHjj31FB6kkeFGPQjSv$@i3vLg^?4Ef-#(yv^pax;s?8F zh~q3nM|IaoC7&0L$W?b{Fd=tNQY|-k`ima5GdQQ>JU+n?Etr-h;qEHh71u1J%HE+% z1!pe~h8Y#Jc#iaqQmH_M9{sP<4*>OS<||fKGAT74ybQPCB0kA6r{Z~BqI!DS)cYq= z6^#XvB0onGa~6*K?bIZEAp&Gvjw|M94Tz!$VJC=B}bNU zn#10P3RMLQS0xpwv4*JNFA^16kcX?Hf@=&-(xO5AimcV-o(bfX^9oiuKC9w$lE6M` zy>e7l2#ZCdJSA3Ksr#aeFW`&RI4u%vJ<%Hgyi_|3yauem!k1NiMfUILvdmRVUQzL? z1ch5-d4hN=Wu}7b_?n8Z;~TUPbU}u(Fh55Z4QEDNtq3bChC|1`MjkE>5noOLihR`0 zQGr{fx2Z~TUO2PHe1Rm9qG8hP=&1JD+Tp?QnAaXBjgqI&@omCCXvtw!j_;E7ExnpL z%|_oPM(!*a#rd4kwb^~T`blNRt~gmCI|x;xW*QulbRtkkY}+Lc8l_3$F50ADuGRL17_SYf59oIPiLQVS7s?^SXVqz~v*FcvCP%osGf*5_jPXBe% zlSye}9qbmpFuXzEav6xD8E@h(dM8!Zga|lEoy3FaduY849)D~Nt&MlEE73SOk%$aV zCZdB=_o2=8u48vPqD9uwc>@Xg+?$SS(Z6B07Jcvzc4^UMAMM+J6G}R!#n#Yw6D_yV zA3sb6>6z@4dyd@0M*))Dq6kKC7L#-dYw+TmMmt5)PI2zS4s=kY8ht-SpWWC)Np;gD zv>!U%srJ&&r)lp2+TDe7*iUo3hX!u~myx9I-$y+(iK}$8`zBfJLNxvmX~a0b#c{p* zr*V7-jHCAh#2PqV_vl_qkw^f~5||NsYKaG(?;>)mH<{=hyo2M3-ehOw1IdCH zs-SCP42KEGBWT4lc#=YtjvJ-<@6k(ya_uD#bmQ_pu${E1(8?>xHGJ#_Ub>I5x#T*= z3F*vS-#R|-BR!Sqy@zSwE-p0S4nB1k^9}eb@&r6#xp*H-a#t}OyANwli>;%S=34YF zsKch4w5GdQX1IYp^6m4CHeOFRYg}ty!+X{HJ`rwwcZeN&wVGIgZf}j^l*= z2}1cKMgJ^@2=(K1%{xt(xM`dse8*`Xp2mwfL*pugmoed`eH4ukaY_Cz^06kM$2c+^ zd5$Fxi_LG$!_D%L_O`_$8xj1 literal 0 HcmV?d00001 diff --git a/ch_31/Exercise31_02.java b/ch_31/Exercise31_02.java deleted file mode 100644 index cff8475..0000000 --- a/ch_31/Exercise31_02.java +++ /dev/null @@ -1,58 +0,0 @@ -package ch_31; - -import javafx.application.Application; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.layout.GridPane; -import javafx.stage.Stage; -import javafx.scene.image.ImageView; -import javafx.scene.image.Image; - -import java.io.File; - -/** - * *31.2 (BMI server) Write a server for a client. The client sends the weight and - * height for a person to the server (see Figure 31.18a). The server computes - * BMI (Body Mass Index) and sends back to the client a string that reports the - * BMI (see Figure 31.18b). See Section 3.8 for computing BMI. Name the client - * Exercise31_02Client and the server Exercise31_02Server. - */ -public class Exercise31_02 extends Application { - private final String SLASH = File.separator; - - @Override - public void start(Stage primaryStage) { - String imagePath1 = "resources" + SLASH + "image" + SLASH + "x.gif"; - String imagePath2 = "resources" + SLASH + "image" + SLASH + "o.gif"; - Image imageX = new Image(imagePath1); - Image imageO = new Image(imagePath2); - - GridPane pane = new GridPane(); - pane.getStylesheets().add("mystyle.css"); - pane.getStyleClass().add("border"); - - pane.setAlignment(Pos.CENTER); - pane.setHgap(5); - pane.setVgap(5); - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if ((int) (Math.random() * 3) == 0) { - ImageView imageView1 = new ImageView(imageX); - imageView1.getStyleClass().add("border"); - pane.add(imageView1, j, i); - } else if ((int) (Math.random() * 3) == 1) { - ImageView imageView2 = new ImageView(imageO); - imageView2.getStyleClass().add("border"); - pane.add(imageView2, j, i); - } - } - } - - Scene scene = new Scene(pane); - primaryStage.setTitle(getClass().getName()); - primaryStage.setScene(scene); - primaryStage.show(); - } - -} diff --git a/ch_31/exercise31_02/BmiDto.java b/ch_31/exercise31_02/BmiDto.java new file mode 100644 index 0000000..3a799ed --- /dev/null +++ b/ch_31/exercise31_02/BmiDto.java @@ -0,0 +1,28 @@ +package ch_31.exercise31_02; + +/** + * Data Transfer Object for BMI data + *

+ * This class is used to transfer data from the client to the server. + * For Exercise31_02, the client sends the weight and height for a person to the server. + */ +public class BmiDto { + private double weight; + private double height; + + public BmiDto() { + } + + public BmiDto(double weight, double height) { + this.weight = weight; + this.height = height; + } + + public double getWeight() { + return weight; + } + + public double getHeight() { + return height; + } +} diff --git a/ch_31/exercise31_02/Exercise31_02.java b/ch_31/exercise31_02/Exercise31_02.java new file mode 100644 index 0000000..964cdf9 --- /dev/null +++ b/ch_31/exercise31_02/Exercise31_02.java @@ -0,0 +1,21 @@ +package ch_31.exercise31_02; + +import javafx.application.Application; +import javafx.application.Platform; +import javafx.stage.Stage; + +/** + * *31.2 (BMI server) Write a server for a client. The client sends the weight and + * height for a person to the server (see Figure 31.18a). The server computes + * BMI (Body Mass Index) and sends back to the client a string that reports the + * BMI (see Figure 31.18b). See Section 3.8 for computing BMI. Name the client + * Exercise31_02Client and the server Exercise31_02Server. + */ +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())); + } +} diff --git a/ch_31/exercise31_02/Exercise31_02Client.java b/ch_31/exercise31_02/Exercise31_02Client.java new file mode 100644 index 0000000..a0b44a1 --- /dev/null +++ b/ch_31/exercise31_02/Exercise31_02Client.java @@ -0,0 +1,106 @@ +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.layout.GridPane; +import javafx.stage.Stage; + +import java.io.*; +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(); + + private Button submitButton = new Button("Submit"); + + // Host name or ip + String host = "localhost"; + + private ObjectOutputStream toServer; + private DataInputStream fromServer; + + public Exercise31_02Client() { + System.out.println("##-_-_--_--_--__-_-- Starting: Exercise31_02Client --_-__--__--__--_--_--##"); + } + + @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() + " -----------##"); + } + } + + /** + * Custom event handler for the submit button + */ + private class ButtonListener implements EventHandler { + @Override + public void handle(ActionEvent 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); + 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() + " -----------##"); + } + } + } + + 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"; + } + } + +} \ No newline at end of file diff --git a/ch_31/exercise31_02/Exercise31_02Server.java b/ch_31/exercise31_02/Exercise31_02Server.java new file mode 100644 index 0000000..6cf501c --- /dev/null +++ b/ch_31/exercise31_02/Exercise31_02Server.java @@ -0,0 +1,84 @@ +package ch_31.exercise31_02; + +import javafx.application.Application; +import javafx.application.Platform; +import javafx.scene.Scene; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextArea; +import javafx.stage.Stage; + +import java.io.*; +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(); + Scene scene = new Scene(new ScrollPane(displayLogTextArea), 450, 200); + primaryStage.setTitle("TicTacToeServer"); + primaryStage.setScene(scene); + primaryStage.show(); + new Thread(() -> runServer(displayLogTextArea)).start(); + } + + 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())) { + + 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); + } + } + + } + } + } + + } catch (ClassNotFoundException | IOException ex) { + System.out.println("##----------- Server Error: Exception: " + ex.getMessage() + " -----------##"); + } + } + + private double calculateBmi(double weight, double height) { + double weightInKilograms = weight * KILOGRAMS_PER_POUND; + double heightInMeters = height * METERS_PER_INCH; + return weightInKilograms / + (heightInMeters * heightInMeters); + } + +}