Issue
package VideoStuff;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* @author 38323
*/
public class ClassStuf extends Application {
Stage window;
GridPane grid;
int x1, x2, x3, y1, y2, y3;
TextField answer1, xAnswer, yAnswer;
String graphtitle, yaxis, xaxis, xcoordinate1, xcoordinate2, xcoordinate3, ycoordinate1, ycoordinate2, ycoordinate3;
Scene scene1, scene2, scene3, scene4;
VBox layout;
@Override
public void start(Stage primaryStage) {
window = primaryStage;
grid = new GridPane();
grid.setAlignment(Pos.TOP_LEFT);
grid.setPadding(new Insets(10));
grid.setVgap(10);
grid.setHgap(10);
Label graphquestion = new Label("Title of graph?");
GridPane.setConstraints(graphquestion, 0, 0);
answer1 = new TextField();
GridPane.setConstraints(answer1, 0, 1);
Button button = new Button("Sumbit");
GridPane.setConstraints(button, 0, 2);
button.setOnAction(e -> {
graphtitle = answer1.getText();
});
grid.getChildren().addAll(graphquestion, answer1, button);
scene1 = new Scene(grid, 300, 200);
window.setScene(scene1);
//Scene 2 (X and Y axis)
layout = new VBox(15);
scene2 = new Scene(layout, 400, 200);
button.setOnAction(e -> window.setScene(scene2));
Label xAxis = new Label("X Axis?");
xAnswer = new TextField();
Label yAxis = new Label("Y Axis?");
yAnswer = new TextField();
Button nextbutton = new Button("Proceed");
nextbutton.setOnAction(e -> {
yaxis = yAnswer.getText();
xaxis = xAnswer.getText();
});
layout.getChildren().addAll(xAxis, xAnswer, yAxis, yAnswer, nextbutton);
//X and Y inputs
VBox box2 = new VBox(30);
scene3 = new Scene(box2, 800, 800);
nextbutton.setOnAction(e -> window.setScene(scene3));
Label xvalue1 = new Label("1st x value?");
TextField xanswer1 = new TextField();
Label xvalue2 = new Label("2st x value?");
TextField xanswer2 = new TextField();
Label xvalue3 = new Label("3st x value?");
TextField xanswer3 = new TextField();
Button xclick = new Button("Submit x values");
Label yvalue1 = new Label("1st y value?");
TextField yanswer1 = new TextField();
Label yvalue2 = new Label("2st y value?");
TextField yanswer2 = new TextField();
Label yvalue3 = new Label("3st y value?");
TextField yanswer3 = new TextField();
Button yclick = new Button("Submit y values");
xclick.setOnAction(e
-> {
xcoordinate1 = xanswer1.getText();
xcoordinate2 = xanswer2.getText();
xcoordinate3 = xanswer3.getText();
x1 = Integer.parseInt(xcoordinate1);
x2 = Integer.parseInt(xcoordinate2);
x3 = Integer.parseInt(xcoordinate3);
});
yclick.setOnAction(e
-> {
ycoordinate1 = yanswer1.getText();
ycoordinate2 = yanswer2.getText();
ycoordinate3 = yanswer3.getText();
y1 = Integer.parseInt(ycoordinate1);
y2 = Integer.parseInt(ycoordinate2);
y3 = Integer.parseInt(ycoordinate3);
});
box2.getChildren().addAll(xvalue1, xanswer1, xvalue2, xanswer2, xvalue3, xanswer3, xclick,
yvalue1, yanswer1, yvalue2, yanswer2, yvalue3, yanswer3, yclick);
System.out.println(xaxis);
//LineChart Creation
HBox root = new HBox();
CategoryAxis xline = new CategoryAxis();
xline.setLabel(xaxis);
NumberAxis yline = new NumberAxis();
yline.setLabel(yaxis);
LineChart<String, Number> linechart = new LineChart<String, Number>(xline, yline);
linechart.setTitle(graphtitle);
XYChart.Series<String, Number> data = new XYChart.Series<>();
data.setName(xaxis);
data.getData().add(new XYChart.Data<>((xcoordinate1), (y1)));
data.getData().add(new XYChart.Data<>((xcoordinate2), (y2)));
data.getData().add(new XYChart.Data<>((xcoordinate3), (y3)));
linechart.getData().add(data);
root.getChildren().add(linechart);
scene4 = new Scene(root, 350, 330);
yclick.setOnAction(e -> window.setScene(scene4));
window.setTitle("LineChart Demo");
window.show();
}
public static void main(String[] args) {
launch(args);
}
}
Just as a heads up, the code runs well enough until where the double slashes indicate LineChart Creation. I apologize for my messy code as I am still new to JavaFX. Whilst having no red lines, I am struggling to identify the problem of why the linechart isn't working. What is supposed to happen is that the user should be able to input all of the values, which is the values of the x/y coordinates, etc, are up to them to create. Not to mention, that it must be demonstrated on GUI rather than plaintext.
Solution
When the application is launched only code in the start
method that is outside of event handlers is executed. Any code inside event handlers may be executed later after the start
method has returned, if the user interacts with the GUI in a certain way.
This means that any input of data by the user happens after you fill the data.
The effect is that you"re effectively executing the following logic when filling the data:
data.getData().add(new XYChart.Data<>((String) null, 0));
data.getData().add(new XYChart.Data<>((String) null, 0));
data.getData().add(new XYChart.Data<>((String) null, 0));
You need to delay filling the data until you execute the event handler showing the data.
Furthermore in the following part of the code you completely replace the first event handler. The first event handler has no effect on the result whatsoever.
yclick.setOnAction(e
-> {
ycoordinate1 = yanswer1.getText();
ycoordinate2 = yanswer2.getText();
ycoordinate3 = yanswer3.getText();
y1 = Integer.parseInt(ycoordinate1);
y2 = Integer.parseInt(ycoordinate2);
y3 = Integer.parseInt(ycoordinate3);
});
...
yclick.setOnAction(e -> window.setScene(scene4));
This is not the only part of your code with this issue. You do the same thing with button
(first scene) and nextbutton
in the second scene. Just merge the logic from both event handlers into a single event handler.
Note: One thing that seems weird is the fact that even if you get the code working you require 2 user interactions to show the data. Usually you try to minimize the necessary interactions the user has to do. I'd expect a click on a single button to parse the data for x as well as y coordinates and show the data.
/**
* Helper method to avoid repetition
*/
private static void addPoint(XYChart.Series<String, Number> series, TextField xText, TextField yText) {
int y = Integer.parseInt(yText.getText());
series.getData().add(new XYChart.Data<>(xText.getText(), y));
}
...
someButton.setOnAction(evt -> {
CategoryAxis xline = new CategoryAxis();
xline.setLabel(xaxis);
NumberAxis yline = new NumberAxis();
yline.setLabel(yaxis);
LineChart<String, Number> linechart = new LineChart<String, Number>(xline, yline);
linechart.setTitle(graphtitle);
XYChart.Series<String, Number> data = new XYChart.Series<>();
data.setName(xaxis);
// data is read here
addPoint(data, xanswer1, yanswer1);
addPoint(data, xanswer2, yanswer2);
addPoint(data, xanswer3, yanswer3);
linechart.getData().add(data);
root.getChildren().add(linechart);
Scene scene4 = new Scene(root, 350, 330);
// logic from the second event handler needs to be merged into a single event handler
window.setScene(scene4);
});
Answered By - fabian