Image FXML is not opening in JavaFX - java

While I was trying to load two different scenes, it doesn't open the image FXML, basically I want the image FXML to be opened first followed by welcome screen. Some how Image scene is not showing.
Main.java
public class Main extends Application {
#Override
public void start(Stage stage) throws Exception {
System.out.println("im in main");
Parent root = FXMLLoader.load(getClass().getResource("ImageScreen.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("test");
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
ImageScreen.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.StackPane?>
<StackPane fx:id="imagepane" maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.102" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="application.ImageScreenController">
<children>
<ImageView fitHeight="438.0" fitWidth="603.0" pickOnBounds="true"
preserveRatio="true">
<image>
<Image url="#bamboo-fountain-and-zen-stone.jpg" />
</image>
</ImageView>
<Pane prefHeight="200.0" prefWidth="200.0" />
</children>
ImageScreenController
public class ImageScreenController implements Initializable {
#FXML
private StackPane imagepane;
public static AnchorPane welcomepane;
#Override
public void initialize(URL url, ResourceBundle rb) {
AnchorPane pane;
try {
System.out.println("im in controller");
pane = FXMLLoader.load(getClass().getResource("WelcomeFXMLDoc.fxml"));
imagepane.getChildren().setAll(pane);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
WelcomeFXMLDoc.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<AnchorPane fx:id="welcomepane" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.102"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.WelcomeFXMLController">
<children>
<Text layoutX="212.0" layoutY="100.0" strokeType="OUTSIDE"
strokeWidth="0.0" text="Welcome" wrappingWidth="176.13671875">
<font>
<Font size="35.0" />
</font>
</Text>
</children>
WelcomeFXMLController.java
public class WelcomeFXMLController implements Initializable {
/**
* Initializes the controller class.
*
*/
#FXML
private AnchorPane welcomepane;
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}

In ImageScreenController you use imagepane.getChildren().setAll(pane). setAll() clear collection and then add new elements. In this case you remove ImageView from scene graph and show only welcomepane.
Use imagepane.getChildren().add(pane); instead and then remove welcomepane when you don't need is anymore.
EDIT
Based on your comment.
Use PauseTransition to wait for WelcomeFXMLController:
#Override
public void initialize(URL url, ResourceBundle rb) {
PauseTransition pt = new PauseTransition(Duration.seconds(10));
pt.setOnFinished(e -> {
AnchorPane pane;
try {
System.out.println("im in controller");
pane = FXMLLoader.load(getClass().getResource("WelcomeFXMLDoc.fxml"));
imagepane.getChildren().setAll(pane);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
pt.play();
}

Related

View Injection in FXML

#Override
public void start(Stage stage) throws Exception {
BorderPane root = FXMLLoader.load(getClass().getClassLoader().getResource("mainView.fxml"));
When i run this it doesnt show the injected views
Im building a new application with JavaFX for the main page im using 3 views build by 3 fxml files
each view has its controller. for the main page i want to inject the three fxml files in a mainView.fxml via fx:include the mainView.fxml has also a controller how can i do that?
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>
<fx:root alignment="CENTER_LEFT" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="93.0" prefWidth="600.0" style="-fx-min-width: 800; -fx-min-height: 100; -fx-spacing: 30;" type="javafx.scene.layout.HBox" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label fx:id="title" alignment="CENTER" prefHeight="91.0" prefWidth="179.0" style="-fx-label-padding: 20; -fx-line-spacing: 20;" text="News" textFill="#00a4f2">
<font>
<Font name="Arial Black" size="36.0" />
</font>
<opaqueInsets>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</opaqueInsets></Label>
<Button fx:id="refresh" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" style="-fx-alignment: CENTER; -fx-background-color: #66a6ff;" text="Button" textAlignment="CENTER">
<opaqueInsets>
<Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
</opaqueInsets></Button>
<Button fx:id="stat" alignment="CENTER" mnemonicParsing="false" style="-fx-background-color: #feada6;" text="Button">
<opaqueInsets>
<Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
</opaqueInsets></Button>
</children>
</fx:root>
This is per example the topView.fxml
package ch.bfh.spacenews;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
public class TopBarController extends HBox {
#FXML
public Label title;
#FXML
public Button refresh;
#FXML
public Button stat;
TopBarController(){
FXMLLoader load = new FXMLLoader(getClass().getClassLoader().getResource("topView.fxml"));
load.setRoot(this);
load.setController(this);
try {
System.out.println("TopBarController");
load.load();
}catch(IOException e) {
e.printStackTrace();
}
}
}
This is the corresponding controller of the topView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<BorderPane fx:controller="ch.bfh.spacenews.mainController" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
<top>
<fx:include fx:id="topBar" source="topView.fxml"/>
</top>
<center>
<fx:include fx:id="article" source="sample.fxml"/>
</center>
<right>
<fx:include fx:id="seacrh" source="searchView.fxml"/>
</right>
</BorderPane>
This is where i want to inject the topView.fxml
package ch.bfh.spacenews;
import javafx.fxml.FXML;
public class mainController {
#FXML
TopBarController topBarController;
#FXML
ArticleController articleController;
#FXML
SearchController searchController;
#FXML
public void initialize() {
}
}
And this is the Controller of the mainView.fxml where i want to inject the topView.fxml
In the FXML custom component pattern the controller classes also serve as the wrapper for the view, by subclassing an appropriate Node subclass. This means you can just instantiate them directly in the FXML via the FXMLLoader. For example, the <TopBarController> element instructs the FXMLLoader to instantiate the TopBarController by calling its no-argument constructor. That constructor, as per your code, loads topView.fxml, etc. There is no need to use <fx:include>, which is an instruction for the FXMLLoader to load another FXML file, since you already have code in your TopBarController to do that.
So your main view FXML file should look like:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<?import ch.bfh.spacenews.TopBarController?>
<!-- other imports... -->
<BorderPane fx:controller="ch.bfh.spacenews.MainController" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
<top>
<TopBarController fx:id="topBar" />
</top>
<center>
<ArticleController fx:id="article" />
</center>
<right>
<SearchController fx:id="search" />
</right>
</BorderPane>
And the corresponding controller is
package ch.bfh.spacenews;
import javafx.fxml.FXML;
public class MainController {
#FXML
TopBarController topBar;
#FXML
ArticleController article;
#FXML
SearchController search;
#FXML
public void initialize() {
}
}
Note that it's really critical to follow standard naming conventions here. The FXMLLoader explicitly relies on the case of an element to determine if it's referring to a class name or a property name.
Main class : Launch.java
public class Launch extends Application {
#Override
public void start(Stage stage) throws Exception {
Controller.show(stage);
}
public static void main(String[] args) {
launch(args);
}
}
You can add view from controller :
public class Controller {
public BorderPane mainPane; // fx:id of your pane
public static Stage current;
public static void show(Stage stage) {
this.current = stage;
Scene scene = null;
BorderPane pane = null;
try {
scene = new Scene(FXMLLoader.load(getClass().getResource("mainView.fxml")));
pane = (BorderPane) scene.lookup("#mainPane");
// Add .fxml view to mainView
pane.setCenter(FXMLLoader.load(getClass().getResource("sample.fxml")));
pane.setTop(FXMLLoader.load(getClass().getResource("topView.fxml")));
pane.setRight(FXMLLoader.load(getClass().getResource("searchView.fxml")));
} catch (IOException e) {
e.printStackTrace();
}
stage.setTitle("MainView");
stage.setScene(scene);
stage.show();
}
}

Caused by: javafx.fxml.LoadException: Root is not an instance of javafx.scene.layout.AnchorPane

I am trying to create my project but facing issue
main class
public class Controller extends AnchorPane {
public Controller() throws IOException {
System.out.println("is this called");
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
FXML File
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button layoutX="198.0" layoutY="129.0" mnemonicParsing="false" text="Button" />
<Button layoutX="198.0" layoutY="200.0" mnemonicParsing="false" onAction="#handleButtonAction" text="Button" />
</children>
</AnchorPane>
Controller class
public class FXMLDocumentController implements Initializable {
private Label label;
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
}
}

JavaFX / FXML UI does not look like it should

I have a UI I have made using Netbeans and Scene builder using Java FX / FXML. I have never had a problem with it before but for this project for some reason in Scene building my UI would look one way, even the windows preview would look identical to it, but when running it in netbeans it would look messed up. In netbeans, all I am doing is loading and calling it. I have no idea on what the issue can be and nothing is helping on Google.
working screen shot on scene builder and editing and netbeans
http://imgur.com/laZYjck
compile and run
http://imgur.com/NOMVBZe
main.java
public class main
{
public static void main(String[] args)
{
View view = new View();
view.launch();
}
}
view.java
public class View extends Application
{
#FXML
private Button login;
#Override
public void start(Stage primaryStage)
{
Parent login_page = null;
try {
login_page = FXMLLoader.load(getClass().getResource("FXMLViewLogin.fxml"));
}
catch (IOException ex)
{
}
primaryStage.setTitle("Welcome!");
primaryStage.setScene(new Scene(login_page));
primaryStage.show();
}
#FXML
private void login(ActionEvent event)
{}
}
FXMLViewLogin.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="520.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.ViewControllerLogin">
<children>
<Button fx:id="button1" defaultButton="true" layoutX="74.0" layoutY="296.0" text="Sign Up" />
<Label layoutX="198.0" layoutY="153.0" text="Password" />
<Label layoutX="187.0" layoutY="35.0" text="User Name" />
<TextField fx:id="password" layoutX="74.0" layoutY="204.0" />
<TextField fx:id="username" layoutX="74.0" layoutY="80.0" />
<Button fx:id="button" layoutX="323.0" layoutY="296.0" onAction="#login" text="Log In" />
</children>
</Pane>

Managing a ComboBox items in JavaFX

I'm populating a ComboBox using Text objects. Using Text objects rather than Strings allows me to add an id value that I can use in my program and later exploit when I decide to internationalize the UI. Anyway, here is what I'm doing:
Main class:
public class MainApp extends Application {
private Stage primaryStage;
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
try {
AnchorPane paneMain = (AnchorPane) FXMLLoader.load(getClass().getResource("Test.fxml"));
Scene scene = new Scene(paneMain);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Controller:
public class Test implements Initializable{
#FXML
private AnchorPane anchorPane;
#FXML
private ComboBox<Text> comboTime;
private Text days;
private Text hours;
private Text minutes;
private int timeMultiplier;
public Test(){
days = new Text("Days");
days.setId("86400000");
hours = new Text("Hours");
hours.setId("3600000");
minutes = new Text("Minutes");
minutes.setId("3600000");
timeMultiplier = 0;
}
#Override
public void initialize(URL location, ResourceBundle resources) {
comboTime.getItems().removeAll(comboTime.getItems());
comboTime.getItems().addAll(days, hours, minutes);
comboTime.getSelectionModel().select(hours);
}
#FXML
private void setTimeMultiplier(){
Text text = comboTime.getSelectionModel().getSelectedItem();
timeMultiplier = Integer.valueOf(text.getId());
}
}
Test.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<AnchorPane id="AnchorPane" fx:id="anchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="100.99990000000253" prefWidth="94.99990000000253" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.spacitron.backupp.ui.controllers.Test">
<children>
<HBox id="HBox" alignment="CENTER" layoutX="41.0" layoutY="224.0" prefWidth="216.0" spacing="5.0" />
<ComboBox id="comboInterval" fx:id="comboTime" editable="false" layoutX="14.0" layoutY="22.0" onAction="#setTimeMultiplier">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="Item 1" />
<String fx:value="Item 2" />
<String fx:value="Item 3" />
</FXCollections>
</items>
</ComboBox>
</children>
</AnchorPane>
Now, this works just fine. The problem however is that when I select an item the text on that item goes blank like so:
And if I select another one, that disappears too:
I can still select the items, but they're just not there to be seen. Is this a bug and if so is there a way around it?
EDITED to provide MCVE
You shouldn't be putting the Text nodes into the ComboBox ... please see this question that will help you: setButtonCell for ComboBox

JavaFX 2.0 FXML Child Windows

After much searching I found this question How to create a javafx 2.0 application MDI. What I really wanted to know is if I can create a pop-up window or child window to the main window using JavaFX components and Scene Builder to create the new window.
I ended up with this for a modal pop-up window:
In the Main class I wanted to save the primary stage to a field I can access from my primary controller class. So, I added a static variable Stage to it and this in the Main.Start() method:
primaryController.primaryStage = primaryStage;
This the method that a button in the primaryController uses:
public void OnBtnShowChild(ActionEvent event) {
MessageBoxController msgBox = new MessageBoxController();
try {
msgBox.showMessageBox(primaryStage);
} catch (Exception e) {
e.printStackTrace();
}
}
This is the MessageBoxController class that I created with help from Scene Builder. It has the basic layout of a standard pop-up box that can be used to display an Icon (ImageView), TextBox (for your message text), and two buttons (for YES/NO functionality). I am not sure yet how to have it communicate the results of what button was pressed back to the primaryController.
public class MessageBoxController implements Initializable {
#FXML
// fx:id="btnNo"
private Button btnNo; // Value injected by FXMLLoader
#FXML
// fx:id="btnYes"
private Button btnYes; // Value injected by FXMLLoader
#FXML
// fx:id="imgMessage"
private ImageView imgMessage; // Value injected by FXMLLoader
#FXML
// fx:id="txtMessage"
private TextField txtMessage; // Value injected by FXMLLoader
private Stage myParent;
private Stage messageBoxStage;
public void showMessageBox(Stage parentStage) {
this.myParent = parentStage;
try {
messageBoxStage = new Stage();
AnchorPane page = (AnchorPane) FXMLLoader.load(MessageBoxController.class.getResource("/MessageBox/MessageBoxFXML.fxml"));
Scene scene = new Scene(page);
messageBoxStage.setScene(scene);
messageBoxStage.setTitle("Message Box");
messageBoxStage.initOwner(this.myParent);
messageBoxStage.initModality(Modality.WINDOW_MODAL);
messageBoxStage.show();
} catch (Exception ex) {
System.out.println("Exception foundeth in showMessageBox");
ex.printStackTrace();
}
}
#Override
public void initialize(URL fxmlFileLocation, ResourceBundle arg1) {
txtMessage.setText("Howdy");
}
public void OnBtnYes(ActionEvent event) {
}
public void OnBtnNo(ActionEvent event) {
}
}
And finally, this is the FXML file I created in Scene Builder:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="172.0" prefWidth="524.0" xmlns:fx="http://javafx.com/fxml" fx:controller="MessageBox.MessageBoxController">
<children>
<VBox prefHeight="172.0" prefWidth="524.0" styleClass="vboxes" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<HBox alignment="CENTER" prefHeight="109.99990000000253" prefWidth="516.0" spacing="30.0">
<children>
<ImageView fx:id="imgMessage" fitHeight="110.0" fitWidth="146.66666666666666" pickOnBounds="true" preserveRatio="true" styleClass="null" />
<TextField fx:id="txtMessage" editable="false" prefHeight="47.0" prefWidth="325.0" />
</children>
<stylesheets>
<URL value="#MyCSS.css" />
</stylesheets>
</HBox>
<HBox alignment="CENTER" prefHeight="58.0" prefWidth="516.0" spacing="30.0">
<children>
<Button fx:id="btnYes" mnemonicParsing="false" onAction="#OnBtnYes" text="Button" />
<Button fx:id="btnNo" mnemonicParsing="false" onAction="#OnBtnNo" text="Button" />
</children>
</HBox>
</children>
<stylesheets>
<URL value="#MyCSS.css" />
</stylesheets>
</VBox>
</children>
<stylesheets>
<URL value="#MyCSS.css" />
</stylesheets>
</AnchorPane>
With this I can create a modal pop-up window, and I also want to create other child windows for displaying data in other ways using different controls. And, most importantly, I can use Scene Builder to create the layout.
What do you think? Is this a good way to do this until they add real support in Java 8 and JavaFX 8?
did you try wit the Group class? you can add diferent elements with fxml and controllers.
Group root= new Group();
AnchorPane frame=FXMLLoader.load(getClass().getResource("frame.fxml"));
AnchorPane content= FXMLLoader.load(getClass().getResource("principal.fxml"));
root.getChildren().add(window);
root.getChildren().add(frame);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();

Categories