I'm just starting to use JavaFx for a new application.
I know how to set the window title in the java code but how to set it in a fxml file ?
Thanks for your help.
Edit :
Here is the code I have
#Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
primaryStage.setTitle(applicationName);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
I just want set the title in Main.fxml.
to set the title of the stage in FXML, you need to construct the stage in FXML, like this:
<?xml version="1.0" encoding="utf-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.stage.Stage?>
<?import javafx.scene.Scene?>
<?import javafx.scene.control.Label?>
<Stage title="Some Stage">
<scene>
<Scene>
<VBox xmlns:fx="http://javafx.com/fxml">
<children>
<Label text="John Doe"/>
</children>
</VBox>
</Scene>
</scene>
</Stage>
If you only construct the root element of the scene (in my example, the VBox) via FXML and then put it into a scene afterwards like you do it (which is the common way), then it is impossible to set the title in FXML directly (without code behind).
Related
I'm extending javafx.stage.Popup to display a popup message. The entire app works fine on Windows and Ubuntu but on Mac Popups go behind the current stage when the app is full screen. I've tried using z-index,.toFront(), setting owner window and everything. But the popups just never showup! Same problem is with javafx.stage.FileChooser. Since the app must be fullscreen all the time, what is the solution?
EDIT: In another page,the textfield has cursor blinking in fullscreen but does not receive typed keys! And this happens ONLY in full screen! If I lose fullscreen, the textfield recieves typed keys. Quite annoying :( Please suggest if I should file a bug or something
I've figured out workaround for popup but problem persists for DirectoryChooser/FileChooser.
This is the class that extends Popup:
public class PopupDisplay extends Popup
{
String Title=new String("Information");
String Prompt=new String("Prompt Text");
#FXML
private AnchorPane anchorMain;
#FXML
private Label lblTitle=new Label();
#FXML
private Font x1;
#FXML
private Label lblPrompt=new Label();
#FXML
private Button btnOk;
#FXML
private GridPane gridMain;
#FXML
private HBox hboxTitle;
static PopupDisplay instance;
private ColorDxDesktop application;
public void show(Stage stage, String titleKey,String promptKey, Locale enLocale)
{
AnchorPane root;
FXMLLoader loader=new FXMLLoader();
ResourceBundle rb;
Prompt=promptKey;
Title=titleKey;
try
{
loader.setLocation(getClass().getResource("/com/sc/colordx/resources/"));
rb=ResourceBundle.getBundle("com.sc.colordx.resources.lang.Popup",application.getLocale());
loader.setResources(rb);
PopupController.prompt=Prompt;
PopupController.title=Title;
root = (AnchorPane)loader.load(getClass().getResource("/com/sc/colordx/presentation/Popup.fxml").openStream());
getScene().setRoot(root);
PopupController popupController=loader.getController();
Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
root.setPrefWidth(application.getStage().getWidth());
root.setPrefHeight(application.getStage().getHeight());
Node n=root.getChildren().get(0);
n.setLayoutX(screenBounds.getWidth()/2.5);
n.setLayoutY((screenBounds.getHeight()/2.5));
//root.toFront();
show(stage);
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
public static PopupDisplay getInstance()
{
return instance;
}
#FXML
private void hide(MouseEvent event)
{
this.hide();
}
public void showInProgress()
{
PopupController.showInProgress();
}
And this is the FXML for Popup:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<AnchorPane id="AnchorPane" fx:id="anchorMain" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="768.0" prefWidth="1024.0" styleClass="mainFxmlClass" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.sc.colordx.controller.PopupController">
<children>
<GridPane id="GridPane" fx:id="gridMain" alignment="CENTER" layoutX="309.0" layoutY="330.0" minWidth="400.0" style="-fx-background-color:black;" styleClass="visibleWindow, gridpane, gridpane-boder" vgap="20.0">
<children>
<Label fx:id="lblPrompt" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="271.0" text="%keyPrompt" textFill="WHITE" textOverrun="CLIP" wrapText="true" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
<font>
<Font name="System Bold" size="14.0" fx:id="x1" />
</font>
<GridPane.margin>
<Insets bottom="6.0" left="6.0" right="6.0" top="6.0" />
</GridPane.margin>
</Label>
<HBox id="HBox" fx:id="hboxButtons" alignment="CENTER" spacing="7.0" style="" styleClass="hbox" GridPane.columnIndex="0" GridPane.hgrow="ALWAYS" GridPane.rowIndex="2" GridPane.vgrow="ALWAYS">
<children>
<Button fx:id="btnOk" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onMouseClicked="#exitOkay" text="%keyYes" HBox.hgrow="ALWAYS" />
<Button id="btnOk" fx:id="btnCancel" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onMouseClicked="#hide" text="%keyNo" HBox.hgrow="ALWAYS" />
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
<stylesheets>
<URL value="#../resources/css/Popup.css" />
</stylesheets>
</HBox>
<ProgressIndicator fx:id="progress" cache="true" cacheHint="QUALITY" progress="0.0" visible="false" GridPane.columnIndex="0" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="300.0" />
</GridPane.margin>
</ProgressIndicator>
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
</columnConstraints>
<padding>
<Insets />
</padding>
<rowConstraints>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</children>
<stylesheets>
<URL value="#../resources/css/Popup.css" />
</stylesheets>
</AnchorPane>
The same thing I was getting with Popup while running JavaFx application in MAC so what I did was created new Stage (dummy/invisible with height and width = 0) with initStyle(StageStyle.UTILITY); and bind my popup with that. Everytime I need to display popup I use dummyStage.show(); and popup.toFront(); so it will cause a trick to handle my problem in mac.
Can someone suggest ,how can we pass the value from one controller to another controller .
My scenario is below
I need to get the username on my home page after login.
please share the piece of code.
Thanks in Advance!!!
As I understood from your question, you need a login screen and then other screens in a row for navigation. First user has to sign in and after validating then the user information will go to the Home screen. Below is the codes which may help you -
Main.java
package sample;
import javafx.application.Application;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
LoginController loginController = new LoginController();
loginController.launchLogingController(primaryStage);
}
public static void main(String[] args) {
launch(args);
}
}
LoginController.java
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import java.io.IOException;
public class LoginController {
private Parent parent;
private Scene scene;
private Stage stage;
#FXML
private TextField userName;
#FXML
private TextField passwordField;
private HomeController homeController;
public LoginController() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/login.fxml"));
fxmlLoader.setController(this);
try {
parent = (Parent) fxmlLoader.load();
scene = new Scene(parent, 600, 400);
} catch (IOException e) {
e.printStackTrace();
}
}
#FXML
protected void handleSubmitButtonAction(ActionEvent event) {
System.out.println(userName.getText());
if (userName.getText().trim().length() > 0 && passwordField.getText().trim().length() > 0) {
homeController = new HomeController();
homeController.redirectHome(stage, userName.getText().trim());
}
}
public void launchLogingController(Stage stage) {
this.stage = stage;
stage.setTitle("User Login");
stage.setScene(scene);
stage.setResizable(true);
stage.hide();
stage.show();
}
}
HomeController.java
package sample;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import java.io.IOException;
public class HomeController {
private Parent parent;
private Scene scene;
private Stage stage;
#FXML
private Text welcomeText;
public HomeController() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/home.fxml"));
fxmlLoader.setController(this);
try {
parent = (Parent) fxmlLoader.load();
scene = new Scene(parent, 600, 400);
} catch (IOException e) {
e.printStackTrace();
}
}
public void redirectHome(Stage stage, String name) {
stage.setTitle("Home");
stage.setScene(scene);
welcomeText.setText("Hello " + name + "! You are welcome.");
stage.hide();
stage.show();
}
}
home.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.text.*?>
<?import sample.LoginController?>
<GridPane alignment="CENTER" hgap="10.0" vgap="10.0" xmlns:fx="http://javafx.com/fxml">
<padding>
<Insets bottom="10.0" left="25.0" right="25.0" top="25.0" />
</padding>
<Text fx:id="welcomeText" text="home" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="0" />
</GridPane>
login.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.text.*?>
<?import sample.LoginController?>
<GridPane alignment="CENTER" hgap="10.0" vgap="10.0" xmlns:fx="http://javafx.com/fxml">
<padding>
<Insets bottom="10.0" left="25.0" right="25.0" top="25.0" />
</padding>
<Text text="Login" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="0" />
<Label text="User Name:" GridPane.columnIndex="0" GridPane.rowIndex="1" />
<TextField fx:id="userName" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label text="Password:" GridPane.columnIndex="0" GridPane.rowIndex="2" />
<PasswordField fx:id="passwordField" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<HBox alignment="BOTTOM_RIGHT" spacing="10.0" GridPane.columnIndex="1" GridPane.rowIndex="4">
<Button onAction="#handleSubmitButtonAction" text="Sign In" />
</HBox>
</GridPane>
Using Maven will be better for tackling problems.
Thanks!
today's question is about embedding a map view into a JavaFX application. I basically followed the instructions on StackOverFlow - embedding google map in JavaFX and Embed OpenLayers with OpenStreetMap, so everything like the *.html file is in place. But there, people are adding the WebView to main Scene. For me, I would like to add the WebView to a SplitPane. ThereFore I prepared the application.fxml file as followed:
<SplitPane id="SplitPane" dividerPositions="0.5" orientation="HORIZONTAL" prefHeight="260.0" prefWidth="850.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<TableView id="tableView1" fx:id="table" prefHeight="263.0" prefWidth="433.0">
<columns>
<TableColumn text="one" /><TableColumn text="two" /><TableColumn text="three" />
</columns>
</TableView>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Region fx:id="webViewRegion" prefHeight="200.0" prefWidth="200.0" />
</children>
</AnchorPane>
</items>
</SplitPane>
The FXML file is loaded by the FXMLLoader when the application is started. In the application controller I get the Region as followed:
#FXML
private Region webViewRegion;
class MyMapView extends Region {
HBox toolbar;
WebView webview = new WebView();
WebEngine webEngine = webview.getEngine();
public MyMapView() {
final URL urlGoogleMaps = getClass().getResource("openstreetmap.html");
webEngine.load(urlGoogleMaps.toExternalForm());
getChildren().add(webview);
}
}
private void load_webView() {
webViewRegion = new MyMapView();
}
For me, now I do not exactly know how to populate the Region with the Webview in a correct way or if there is any better approach?
I am using a BorderPane, where the right area is unused. In the center area I have a HBox with a Canvas and another control e.g. a Button. I want the Canvas to have the same width and height with a value of
Canvas width and height = minimum{maximum possible Canvas height, maximum possible Canvas width}
(in other words: Canvas should be a square)
My problem is: How do I determine the maximum width and the maximum height that a Canvas could grow to?
Here is my FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<BorderPane id="BorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml">
<bottom>
<Label text="Bottom area" />
</bottom>
<center>
<HBox>
<children>
<Canvas width="300" height="300" />
<Button mnemonicParsing="false" text="some button next to the Canvas" />
</children>
</HBox>
</center>
<left>
<Button mnemonicParsing="false" text="Left area"/>
</left>
<top>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
</BorderPane>
Thanks for any hint!
The easiest way I can see this being done is: canvas.getwidth() and canvas.getHeight()
You have to add canvas manually, after the GUI is constructed, so you can calculate its size:
public class YourController implements Initializable {
#FXML HBox mHBox;
#FXML Button mButton;
#Override
public void initialize(final URL paramURL, final ResourceBundle paramResourceBundle) {
Platform.runLater(new Runnable() { public void run() {
double w0 = mHBox.getWidth();
double w1 = mButton.getWidth();
double h0 = mHBox.getHeight();
double size = Math.min(w0-w1, h0);
Canvas canvas = new Canvas(size, size);
mHBox.getChildren().add(0, canvas);
}});
}
}
Problem with the Canvas is that is is not resizable :(
I'm tryin to build a skeleton for a big complex gui, so the idea is to make everything with mvc like style in javafx 2.1, so every component has a fxml file and if needed css,controller and model. I'm tryin to figure out how to change sub scenes(sub fxml at runtime). Anybody know how to do it? I'm kinda stuck on this. May bee to add MainViewController? scenario: user clicks on button in taskbar and the included content1.fxml will be replaced with content2.fxml
here the basic code
MainApp.java
Loads the MainView.fxml
MainView.fxml
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml">
<center>
<fx:include source="Content1.fxml"/>
</center>
<bottom>
<fx:include source="TaskBar.fxml"/>
</bottom>
</BorderPane>
Content1.fxml
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane xmlns:fx="http://javafx.com/fxml" fx:id="content1">
<Label text="Hallo Java FX 2.1.1 Content1.fxml"/>
</StackPane>
Content2.fxml
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane xmlns:fx="http://javafx.com/fxml" fx:id="content2">
<Label text="Hallo Java FX 2.1.1 Content2.fxml"/>
</StackPane>
TaskBar.fxml
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<HBox xmlns:fx="http://javafx.com/fxml" spacing="10" alignment="center"
fx:id="taskBar" fx:controller="TaskBarController">
<children>
<Button fx:id="taskBarButton1" onAction="#handleTaskBarButton1Action"/>
<Button fx:id="taskBarButton2" onAction="#handleTaskBarButton2Action"/>
</children>
</HBox>
TaskBarController.java
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
public class TaskBarController implements Initializable {
// Binding with the FXML
#FXML
private Button taskBarButton1;
#FXML
private Button taskBarButton2;
#FXML
private void handleTaskBarButton1Action(ActionEvent event) {
System.out.println("click! taskBarButton1");
}
#FXML
private void handleTaskBarButton2Action(ActionEvent event) {
System.out.println("click! taskBarButton2");
}
#Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
}
}
Don't just include fxml, create a business logic layer for that:
<BorderPane xmlns:fx="http://javafx.com/fxml">
<center>
<Pane fx:id="content"/>
</center>
and update it in button click handlers:
#FXML
private void handleTaskBarButton2Action(ActionEvent event) {
System.out.println("click! taskBarButton2");
content.getChildren().clear();
content.getChildren().add(FXMLLoader.load(getClass().getResource("Content2.fxml"));
}
it works,thx for help, but i was forced to remove TaskBar.fxml and TaskBarController.java , wrote a MainViewController with #FXML handles and #FXML for the Buttons and the Pane with the fx:id="content" , and put my customs Buttons in MainView.fxml
#FXML
private void handleTaskBarButton2Action(ActionEvent event) throws IOException {
System.out.println("click! taskBarButton2");
content.getChildren().clear();
content.getChildren().add((Node) FXMLLoader.load(getClass().getResource("Content2.fxml")));
}