Here is my Main java file.The probelm is that the Whole project is working on double click when i launch it.
public Stage primaryStage;
public BorderPane rootLayout;
private Pane splashLayout;
private ProgressBar loadProgress;
private Label progressText;
private static final int SPLASH_WIDTH = 600;
private static final int SPLASH_HEIGHT = 400;
public static void main(String[] args) throws Exception {
launch(args);
}
#Override
public void start(final Stage initStage) throws Exception {
//this.primaryStage = primaryStage;
FXMLLoader fxmlLoader1 = new FXMLLoader(getClass().getResource(
"KDAF_Splash.fxml"));
try {
// flag = false;
Parent root2 = fxmlLoader1.load();
Stage stage2 = new Stage();
stage2.initStyle(StageStyle.TRANSPARENT);
// masterpane = new Pane();
// masterpane.setOpacity(1);
// stage2.setTitle("Create New Project");
stage2.setScene(new Scene(root2, 600, 400));
stage2.show();
PauseTransition delay = new PauseTransition(Duration.seconds(5));
delay.setOnFinished( event ->{ stage2.close();showMainStage();} );
delay.play();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
};
private void showMainStage(
) {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Preloader.class.getResource("RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
Stage stage=new Stage();
stage.setTitle("Activation");
Scene scene = new Scene(rootLayout);
//stage.initStyle(StageStyle.DECORATED);
stage.setScene(scene);
stage.initStyle(StageStyle.UNDECORATED);
stage.show();
showPersonOverview();
//mainStage.show();
/* mainStage.setTitle("Activation Wizard");
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
// primaryStage.initStyle(StageStyle.UTILITY);
mainStage.setResizable(false);
mainStage.initStyle(StageStyle.UNDECORATED);
mainStage.setScene(scene);
mainStage.show();
showPersonOverview();*/
} catch (IOException e) {
e.printStackTrace();
}
}
public void showPersonOverview() {
try {
// Load person overview.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("activation wizard.fxml"));
AnchorPane personOverview = (AnchorPane) loader.load();
personOverview.setPrefHeight(400);
// Set person overview into the center of root layout.
rootLayout.setCenter(personOverview);
} catch (IOException e) {
e.printStackTrace();
}
}
private void showSplash(
final Stage initStage,
Task<?> task,
InitCompletionHandler initCompletionHandler
) {
progressText.textProperty().bind(task.messageProperty());
loadProgress.progressProperty().bind(task.progressProperty());
task.stateProperty().addListener((observableValue, oldState, newState) -> {
if (newState == Worker.State.SUCCEEDED) {
loadProgress.progressProperty().unbind();
loadProgress.setProgress(1);
initStage.toFront();
FadeTransition fadeSplash = new FadeTransition(Duration.seconds(1.2), splashLayout);
fadeSplash.setFromValue(1.0);
fadeSplash.setToValue(0.0);
fadeSplash.setOnFinished(actionEvent -> initStage.hide());
fadeSplash.play();
initCompletionHandler.complete();
} // todo add code to gracefully handle other task states.
});
Scene splashScene = new Scene(splashLayout);
initStage.initStyle(StageStyle.UNDECORATED);
final Rectangle2D bounds = Screen.getPrimary().getBounds();
initStage.setScene(splashScene);
initStage.setX(bounds.getMinX() + bounds.getWidth() / 2 - SPLASH_WIDTH / 2);
initStage.setY(bounds.getMinY() + bounds.getHeight() / 2 - SPLASH_HEIGHT / 2);
initStage.show();
}
public interface InitCompletionHandler {
public void complete();
}
}
The FXml is given below. Please help me to resolve this issue. If the question is not clear help me to explain better. The main problem is when the application is launched after splash screen. The button accepts double click and then moves to load next FXML. this is been very painful as i have to double click everytime instead of single click. I am not able to identify the problem here. Whether it is a problem that persists from scene builder or the problem is in the main preloader class.Even the menu item is accepting double click. I try to google the solution for but could not find any solution. please look int the code and help to resolve this issue. I have done a lot of R&D but all went vain . There might be a little problem in it but i am not being able to identify it. Please ignore the formatting of code and unused variables. The code is not final yet. finally i would like to remind the main problem is that after launching, the application is working only on double click. lets look at the work flow to understand it better. SPLASH SCREEN->ACTIVATION WIZARD-DOUBLE CLICK ON A BUTTON->TIP SCREEN-DOUBLE CLICK ON A BUTTON->PROJECT SCREEN->DOUBLE CLICK TO OPEN ANYTHING. It is really frustrating. please help.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-border-color: black;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="EventHandlingController">
<children>
<Button layoutX="301.0" layoutY="333.0" mnemonicParsing="false" text="Buy Full Version" />
<Button fx:id="myButton7" layoutX="420.0" layoutY="333.0" mnemonicParsing="false" onAction="#Showtip" prefHeight="25.0" prefWidth="114.0" text="Continue Trial " />
<TextField editable="false" layoutX="85.0" layoutY="108.0" prefHeight="151.0" prefWidth="449.0" style="-fx-background-color: silver;" text="You have <xx> days left on your trial.">
<font>
<Font size="21.0" />
</font>
</TextField>
<Label layoutX="85.0" layoutY="23.0" prefHeight="37.0" prefWidth="135.0" text="Activation Wizard">
<font>
<Font name="System Bold" size="15.0" />
</font>
</Label>
<Button fx:id="closebutt" layoutX="573.0" layoutY="2.0" mnemonicParsing="false" onAction="#closebuttonD" prefHeight="15.0" prefWidth="20.0" text="X" />
</children>
</AnchorPane>
Related
I've got a RootStage with some MenuItems and want to set the center of my Rootstage to an AnchorPane with a LineChart in the middle.
The chart got a CategoryAxis on the x-Axis and a NumberAxis on the y-Axis.
But now if I call the Controller for the Scene with the LineChart on it, I can see the LineChart but it has no values. Or at least doesn't show them.
Why is the LineChart not getting filled?
Or why doesn't it show the values?
MainController.class
public class MainController extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
#FXML
private MenuBar menuBar;
#FXML
private Menu menuAnsicht, menuOptionen;
#FXML
private MenuItem menuItemTag, menuItemWoche, menuItemAbout, menuItemCloseWindow;
#Override
public void init() {
}
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
initRootLayout();
}
private void initRootLayout() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/de/mgo/temperaturstatistics/view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
logger.debug("ERROR: " + e.getMessage());
e.printStackTrace();
}
}
#FXML
public void handleTagItem(ActionEvent event) {
try {
BorderPane nowLayout = (BorderPane) menuBar.getScene().getRoot();
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/de/mgo/temperaturstatistics/view/DailyScene.fxml"));
nowLayout.setCenter(loader.load());
} catch (Exception e) {
logger.debug("ERROR: " + e.getMessage());
e.printStackTrace();
}
}
DailySceneController.class
public class DailySceneController extends Application {
#FXML
private Label titleDaily;
#FXML
private LineChart<String, Number> dailyChart;
#FXML
private CategoryAxis xDaily;
#FXML
private NumberAxis yDaily;
public int count = 0;
public DailySceneController() {
count++;
System.out.println(count);
}
#Override
public void init() {
this.setChartDaily();
}
#Override
public void start(Stage primaryStage) {
}
public void setChartDaily() {
LocalDate localDate = LocalDate.now().minusDays(0);
List<Temperaturen> listeNodemcu_JHL = MainController.getListeNodemcu_JHL();
this.xDaily.setAutoRanging(false);
this.yDaily.setAutoRanging(false);
this.dailyChart.setAnimated(false);
XYChart.Series<String, Number> seriesJHL = new XYChart.Series<String, Number>();
seriesJHL.setName("Nodemcu_JHL");
seriesJHL.getData().add(new XYChart.Data<String, Number>("Test", 15));
this.dailyChart.getData().add(seriesJHL);
}
}
DailyScene.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?package de.mgo.temperaturstatistics.controller.Controller?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.text.Font?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.mgo.temperaturstatistics.view.DailySceneController">
<top>
<Label fx:id="titleDaily" text="Temperatur-Statistik Tagesansicht" BorderPane.alignment="CENTER">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
</top>
<center>
<LineChart fx:id="dailyChart" prefHeight="300.0" prefWidth="500.0" BorderPane.alignment="CENTER">
<xAxis>
<CategoryAxis fx:id="xDaily" animated="false" label="Uhrzeit" side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis fx:id="yDaily" animated="false" autoRanging="false" label="Temperatur" lowerBound="10.0" side="LEFT" tickLabelGap="1.0" tickUnit="1.0" upperBound="30.0" />
</yAxis>
</LineChart>
</center>
</BorderPane>
You're extending Application with your controller class an expect it's lifecycle methods to be invoked for it. This is bad practice and also does not result in the invocation of the lifecycle methods.
If you want a method to be invoked, use Initializable.initialize or simply a parameterless initialize method:
#FXML
private void initialize() {
this.setChartDaily();
}
I would like to add a custom element into a VBox.
For example: being able to write VBox.getChildren().add(element) and element is a custom node created by me in FXML.
I already followed this tutorial: https://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm
but the example only shows how to do this inside the same controller (a single controller, i already have my "big" controller, which is WinnerController, I would like to split the two classes, one that manages the single element, and one that manages the whole scene Winner.fxml).
I already have a class WinnerController which is the controller of my FXML Winner.fxml.
Here the code of my Winner.fxml:
<AnchorPane id="paneWinner" fx:id="paneWinner" prefHeight="800.0" prefWidth="1280.0" stylesheets="#winner.css" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.gui.WinnerController">
<children>
<VBox layoutX="434.0" layoutY="125.0" prefHeight="250.0" prefWidth="413.0" spacing="10.0">
<children>
<AnchorPane id="leaderBoardElement" prefHeight="80.0" prefWidth="413.0" stylesheets="#leaderBoard.css">
<children>
<Text layoutX="49.0" layoutY="45.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Text" wrappingWidth="107.13671875" />
</children></AnchorPane>
</children>
</VBox>
I would like to dynamically add element with the id "leaderBoardElement" (so an AnchorPane + Text) into my VBox.
How can i do that?
Edit: I also tried with this solution:How to understand and use `<fx:root>` , in JavaFX?
but i keep getting nothing. When i do vbox.getChildren().add(new MyComponent());
called in my WinnerControlleri get nothing.
WinnerController class:
public class WinnerController implements Initializable {
#FXML
private VBox leaderBoard;
#FXML
public void initialize(URL location, ResourceBundle resources) {
System.out.println("Winner Init");
MyComponent test = new MyComponent();
System.out.println(test);
// leaderBoard.getChildren().add(new MyComponent());
}
}
My Component class:
public class MyComponent extends AnchorPane {
#FXML
private TextField textField ;
#FXML
private Button button ;
public MyComponent() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyComponent.fxml"));
loader.setController(this);
loader.setRoot(this);
loader.load();
textField.setText("HELLO!");
} catch (IOException exc) {
// handle exception
System.out.println("ELEMENT NOT CREATE!!!");
}
}
}
Winner.fxml:
<AnchorPane id="paneWinner" fx:id="paneWinner" prefHeight="800.0"
prefWidth="1280.0" stylesheets="#winner.css" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.gui.WinnerController">
<children>
<VBox fx:id="leaderBoard" layoutX="434.0" layoutY="125.0" prefHeight="250.0" prefWidth="413.0" spacing="10.0" />
MyComponent.fxml:
<fx:root type="javafx.scene.layout.AnchorPane" fx:id="leaderBoardElement" id="leaderBoardElement">
<TextField fx:id="textField" />
<Button fx:id="button" />
And i call the creation and loading of Winner.fxml from another class like this:
FXMLLoader loader = new FXMLLoader(getClass().getResource("/Winner.fxml"));
if (loader!=null)
System.out.println("LOADER NOT NULL!!");
try{
System.out.println("TRY!");
Parent root = (Parent) loader.load();
if(root!=null)
System.out.println("ROOT NOT NULL!!");
Scene startedGame = new Scene(root, 1280, 800, Color.WHITE);
if(startedGame!=null)
System.out.println("SCENE NOT NULL!");
Stage window = (Stage) paneCarta0.getScene().getWindow();
if (window!=null)
System.out.println("WINDOW NOT NULL!!");
window.setScene(startedGame);
window.show();
catch (IOException Exception) {
System.out.println("View not found. Error while loading");
}
The problem is inside the new MyComponent(), where probably i get an exception and it propagates to my main caller. I've tried everything but i can't figure out why it can't create the MyComponent object.
If your custom component is in a separate FXML file you can do this.
In your WinnerController class:
#FXML
private void initialize() throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getRessource("customElement.fxml"));
fxmlLoader.setController(new CustomElementController()); //Or just specify the Controller in the FXML file
myVBox.getChildren().add(fxmlLoader.load());
}
Edit: In this solution there should be NO <fx:include> tags in your main fxml
For anyone experienced with JavaFX, I have made a canvas inside my scene builder, but when I actually try to access said canvas it is null, I am not sure why as I know its made inside my scene builder and shows up in my FXML File
Ive gone ahead and pushed the code to github, it can be found here if anyone wants to look and see if I did something wrong:
https://github.com/ProSavage/JavaFXCalculator/tree/master/src/application/grapher
Feel free to give any other advice as well!
Here is the relevant code
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="application.grapher.GrapherController">
<children>
<HBox alignment="CENTER" layoutX="4.0" layoutY="280.0" prefHeight="20.0"
prefWidth="593.0">
<children>
<TextArea prefHeight="37.0" prefWidth="569.0" />
</children>
</HBox>
<Button layoutX="238.0" layoutY="336.0" mnemonicParsing="false"
prefHeight="50.0" prefWidth="125.0" text="Graph" />
<HBox fx:id="canvasBox" layoutX="14.0" layoutY="20.0"
prefHeight="250.0" prefWidth="570.0" />
</children>
</AnchorPane>
The class
public class GrapherController {
#FXML
private HBox canvasBox;
public void test() {
Canvas canvas = new Canvas(570,250);
canvasBox.getChildren().add(canvas);
double startX = canvas.getWidth()/2 * -1;
double endX = startX * -1;
double startY = canvas.getHeight()/2 * -1;
double endY = startY * -1;
GraphicsContext grapher = canvas.getGraphicsContext2D();
grapher.beginPath();
String equation = "x+1";
grapher.moveTo(startX,Evaluator.eval(equation.replace("x",startX + "")));
for (double i = startX; i < endX; i++) {
grapher.lineTo(startX,Evaluator.eval(equation.replace("x",String.valueOf(i))));
}
}
}
Basically when running the test method, If I create a canvas and add it to the box, the canvas is null and if I try making it into the xml file itself its still null. I feel like theres some essential step I am missing to the canvas it self.
It is actually your canvasBox field that is null. But the issue lies in your GrapherScene class. You are manually creating a GrapherController and calling test() on that instance. There is no possible way for canvasBox to not be null in that instance:
You never set it yourself
The instance wasn't created by a FXMLLoader which means no dependency injection of the FXML fields occur
Change:
public GrapherScene() {
try {
Stage grapherStage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("grapher.fxml"));
Scene scene = new Scene(root, 600, 400);
//scene.getStylesheets().add(getClass().getResource("app.css").toExternalForm());
grapherStage.setScene(scene);
grapherStage.setTitle("Grapher");
grapherStage.show();
} catch (Exception ex) {
ex.printStackTrace();
}
GrapherController grapher = new GrapherController();
grapher.test();
}
To:
public GrapherScene() {
try {
Stage grapherStage = new Stage();
FXMLLoader loader = new FXMLoader(getClass().getResource("grapher.fxml"));
grapherStage.setScene(new Scene(loader.load());
grapherStage.setTitle("Grapher");
grapherStage.show();
// Must be called AFTER loader.load()
// Method has generic return type so explicit casting is not necessary in this case
GrapherController grapher = loader.getController();
grapher.test();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Note: I'm using the instance FXMLLoader.load() method here and not the static FXMLLoader.load(URL) method.
For more information:
Accessing FXML controller class
JavaFX - How to get FXML Controller? [duplicate]
Passing Parameters JavaFX FXML
Introduction to FXML
I have a program that uses one form to add and display an object. I can use the form to add an object fine but when I try to display the same object in the form after this, no text will appear. The object is definitely added correctly and I can print out all of the elements so nothing is null. I think the error is with my .setText() line. I have created a smaller version of the program that just tries to display text:
public class TestApp extends Application {
private Stage primaryStage;
#FXML public TextField txtField;
#FXML public TextArea txtArea;
#FXML public Button btnTest;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Change Solutions");
showWelcome();
}
public void showWelcome(){
try{
AnchorPane page = FXMLLoader.load(TestApp.class.getResource("testFXML.fxml"));
page.setStyle("-fx-background: #FFFFFF;");
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("Welcome to Change Solutions");
primaryStage.show();
}catch (IOException i)
{
Logger.getLogger(TestApp.class.getName()).log(Level.SEVERE, null, i);
}
}
public void addText(){
txtArea.setText("test");
txtField.setText("test");
showWelcome();
}
public void handleButton(ActionEvent actionEvent) {
addText();
}
}
FXML:
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testpack.TestApp">
<children>
<AnchorPane layoutX="76.0" layoutY="70.0" prefHeight="243.0" prefWidth="309.0">
<children>
<TextField fx:id="txtField" layoutX="45.0" layoutY="40.0" promptText="TextField" AnchorPane.leftAnchor="45.0" AnchorPane.topAnchor="40.0" />
<TextArea fx:id="txtArea" layoutX="45.0" layoutY="81.0" prefHeight="138.0" prefWidth="149.0" promptText="TextArea" AnchorPane.leftAnchor="45.0" AnchorPane.topAnchor="81.0" />
<Button fx:id="btnTest" layoutX="217.0" layoutY="109.0" mnemonicParsing="false" onAction="#handleButton" text="Button" AnchorPane.bottomAnchor="109.0" AnchorPane.rightAnchor="40.0" />
</children>
</AnchorPane>
</children>
</AnchorPane>
The code, both here and in the actual program, compiles without errors.
I have see versions of this question before but none of the solutions work for me so I thought I would start a new thread.
I'm making some kind of information application about a city which I need to use a database for, I got my database set up and ready and most of the code needed as well; the only part is to extract the data I need from my SQL server into a BarChart in fxml. Can anyone give me a example or something?
My fxml:
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controllers.ControllerZW">
<BarChart fx:id="graph" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<xAxis>
<CategoryAxis side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis side="LEFT" />
</yAxis>
</BarChart>
</Pane>
My controller atm:
package Controllers;
public class ControllerZW implements Interface.Ibacktomenu {
#Override
public void backtomenu() {
try {
Main.mainStage.setScene(
new Scene(FXMLLoader.load(getClass().getResource("../scenes/MainMenu.fxml")))
);
} catch (IOException e) {
System.out.println("Probably couldnt find resource file");
e.printStackTrace();
}
}
}
Do you want to render the data form database to XML format?
I think some template engine maybe help you, such as Freemarker.
You could use Freemarker as view of Spring MVC, please refer to http://viralpatel.net/blogs/spring-mvc-freemarker-ftl-example/
Use a Task to get the data from the database and any method described in Passing Parameters JavaFX FXML to get the data to the controller, e.g.
#Override
public void start(Stage primaryStage) {
Task<Pane> dataLoader = new Task<Pane>() {
#Override
protected Pane call() throws Exception {
// create data
XYChart.Series<String, Double> rain = new XYChart.Series<>();
rain.setName("rain");
Month[] months = Month.values();
for (Month month : months) {
// simulates slow database connection; just adding some random values here
Thread.sleep(200);
rain.getData().add(new XYChart.Data<>(month.toString(), Math.random() * 100));
}
// load chart (replace BarChartLoad.class.getResource("chart.fxml") with your own URL)
FXMLLoader loader = new FXMLLoader(BarChartLoad.class.getResource("chart.fxml"));
Pane pane = loader.load();
// pass data to controller
loader.<ControllerZW>getController().setData(FXCollections.observableArrayList(rain));
return pane;
}
};
// placeholder
Pane root = new Pane();
Scene scene = new Scene(root, 1000, 600);
// set new scene root on successfull completion of the task
dataLoader.setOnSucceeded(evt -> scene.setRoot(dataLoader.getValue()));
// TODO: handle task failure
new Thread(dataLoader).start();
primaryStage.setScene(scene);
primaryStage.show();
}
public class ControllerZW implements Interface.Ibacktomenu {
#FXML
private BarChart<String, Double> graph;
public void setData(ObservableList<XYChart.Series<String, Double>> data) {
graph.setData(data);
}
...