How to handle button action in java fx 8? - java

Here i want, if i wrote something on textarea and then click on button then the label will change as what i typed. But i can't handle the code properly.
Here is my source code---
ClickDemo.java-
package Application;
import java.io.FileInputStream;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class ClickDemo extends Application{
#Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader();
// Path to the FXML File
String fxmlDocPath = "src/View/sample1.fxml";
FileInputStream fxmlStream = new FileInputStream(fxmlDocPath);
// Create the Pane and all Details
AnchorPane root = (AnchorPane) loader.load(fxmlStream);
// Create the Scene
Scene scene = new Scene(root);
// Set the Scene to the Stage
stage.setScene(scene);
// Set the Title to the Stage
stage.setTitle("A SceneBuilder Example");
// Display the Stage
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Sample1Controller.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Controllers;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.input.MouseEvent;
/**
* FXML Controller class
*
* #author Dell
*/
public class Sample1Controller {
/**
* Initializes the controller class.
*/
#FXML
private Button btn;
#FXML
private Label label;
#FXML
private TextArea textarea;
#FXML
void btn1handle(ActionEvent event) {
// label.setText("Hello world");
textarea.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
//System.out.println(newValue);
label.setText(newValue);
}
});
}
#FXML
void textareaHandle(MouseEvent event) {
}
}
Sample1.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111" fx:controller="Controllers.Sample1Controller">
<children>
<Button fx:id="btn" layoutX="274.0" layoutY="230.0" mnemonicParsing="false" onAction="#btn1handle" text="Button" />
<Label fx:id="label" layoutX="210.0" layoutY="58.0" prefHeight="42.0" prefWidth="233.0" text="This is Text 1">
<font>
<Font size="31.0" />
</font>
</Label>
<TextArea fx:id="textarea" layoutX="101.0" layoutY="121.0" onDragDetected="#textareaHandle" prefHeight="79.0" prefWidth="399.0" />
</children>
</AnchorPane>

The issue is that you have the wrong implementation of the method called btn1handle. You are adding the new listener to the textarea instead of setting textarea's text into the label. The implementation of the method btn1handle could be very simple:
#FXML
void btn1handle(ActionEvent event) {
label.setText(textarea.getText());
}

Related

Why does FXMLLoader not initialize fields when a field is declared as a super-type

When I declare a field player as shown below:
class Controller{
#FXML Shape player;
}
.fxml file - <Rectangle fx:id="player" ...\>
Where in the Controller, player is declared as a super type (Shape), and in the fxml file
it is declared as a subtype.
I declare player as Shape, instead of Rectangle, because I have multiple similar fxml files, and the program decides, during runtime, which one to load. Every fxml file has a player object of some child class of Shape
My problem is that when a field is declared as the super type, fxml loader doesn't initialize that field. I would like to know a work-around to this problem.
A minimum reproducible example:
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
public class test2 extends Application {
#FXML Shape player;
public void start(Stage stage) throws Exception
{
Scene scene = new Scene(
FXMLLoader.load(getClass().getResource("t.fxml"))
);
stage.setTitle("JavaFX Example");
stage.setScene(scene);
stage.show();
System.out.println(player); //prints null
}
public static void main (String [] args){
launch(args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.shape.Rectangle?>
<Pane xmlns:fx="http://javafx.com/fxml" prefHeight="400.0" prefWidth="600.0">
<Rectangle fx:id="player" x="20" y="20" width="40" height="40"/>
</Pane>
#FXML-annotated fields are initialized in the controller. Typically to create controllers, you specify a fx:controller attribute in the root element of the FXML (though there are other ways to do this). Your test2 class [sic] is not the controller class (and even if it were, the instance on which start() is invoked would not be the controller).
The following modification of your code demonstrates that fields declared as a superclass type are indeed initialized as you would expect:
Controller.java:
package org.jamesd.examples.supertype;
import javafx.fxml.FXML;
import javafx.scene.shape.Shape;
public class Controller{
#FXML Shape player;
public void initialize() {
System.out.println(player);
}
}
t.fxml (note fx:controller attribute):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.shape.Rectangle?>
<Pane xmlns:fx="http://javafx.com/fxml" prefHeight="400.0"
prefWidth="600.0"
fx:controller="org.jamesd.examples.supertype.Controller">
<Rectangle fx:id="player" x="20" y="20" width="40" height="40" />
</Pane>
Test2.java:
package org.jamesd.examples.supertype;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
public class Test2 extends Application {
#FXML Shape player;
public void start(Stage stage) throws Exception
{
Scene scene = new Scene(
FXMLLoader.load(getClass().getResource("t.fxml"))
);
stage.setTitle("JavaFX Example");
stage.setScene(scene);
stage.show();
}
public static void main (String [] args){
launch(args);
}
}
This generates the expected output:
Rectangle[id=player, x=20.0, y=20.0, width=40.0, height=40.0, fill=0x000000ff]

how to combine fxml file with 3d Box and PerspectiveCamera

As a newbie I'm trying to do some my own projects to practice Java, JavaFX and Raspberry coding. Ma latest goal which I set for myself is 3D visualization of force from tensometric beam. I managed to achieve simple chart and and simple visualization of actual pressure force (in circle).
(https://imagizer.imageshack.com/img922/2663/spBwMs.gif)
Now I'd like to represent it as 3D bar.
I tried to understood some examples from Ensemble: jnlps://download.oracle.com/otndocs/products/javafx/8/samples/Ensemble/Ensemble.jnlp
and I managed to do something like that:
(https://imagizer.imageshack.com/img921/2766/12te0a.gif)
but I'd like to achieve something similar using FXML file.
I tried to code it but no effect so far. I'd like you use some Hbox to place 2 boxes next to each other, but then I don't know where to place Camera properly. Actually 3D with javaFX is a little bit of black magic for me ;)
Main.java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root,800,800, true, SceneAntialiasing.BALANCED));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java:
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.fxml.FXML;
import javafx.scene.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.util.Duration;
public class Controller{
#FXML
private AnchorPane pane;
#FXML
private Box box;
#FXML
private PerspectiveCamera camera;
final Rotate rx = new Rotate(0, Rotate.X_AXIS);
final Rotate ry = new Rotate(0, Rotate.Y_AXIS);
final Rotate rz = new Rotate(0, Rotate.Z_AXIS);
private Timeline animation;
#FXML
void initialize() {
box.setMaterial(new PhongMaterial(Color.ORANGE));
/* box.setDepth(100);
box.setWidth(100);
box.setHeight(100);*/
rx.setAngle(90);
ry.setAngle(25);
box.getTransforms().addAll(rz, ry, rx);
animation = new Timeline();
animation.getKeyFrames().addAll(
new KeyFrame(Duration.ZERO,
new KeyValue(box.depthProperty(), 0d),
new KeyValue(box.translateYProperty(),400d)),
new KeyFrame(Duration.seconds(5),
new KeyValue(box.depthProperty(), 800d),
new KeyValue(box.translateYProperty(), 0d)));
animation.setCycleCount(Timeline.INDEFINITE);
camera.getTransforms().addAll (
new Rotate(-35, Rotate.X_AXIS),
new Translate(0, 0, 10)
);
box.sceneProperty().addListener(new InvalidationListener() {
#Override
public void invalidated(Observable observable) {
box.getScene().setCamera(camera);
box.sceneProperty().removeListener(this);
}
});
animation.play();
}
}
main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.PerspectiveCamera?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Box?>
<AnchorPane fx:id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="check.brakes.Controller">
<children>
<Box fx:id="box" depth="100.0" height="100.0" layoutX="380.0" layoutY="673.0" width="100.0">
</Box>
<PerspectiveCamera fx:id="camera" farClip="70.0" fieldOfView="35.0" nearClip="0.5" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
I expect the bars should look like from the example I provided.
Update
I did it, I'm sure it's not perfect at all, but somehow I have to start.
BTW.
Why is that, when i resize application window, camera angle is changing ?

Can't find Method in handler [duplicate]

This question already has an answer here:
Java FX fxml on Action
(1 answer)
Closed 4 years ago.
I am trying to create a basic UI with JavaFX. The problem is only that my Handlers can't be found in my controller.
my ui.fxml:
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane id="pane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="reldb0.controller.PersonOverviewController">
<children>
<Button text="Hinzufügen" onAction="#handleAddClicked" fx:id="addButton" />
<Button text="Entfernen" onAction="#handleDeleteClicked" fx:id="deleteButton" />
<TableView fx:id="table">
<columns>
<TableColumn fx:id="vorname" prefWidth="100" text="Vorname" />
<TableColumn fx:id="nachname" prefWidth="100" text="Nachname" />
</columns>
</TableView>
</children>
</StackPane>
My Controller class:
package reldb0.controller;
import java.awt.event.ActionEvent;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import reldb0.entity.Person;
import reldb0.MockData;
/**
*
* #author hnsdi
*/
public class PersonOverviewController implements Initializable{
#FXML
private TableView<Person> table;
#FXML
private TableColumn<Person, String> vorname;
#FXML
private TableColumn<Person, String> nachname;
#Override
public void initialize(URL location, ResourceBundle resources) {
vorname.setCellValueFactory(new PropertyValueFactory<Person, String>("vorname"));
nachname.setCellValueFactory(new PropertyValueFactory<Person, String>("nachname"));
table.getItems().setAll(MockData.persons());
}
#FXML
private void handleAddClicked(ActionEvent event) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 300);
Stage addWindow = new Stage();
addWindow.setTitle("Person hinzufügen");
addWindow.setScene(scene);
addWindow.show();
}
#FXML
private void handleDeleteClicked(ActionEvent event) {
//TODO
}
}
I can't find the issue why my EventHandlers can't be found. I have the #FXML Annotations and the controller is registered correctly because the Table is filled with the data.
import java.awt.event.ActionEvent; // which is wrong
Import javafx.event.ActionEvent instead of java.awt.event.ActionEvent in your PersonOverviewController class

Changing sceenes with IntelliJ 2018.1 and Scene Builder 9.0.1

I have created a new JavaFx project.
In the project I have a Main class, a Controller class and a design file.
When I click on "New products" I want to load a new fxml file named new_product.fxml.
However I get a error when I click the "New product" button:
Caused by: java.lang.NullPointerException
at sample.Main.changeScene(Main.java:33)
at sample.Controller.buttonNewProductOnMouseClicked(Controller.java:21)
In Main.java line 33 is the primaryStage. Looks like my controller can't access it?
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
Stage primaryStage;
#Override
public void start(Stage primaryStage) throws Exception{
this.primaryStage = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Scene primaryScene = new Scene(root, 300, 275);
primaryStage.setScene(primaryScene);
primaryStage.show();
}
public void changeScene(String fxml){
Parent pane = null;
try {
pane = FXMLLoader.load(getClass().getResource(fxml));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene( pane );
primaryStage.setScene(scene);
}
public static void main(String[] args) {
launch(args);
}
}
My design file
<?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.BorderPane?>
<?import javafx.scene.layout.HBox?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<top>
<HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="buttonProducts" mnemonicParsing="false" onMouseClicked="#buttonProductsOnMouseClicked" text="Products" />
<Button fx:id="buttonNewProduct" mnemonicParsing="false" onMouseClicked="#buttonNewProductOnMouseClicked" text="New products">
<HBox.margin>
<Insets left="5.0" />
</HBox.margin></Button>
</children>
</HBox>
</top>
<center>
<Label text="Label" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
The Controller class for the design file
package sample;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
public class Controller {
#FXML
private Button buttonProducts;
#FXML
private Button buttonNewProduct;
public void buttonProductsOnMouseClicked(javafx.scene.input.MouseEvent mouseEvent) {
buttonProducts.setText("You have clicked on me!");
}
public void buttonNewProductOnMouseClicked(javafx.scene.input.MouseEvent mouseEvent) {
buttonNewProduct.setText("You have clicked on me!");
Main mainclass = new Main();
mainclass.changeScene("new_product/new_product.fxml");
}
}

How to maintain full screen when changing scenes javafx

I have seen a similar question being asked, however my problem is that I want the stage to maintain full screen mode during the entirety of the scene change ie not simply adding stage.setFullScreen(true) at the end of it, which causes a momentary but very noticeable exit from full screen. Hiding the stage before changing scenes doesn't really help either, as there is a noticeable disappearance . Here's my code:
Main:
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root));
primaryStage.setFullScreen(true);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller:
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.layout.AnchorPane;
import javafx.stage.Stage;
public class Controller {
#FXML
private AnchorPane pane;
#FXML
void doSomething(ActionEvent event) throws Exception {
Stage stage = (Stage) pane.getScene().getWindow();
Parent parent = FXMLLoader.load(getClass().getResource("sample2.fxml"));
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.setFullScreen(true);
stage.show();
}
}
Sample:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-
Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.Controller">
<children>
<Button layoutX="180.0" layoutY="188.0" mnemonicParsing="false"
onAction="#doSomething" prefHeight="25.0" prefWidth="241.0" text="Do Something"
/>
</children>
</AnchorPane>
Sample2
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-
Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: blue;"
xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.Controller">
<children>
<Button layoutX="180.0" layoutY="188.0" mnemonicParsing="false"
onAction="#doSomething" prefHeight="25.0" prefWidth="241.0" text="Do Something"
/>
</children>
</AnchorPane>
As you can see, if you run the code and press the button, there is a momentary exit from full screen. Is there any way to fix this, other than using the same fxml file?
Thanks a lot.
I didn't clearly understood what you are saying. I think you need a stage of size equals to Computer screen resolution and switch between the two screens. If yes then the following files will help you do so. If you want to come back to first scene from second scene then keep another button to load the first scene or keep a static variable and switch between the scenes by incrementing the variable and show the scene based on odd or even. Like for odd value of the variable show first scene and for even values show second scene.
Other process is getting the children of the stage. This gives you a ObservableList. Now clear the list and then add the respective scene to the list and show the stage.
Main class:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Screen;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
Scene scene = new Scene(root, 500, 200);
primaryStage.setScene(scene);
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
//set Stage boundaries to visible bounds of the main screen
primaryStage.setX(primaryScreenBounds.getMinX());
primaryStage.setY(primaryScreenBounds.getMinY());
primaryStage.setWidth(primaryScreenBounds.getWidth());
primaryStage.setHeight(primaryScreenBounds.getHeight());
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller Class:
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
public class Controller {
#FXML
private AnchorPane pane;
#FXML
void doSomething(ActionEvent event) throws Exception {
Stage stage = (Stage) pane.getScene().getWindow();
Parent parent = FXMLLoader.load(getClass().getResource("sample2.fxml"));
Scene scene = new Scene(parent, 500, 200);
stage.setScene(scene);
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
//set Stage boundaries to visible bounds of the main screen
stage.setX(primaryScreenBounds.getMinX());
stage.setY(primaryScreenBounds.getMinY());
stage.setWidth(primaryScreenBounds.getWidth());
stage.setHeight(primaryScreenBounds.getHeight());
stage.show();
}
}

Categories