javafx and scene builder - javafx

#Override
public void start(Stage stage) throws Exception {
PieChart pie = new PieChart();
pie.setData(getChart());
StackPane pane = new StackPane();
Scene scene = new Scene(pane);
stage.setScene(scene);
pane.getChildren().addAll(pie);
stage.show();
}
private ObservableList<PieChart.Data> getChart() {
ObservableList<PieChart.Data> list = FXCollections.observableArrayList();
list.addAll(new PieChart.Data("java",20), new PieChart.Data("c",20),
new PieChart.Data("C++",20));
return list;
}
i want this chart to be displayed on scene builder. how is it possible..??

In SceneBuilder, from the menu:
Select File | Open
Choose pie.fxml
Select View | Show Sample Data
pie.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.chart.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<StackPane id="StackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="250.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
<children>
<PieChart id="PieChart" prefHeight="-1.0" prefWidth="-1.0" />
</children>
</StackPane>

Related

Passing a Button in FXML using JavaFX

Hello I Have this portion of my code, I actually need disable the button when the user is logging, I am trying to pass the button to the FXML, but nothing happens: this is the code in the Main Controller, when the user is logged and data match with the password and username the button with the variable btn1 must disabled, I post my entire code for any help.
public Button getBtn1() {
return btn1;
}
public void conexion () {
String usus="";
String Passu ="";
String Bd="jdbc:sqlserver: // THUMANO2:1433;databaseName=QUORA";
String Usuario="sa";
String Pass="milkas87";
String SqlQuery= "select NOMBREUSUARIO, CONVERT (VARCHAR(50), (DecryptByPassPhrase('*xc/6789oÑ---+y',PASS))) as PASS from usuarios where CONVERT (VARCHAR(50), (DecryptByPassPhrase('*xc/6789oÑ---+y',PASS)))='"+fcontrasena.getText().toString().trim()+"'";
Connection Conexion = null;
try {
Conexion=DriverManager.getConnection(Bd, Usuario, Pass);
PreparedStatement ps =Conexion.prepareStatement(SqlQuery);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
usus = rs.getString("NOMBREUSUARIO");
Passu = rs.getString("PASS");
}
if(fcontrasena.getText().toString().trim().equals(Passu) && fusuario.getText().toString().equals(usus)) {
Stage administrador=new Stage();
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Admin.fxml"));
Stage login=(Stage)fusuario.getScene().getWindow();
Parent root = loader.load();
AdminScreenController controlador = loader.<AdminScreenController>getController();
controlador.setBtn1(btn1);
Scene scene=new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
administrador.setScene(scene);
administrador.setTitle("AdminScreen");
login.hide();
administrador.show();
} catch(Exception e) {}
}
} catch(SQLException e) {
JOptionPane.showMessageDialog(null,"error","ERROR",0);
}
}
this is the code for AdminScreenController:
public void setBtn1(Button btn1) {
btn1.setDisable(true);
}
this is the FXML Document:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="576.0" prefWidth="791.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.AdminScreenController">
<children>
<BorderPane fx:id="bpane" prefHeight="621.0" prefWidth="791.0">
<left>
<VBox fx:id="vboxr" prefHeight="576.0" prefWidth="205.0" BorderPane.alignment="CENTER">
<children>
<BorderPane prefHeight="106.0" prefWidth="205.0">
<center>
<Button fx:id="btn1" mnemonicParsing="false" prefHeight="51.0" prefWidth="127.0" text="Planilla Sistemas" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
<BorderPane prefHeight="106.0" prefWidth="205.0">
<center>
<Button fx:id="btn2" mnemonicParsing="false" prefHeight="51.0" prefWidth="127.0" text="AMP" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
<BorderPane prefHeight="116.0" prefWidth="205.0">
<center>
<Button fx:id="btn3" mnemonicParsing="false" prefHeight="51.0" prefWidth="127.0" text="Tareas Funcionarios" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
<BorderPane prefHeight="106.0" prefWidth="205.0">
<center>
<Button fx:id="btn4" mnemonicParsing="false" prefHeight="51.0" prefWidth="127.0" text="Indicadores" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
<BorderPane prefHeight="106.0" prefWidth="205.0" />
</children>
</VBox>
</left>
<top>
<BorderPane prefHeight="145.0" prefWidth="791.0" BorderPane.alignment="CENTER">
<left>
<Pane fx:id="imgview" prefHeight="145.0" prefWidth="205.0" BorderPane.alignment="CENTER" />
</left>
</BorderPane>
</top>
</BorderPane>
</children>
</StackPane>
its something wrong? i need some orientation here. thanks.
Here is an example that shows the MVC relationship in JavaFX. The button is defined in FXML and injected into the controller where it can be accessed.
TestAppView.fxml
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="CENTER" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.app.TestAppController">
<Button fx:id="myButton" text="Hello World" />
</VBox>
TestAppController.java
public class TestAppController implements Initializable {
#FXML
private Button myButton;
#Override
public void initialize(URL url, ResourceBundle resources) {
// Prints Hello World & disables the button when clicked
myButton.setOnAction((e) -> {
System.out.println("Hello World");
myButton.setDisable(true);
});
}
}
TestAppMain.java
public class TestAppMain extends Application {
#Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(TestAppController.class.getResource("TestAppView.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root, 200, 200);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Changing the value of comboBox via another controller isn't triggering the onAction callback in JavaFX

Two controllers are there and their respective FXML files.
If I click on the button in View1.fxml, the value of the comboBox is being changed however I am not getting the output in the console.
But if I click on the changeValueOfDemoComboBoxBtn in View2.fxml, the output is printed in the console.
View1.fxml
<?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/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller1">
<children>
<Button fx:id="button" layoutX="187.0" layoutY="120.0" mnemonicParsing="false" onAction="#handleButtonAction" text="Button" />
</children>
</AnchorPane>
View2.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?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/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller2">
<children>
<Button fx:id="changeValueOfDemoComboBoxBtn" layoutX="200.0" layoutY="264.0" mnemonicParsing="false" onAction="#handleChangeValueOfDemoComboBoxBtnAction" text="Button" />
<ComboBox fx:id="demoComboBox" layoutX="161.0" layoutY="127.0" onAction="#handleDemoComboBox" prefWidth="150.0" />
</children>
</AnchorPane>
Controller1.java
#FXML
private Button button;
#FXML
private void handleButtonAction() throws IOException {
StackPane contentStackPane = (StackPane)mainScene.lookup("#contentStackPane");
FXMLLoader loader = new FXMLLoader(getClass().getResource("view2.fxml));
Parent view2Fxml = loader.load();
Controller2 controller2 = loader.getController();
controller2.setDemoComboBox("Apple");
contentStackPane.getChildren().removeAll();
contentStackPane.getChildren().setAll(view2Fxml );
}
Controller2.java
#FXML
private ComboBox<String> demoComboBox;
#FXML
private Button changeValueOfDemoComboBoxBtn;
#FXML
private void handleDemoComboBox() {
System.out.println("Value changed in Demo ComboBox");
}
#FXML
private void handleChangeValueOfDemoComboBoxBtnAction(){
setDemoComboBox("Oranges");
}
public void setDemoComboBox(String value){
demoComboBox.setValue(value);
}

JavaFX loading a new fxml file into the same scene

I have a class named Test1Controller where a Scene is executed and in another class, Test2Controller, I want to load another FXML but in the same Scene. Can someone help me with this?
public class Test1Controller {
private static AnchorPane page;
public static Stage initialicePage() {
primaryStage = new Stage();
page = (AnchorPane) FXMLLoader.load(Principal.class.getResource("Test1.fxml"));
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("Test1");
primaryStage.setResizable(true);
primaryStage.setMinHeight(700);
primaryStage.setMinWidth(824);
primaryStage.setMaximized(true);
primaryStage.show();
}
}
public class SwitchScene extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
public class FXMLDocumentController {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
try {
Parent root = FXMLLoader.load(getClass().getResource("SecondScreen.fxml"));
Scene dashboard=new Scene(root);
//This line gets the Stage Information
Stage window=(Stage)((Node)event.getSource()).getScene().getWindow();
window.setScene(dashboard);
window.show();
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class SecondScreenController {
public void MoveBack(ActionEvent event){
try {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene dashboard = new Scene(root);
//This line gets the Stage Information
//here we get the stage from event action and setting the root element in the scene and display scene with stage object (window) which is retrieved from action event
Stage window=(Stage)((Node)event.getSource()).getScene().getWindow();
window.setScene(dashboard);
window.show();
} catch (IOException ex) {
Logger.getLogger(SecondScreenController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
//FXMLDocument.xml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="switchscene.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
////SecondScreen fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="switchscene.SecondScreenController">
<children>
<Button fx:id="btnMove" layoutX="269.0" layoutY="188.0" mnemonicParsing="false" onAction="#MoveBack" text="Move Back" />
</children>
</AnchorPane>

JAVAFX - Change specific Pane only using 1 window

Can you Help me how to change the Spesific pane in 1 scene.
So when i want to click the Menu A. The Content will change to content A.
And when i click the menu B. The Content will be change to Content B
i try with the 2 FXML and using normal method like load screen A an screen B
But the result only change the window. i want to change the content with 1 window only.
Is there any suggestion how to change the specific pane in 1 window?
As an option.
Make FXML and controller for any "Content" and when the some button is clicked to delete the old "Content" and upload new.
Working example below (edited according to James_D comment):
Main.java
public class Main extends Application {
Parent root;
Stage stage;
#Override
public void start(Stage primaryStage) {
try {
root = FXMLLoader.load(getClass().getResource("Main.fxml"));
stage = primaryStage;
stage.setTitle("Stage");
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<BorderPane fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
<left>
<ToolBar orientation="VERTICAL" BorderPane.alignment="CENTER">
<items>
<Button mnemonicParsing="false" onAction="#onBtnAClick" text="A" />
<Button mnemonicParsing="false" onAction="#onBtnBClick" text="B" />
<Button mnemonicParsing="false" onAction="#onBtnCClick" text="C" />
</items>
</ToolBar>
</left>
</BorderPane>
Controller.java
import javafx.fxml.FXML;
import javafx.scene.layout.BorderPane;
public class Controller {
#FXML
BorderPane mainPane;
#FXML
public void onBtnAClick(){
ContentA contentA = new ContentA();
mainPane.setCenter(contentA);
}
#FXML
public void onBtnBClick(){
ContentB contentB = new ContentB();
mainPane.setCenter(contentB);
}
#FXML
public void onBtnCClick(){
ContentC contentC = new ContentC();
mainPane.setCenter(contentC);
}
}
And some sample of Content:
ContentA.java
public class ContentA extends AnchorPane{
public ContentA(){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ContentA.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ContentA.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<fx:root prefHeight="200.0" prefWidth="300.0" type="AnchorPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ListView layoutX="50.0" layoutY="-26.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</fx:root>
try to use this, its easy
Parent root = null;
try {
root=FXMLLoader.load(getClass().getResource("your_FXML_File.fxml"));
} catch (Exception e) {
}
borderpane.setCenter(root);

Copy entite fxml data to different container

I am having two vbox(es).
First vbox fx:id is vbox1
Second vbox fx:id is vbox2
In vbox1 I am having textbox, combobox, buttons and everything else.
I am having one button which want to copy(onclick) entire source/fxml from vbox1 to vbox2.
Is there anyway to do that?
Define the content of the VBoxes in a separate FXML file. You can include the content in the first VBox directly in your "main" fxml with a <fx:include>:
<VBox fx:id="vbox1">
<fx:include source="Content.fxml"/>
</VBox>
and then you can load another copy in the button's handler with
#FXML
public void handleButtonAction(ActionEvent e) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Content.fxml"));
vbox2.getChildren().add(loader.load());
}
Complete example (everything in a package called application):
Main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<center>
<HBox spacing="5">
<VBox fx:id="vbox1">
<fx:include source="Content.fxml"/>
</VBox>
<VBox fx:id="vbox2"/>
</HBox>
</center>
<bottom>
<Button text="Load" onAction="#load" BorderPane.alignment="CENTER"/>
</bottom>
</BorderPane>
MainController.java:
package application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.VBox;
public class MainController {
#FXML
private VBox vbox1 ;
#FXML
private VBox vbox2 ;
#FXML
private void load() throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Content.fxml"));
vbox2.getChildren().add(loader.load());
}
}
Content.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.collections.FXCollections?>
<?import java.lang.String?>
<?import javafx.scene.control.Button?>
<VBox xmlns:fx="http://javafx.com/fxml/1">
<TextField promptText="Text Field"/>
<ComboBox>
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="One"/>
<String fx:value="Two"/>
<String fx:value="Three"/>
</FXCollections>
</items>
</ComboBox>
<Button text="Click me"/>
</VBox>
Main.java:
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = (BorderPane)FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}

Resources