I am designing a customized calculator based on fuel cost and the car's fuel efficiency. I'm unable to run the client as I keep getting this exception "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4 exception". Would really appreciate some help on this!
Server:
public class MiniProjServer extends Application {
@Override
public void start(Stage primaryStage) {
TextArea ta = new TextArea();
new Thread(() -> {
try{
ServerSocket serverSocket = new ServerSocket(8000);
Platform.runLater(() ->
ta.appendText("Mini Project Server started at "
+ new Date() + '\n'));
Socket socket = serverSocket.accept();
DataInputStream inputFromClient = new DataInputStream(socket.getInputStream());
DataOutputStream outputToClient = new DataOutputStream(socket.getOutputStream());
int getFuelType= inputFromClient.readInt();
Scanner scanner = new Scanner(new File("fuelCost.csv"));
//Set the delimiter used in file
scanner.useDelimiter(",");
//Get all tokens and store them in some data structure
String InputLine="";
while (scanner.hasNextLine()) {
InputLine= scanner.nextLine();
String[]fuelCostArray=InputLine.split(",");
if(getFuelType==1)
{
outputToClient.writeUTF(fuelCostArray[0]);
}
else if(getFuelType==2)
{
outputToClient.writeUTF(fuelCostArray[1]);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}).start();
StackPane root = new StackPane();
root.getChildren().addAll(ta);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Server");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Client:
public class MiniProject extends Application {
ServerSocket ss;
Socket s;
DataInputStream dis;
DataOutputStream dos;
@Override
public void start(Stage primaryStage)
{
//Create New Image
Image image = new Image("/image/alset.PNG");
//Create image view so that it can be added to Grid Pane
ImageView alset = new ImageView();
alset.setImage(image);
//Title of the project
Text title= new Text("Alset Business Trip Calculator");
title.setFont(Font.font("verdana", FontWeight.BOLD, FontPosture.REGULAR, 20));
Label lblDist = new Label();
lblDist.setText("Distance:");
//Textbox to get user input for distance
TextField TxtDistance = new TextField();
TxtDistance.setPromptText("Enter distance in miles");
TxtDistance.setFocusTraversable(false);
Text TxtDistUnit= new Text("miles");
TxtDistUnit.setFont(Font.font("verdana", FontWeight.BOLD,10));
Text TxtFCUnit = new Text("miles per gallon(MPG)");
TxtFCUnit.setFont(Font.font("verdana", FontWeight.BOLD,10));
Label lblFuelConsumption = new Label();
lblFuelConsumption.setText("Fuel Consumption:");
//Textbox to get user input for Car's fuel efficiency
TextField TxtFuelConsumption = new TextField();
TxtFuelConsumption.setPrefWidth(100);
TxtFuelConsumption.setPromptText("Input Cars fuel consumption in miles per gallon(MPG)");
TxtFuelConsumption.setFocusTraversable(true);
Label lblRBTitle = new Label();
lblRBTitle.setText("Fuel Type:");
//Radio Button to get Fuel Type
RadioButton rbOctane = new RadioButton("98 Octane(£1.03/L)");
RadioButton rbDiesel = new RadioButton("Diesel(£1.05/L)");
ToggleGroup fuelType = new ToggleGroup();
rbOctane.setToggleGroup(fuelType);
rbDiesel.setToggleGroup(fuelType);
fuelType.selectToggle(rbOctane);
//Button to calculate the cost of the trip
Button calcFuelCostBtn = new Button();
//Button to clear all the user inputs
Button clearBtn = new Button();
calcFuelCostBtn.setStyle("-fx-border-color: #ff0000; -fx-border-width: 5px;");
Label lblResult= new Label();
lblResult.setText("Cost:£");
Label lblException = new Label();
Label lblTest=new Label();
calcFuelCostBtn.setText("Calculate Fuel Cost");
clearBtn.setText("Clear");
TextField TxtResultBox = new TextField();
new Thread(() -> {
try{
s=new Socket("localhost",8000);
dis= new DataInputStream(s.getInputStream());
dos= new DataOutputStream(s.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(MiniProject.class.getName()).log(Level.SEVERE, null, ex);
}
//Event Handler to set the action when user clicks on "Calculate Fuel Cost" Button
calcFuelCostBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
TxtResultBox.clear();
//checks if either of the textboxes are empty
if(TxtDistance.getText().trim().equals(""))
{
lblResult.setText("No distance value is entered!");
}
else if(TxtFuelConsumption.getText().trim().equals(""))
{
lblResult.setText("No fuel consumption value is entered!");
}
RadioButton rb = (RadioButton)fuelType.getSelectedToggle();
//if Octane Radio Button is selected call calculate octane cost method
if(fuelType.getSelectedToggle()==rbOctane)
{
//Exception handling if user enters an invalid number into each respective textbox
try{
double distVal= Double.parseDouble(TxtDistance.getText());
double fuelConsumpVal= Double.parseDouble(TxtFuelConsumption.getText());
int propaneFuelType=1;
if(fuelConsumpVal==0)
{
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Unable to calculate trip cost because:");
alert.setContentText("Fuel Efficiency cannot be 0!");
alert.showAndWait();
}
else{
//Get scanner instance
dos.writeInt(propaneFuelType);
String propaneCost = dis.readUTF();
TxtResultBox.setText(String.format("%.2f",calcPropaneCost(distVal,fuelConsumpVal,Double.valueOf(propaneCost))));
printResults(distVal,fuelConsumpVal,rbOctane.getText(),calcPropaneCost(distVal,fuelConsumpVal,Double.valueOf(propaneCost)));
}
}catch(NumberFormatException ex)
{
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Unable to calculate trip cost because:");
alert.setContentText("You did not enter a valid number!");
alert.showAndWait();
} catch (IOException ex) {
Logger.getLogger(MiniProject.class.getName()).log(Level.SEVERE, null, ex);
}
}
// lblException.setText("You did not enter a valid number!");
//if Diesel Radio Button is selected call calculate diesel cost method
else if(fuelType.getSelectedToggle()==rbDiesel)
{
//exception handling for when user enters an invalid numbe into either respective text box
try{
double distVal= Double.parseDouble(TxtDistance.getText());
double fuelConsumpVal= Double.parseDouble(TxtFuelConsumption.getText());
int dieselFuelType=2;
if(fuelConsumpVal==0)
{
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Unable to calculate trip cost because:");
alert.setContentText("Fuel Efficiency cannot be 0!");
alert.showAndWait();
}
else{
dos.writeInt(dieselFuelType);
String dieselCost = dis.readUTF();
//Get all tokens and store them in some data structure
//I am just printing them
TxtResultBox.setText(String.format("%.2f",calcDieselCost(distVal,fuelConsumpVal,Double.valueOf(dieselCost))));
printResults(distVal,fuelConsumpVal,rbDiesel.getText(),calcPropaneCost(distVal,fuelConsumpVal,Double.valueOf(dieselCost)));
}
}
catch(NumberFormatException ex)
{
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Unable to calculate trip cost because:");
alert.setContentText("You did not enter a valid number!");
alert.showAndWait();
} catch (IOException ex) {
Logger.getLogger(MiniProject.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
});
//logic behind clear button
clearBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
TxtDistance.clear();
TxtFuelConsumption.clear();
fuelType.selectToggle(null);
TxtResultBox.clear();
}
});
//create new grid pane
GridPane grid = new GridPane();
//add all the nodes to grid pane
grid.getChildren().addAll(title,lblDist,TxtDistance,TxtDistUnit,lblFuelConsumption,TxtFuelConsumption,TxtFCUnit,lblRBTitle,rbOctane,rbDiesel,calcFuelCostBtn,clearBtn,lblResult,lblException,TxtResultBox,alset,lblTest);
//put each respective nodes into a row and column
GridPane.setConstraints(alset,0,0,2,1);
GridPane.setConstraints(title,0,1,2,1);
GridPane.setConstraints(lblDist,0,3);
GridPane.setConstraints(TxtDistance,1,3);
GridPane.setConstraints(TxtDistUnit, 2, 3);
GridPane.setConstraints(lblFuelConsumption,0,4);
GridPane.setConstraints(TxtFuelConsumption, 1, 4);
GridPane.setConstraints(TxtFCUnit, 2, 4);
GridPane.setConstraints(lblRBTitle,0,5);
GridPane.setConstraints(rbOctane, 0, 6);
GridPane.setConstraints(rbDiesel, 1, 6);
GridPane.setConstraints(calcFuelCostBtn, 0, 7);
GridPane.setConstraints(clearBtn, 1, 7);
GridPane.setConstraints(lblResult, 0, 8);
GridPane.setConstraints(lblException, 0, 9);
GridPane.setConstraints(TxtResultBox, 1, 8);
GridPane.setConstraints(lblTest, 1, 10);
Scene scene = new Scene(grid, 600, 300);
primaryStage.setTitle("ALSET BUSINESS TRIP CALCULATOR");
primaryStage.setScene(scene);
primaryStage.show();
}).start()
;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
//method to calculate trip using propane
public double calcPropaneCost(double distance,double fuelConsumption,double cost)
{
// final double propane_cost=1.03;
final double gallon_to_litre=3.78541;
double octaneCost= (distance/fuelConsumption)*gallon_to_litre*cost;
return octaneCost;
}
//method to calculate trip cost using diesel
public double calcDieselCost(double distance, double fuelConsumption,double cost)
{
final double gallon_to_litre=3.78541;
// final double diesel_cost=1.05;
double dieselCost= (distance/fuelConsumption)*gallon_to_litre*cost;
return dieselCost;
}
public void printResults(double distance, double MPG, String fuelType, double result) throws IOException
{
try(FileWriter fw = new FileWriter("output.csv",true)){
StringBuilder sb = new StringBuilder();
sb.append(distance+",");
sb.append(MPG+",");
sb.append(fuelType+",");
sb.append(result+"\n");
fw.write(sb.toString());
}catch(FileNotFoundException ex){
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("An error has occured because:");
alert.setContentText("The csv file does not exist!");
alert.showAndWait();
}
}
}
Exception:
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:444)
at javafx.stage.Stage.setScene(Stage.java:251)
at miniproject.MiniProject.lambda$start$0(MiniProject.java:312)
at java.lang.Thread.run(Thread.java:748)