Access to Javafx elements from another class without FXML - java

I am using Javafx8 and lets say i have created many ui items (like buttons and so on...). I thought its a good idea to put all EventHandler for these buttons into a separates class. My question is: How can i get access from an EventHandler to any button, e.g. to diable it or to manipulate it on any other way.
Here is a minimum example with two buttons and a separate class for EventHandlers
Let's say this is my Start class:
public class App extends Application
{
#Override
public void start(Stage primaryStage) throws Exception {
Button b1 = new Button();
b1.setOnAction(ListenerClass.createB1Event());
Button b2 = new Button();
b2.setOnAction(ListenerClass.createB2Event());
VBox vbox = new VBox(b1, b2);
Scene scene = new Scene(vbox, 200, 200);
primaryStage.setTitle("App");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main( String[] args )
{
Application.launch(args);
}
}
And my (separate) listener class:
public class ListenerClass {
public static EventHandler<ActionEvent> createB1Event() {
return new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
//Access here to b1 and b2...
//Deactivate B1
//Activate B2
}
};
}
public static EventHandler<ActionEvent> createB2Event() {
return new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
//Access here to b1 and b2...
//Activate B1
//Dectivate B2
}
};
}
}
Thanks

So based on your principal. You want the button that is located in a vbox and got pressed to be disabled and all other buttons from that vbox to be enabled.
And your problem is how to find button that got pressed.
You need to use ActionEvent.getSource() method.
Heres how I'd code it....
This is Start class:
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
VBox vbox = new VBox();
Button b1 = addNewButton("Button1",vbox);
Button b2 = addNewButton("Button2",vbox);
Button b3 = addNewButton("Button3",vbox);
Scene scene = new Scene(vbox, 200, 200);
primaryStage.setTitle("App");
primaryStage.setScene(scene);
primaryStage.show();
}
public static Button addNewButton(String label, VBox ownerVBox){
Button button = new Button(label);
ownerVBox.getChildren().add(button);
button.setOnAction(ListenerClass.createBEvent());
return button;
}
public static void main(String[] args) {
launch(args);
}
}
Listener class:
public class ListenerClass {
public static EventHandler<ActionEvent> createBEvent() {
return new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
Button b = (Button) t.getSource();
VBox vbox =(VBox) b.getParent();
vbox.getChildren().forEach(button-> {
button.setDisable(false);
});
b.setDisable(true);
}
};
}
}

Related

How do I call back to the main node so I can switch to a different scene in javafx

so I am trying to switch to a different scene in javafx. I am working on a project where the user will select on a food category via a combobox, which will switch to a new scene that has all the recipes under that specific category.
The problem is I am able to load my MainMenuScene, but I am not sure how to switch to a different scene, which I think is because of how I have structured my code.
My code is structured where I can GUIAPP (which starts the entire GUI)
private static View myView;
private static Recipe myRecipe;
public GUIApp() {
myView = new View();
myRecipe = new Recipe();
}
public static View getView() {
return myView;
}
public static Recipe getRecipe() {
return myRecipe;
}
#Override
public void start(Stage primaryStage) throws Exception {
System.out.println("Starting app...");
myView.setStage(primaryStage);
}
public static void main(String [] args) {
myRecipe = new Recipe();
launch(args);
}
}
Then View, which sets the primary Stage (which is MainMenuScene)
private Stage myStage;
private Scene myMainMenuScene;
private Scene myMealScene;
public View() {
myMainMenuScene = new MainMenuScene(new BorderPane());
}
public Stage getStage() {
return myStage;
}
public Scene getMealScene() {
return myMealScene;
}
public void setStage(Stage primaryStage) {
myStage = primaryStage;
myStage.setScene(myMainMenuScene);
myStage.setTitle("Recipe Database");
myStage.setWidth(600);
myStage.setHeight(400);
Scene scene = myMainMenuScene;
myStage.setScene(scene);
myStage.show();
}
}
Here is MainMenuScene, where it calls the recipe code I had previously made
private BorderPane myRoot;
private String f, t;
Label label = new Label();
public MainMenuScene(Parent root) {
super(root);
myRoot = (BorderPane) root;
BorderPane titleBox = new BorderPane();
titleBox.setStyle("-fx-font: 24 arial;");
myRoot.setTop(titleBox);
Text title = new Text("Recipe Database Tool");
title.setFont(new Font(50));
titleBox.setCenter(title);
//VBox and HBox creation
VBox leftBox = new VBox();
VBox rightBox = new VBox();
VBox centerBox = new VBox();
//Button search = new Button("Recipe Categories");
Button create = new Button("Create/Upload a New Recipe");
//Creates a combobox that gets the category name from Recipe
ComboBox<String> search = new ComboBox<String>();
search.getItems().addAll(GUIApp.getRecipe().getCategory());
search.setOnAction((e) -> {
search.getSelectionModel().selectFirst();
});
/*
****//Create a button that switches to MealScene when a category is selected
Button select = new Button("Select");
select.setOnAction((e) -> {
View.getStage().setScene(View.getMealScene());****
});
*/
//myRoot for each Box
myRoot.setLeft(leftBox);
myRoot.setRight(rightBox);
myRoot.setCenter(centerBox);
//adding the search categories button to the left box
leftBox.setAlignment(Pos.CENTER);
leftBox.setSpacing(30);
leftBox.getChildren().add(search);
//adding the create a new recipe to the right box
rightBox.setAlignment(Pos.CENTER);
rightBox.setSpacing(30);
rightBox.getChildren().add(create);
}
}
I tried calling the button by using View, but I am getting an error that I am not sure how to fix.
Here's the error: It's asking for View.getStage() to make getStage a static method in View, which I don't want to do and View.getMealScene to also become static
Please let me know! I would love to learn how to prevent this in the future

how to change real time node information in javafx?

I'm trying to change the value of a string that is in another method with an event in a button, but when clicking nothing happens.
public class Test extends Application{
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Objeto1 root = new Objeto1();
Scene scene = new Scene(root.first());
stage.setScene(scene);
stage.show();
}
}
Objeto1
public class Objeto1 {
String tmp ="hola";
public Objeto1() {
}
public VBox first(){
VBox root = new VBox();
setTmp("hola");
HBox button = new HBox();
Button btn = new Button("cliclk");
btn.setOnAction(e->{
setTmp("");
});
button.getChildren().add(btn);
HBox a = form();
root.getChildren().addAll(button,a);
return root;
}
public HBox form(){
HBox root = new HBox();
Label lab = new Label(getTmp());
root.getChildren().add(lab);
return root;
}
public String getTmp() {
return tmp;
}
public void setTmp(String tmp) {
this.tmp = tmp;
}
}
I would like to click on the content of the string change and show in the label the change

JavaFX how to handle ActionEvent from controller class?

Hello i have problem with handling action from my button: here's my code:
public class HelloWorld extends Application {
Button btn;
#Override
public void start(Stage primaryStage) {
btn = new Button();
btn.setText("Say 'Hello World'");
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public void setButtonOnAction(EventHandler<ActionEvent> acn)
{
btn.setOnAction(acn);
}
}
my controller class
public class Controller {
private HelloWorld helloWorld;
private Model model;
public Controller(HelloWorld helloWorld, Model model) throws Exception {
this.helloWorld = helloWorld;
this.model = model;
System.out.println(this.mainView.returnOne());
this.helloWorld.setButtonOnAction(e->
{
System.out.println("CATCH");
});
}
}
main runClass:
public class runExample {
public static void main(String[] args) throws Exception {
HelloWorld helloWorld = new HelloWorld();
Model model = new Model();
Application.launch(helloWorld.getClass(),args);
Controller controller = new Controller(helloWorld, model);
}
}
`
Does anyone know why setButtonOnAction don't work in controller class but in HelloWorld class it work perfectly ? Compiler don't give me any error. Only if i switch in run class like that:
Controller controller = new Controller(mainView, model);
Application.launch(mainView.getClass(),args);
it gives me
Exception in thread "main" java.lang.NullPointerException
and if i'm using setButtonOnAction in HelloWorld class it works fine. Can u help me catch event in my controller class ? I'm using jdk8 but on 11 it isn't work too.
Working example ;)
public class HelloWorld extends Application {
Button btn;
#Override
public void start(Stage primaryStage) {
btn = new Button();
btn.setText("Say 'Hello World'");
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
Controller controller = new Controller(this,new Model()));
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public void setButtonOnAction(EventHandler<ActionEvent> acn)
{
btn.setOnAction(acn);
}
}
And run class:
public class runExample {
public static void main(String[] args) throws Exception {
Application.launch(HelloWorld.class,args);
}
}

Adding text to a label from another class. Java

In my program, there are two Form and Checked classes.
In the Form class, there is a Label and a Button. At the click in the Button I create an instance of the class Checked and start its thread.
Now, what I'm having trouble with is that I need to pass the text from the Checked class and change the Label value, but I have not succeeded.
Here is my code:
public class MainForm extends Application {
protected static int intVerifiedNews = 0;
Button btnPlay = new Button("Button");
Label lbVerifiedNews = new Label("News: ");
#Override
public void start(Stage primaryStage) throws IOException {
final BorderPane border = new BorderPane();
final HBox hbox = addHBox();
Scene scene = new Scene(border, 850, 500, Color.BLACK);
btnPlay.setPrefSize(100, 24);
btnPlay.setMinSize(24, 24);
btnPlay.setOnAction((event) -> {
Checked ch = new Checked();
ch.start();
}
);
border.setTop(hbox);
hbox.getChildren().addAll(btnPlay, lbVerifiedNews);
primaryStage.setScene(scene);
primaryStage.show();
}
private HBox addHBox() {
HBox hbox = new HBox();
hbox.setPadding(new Insets(5, 0, 5, 5));
return hbox;
}
public static void main(String[] args) throws IOException {
launch(args);
}
}
Checked class:
public class Checked extends Thread {
public void run() {
for (int i = 0; i <= 5; i++) {
MainForm.intVerifiedNews ++;
//Here you need to pass the intVerifiedNews value to the Label
System.out.println(MainForm.intVerifiedNews);
}
}
}
Pass lbVerifiedNews into the constructor of the Checked class and store this reference in a field.
Checked ch = new Checked(lbVerifiedNews);
public class Checked extends Thread {
Label checkedLabelReference;
public Checked(Label label){
this.checkedLabelReference = label;
}
public void run() {
for (int i = 0; i <= 5; i++) {
MainForm.intVerifiedNews ++;
//Here you need to pass the intVerifiedNews value to the Label
Platform.runLater(new Runnable() {
#Override public void run() {
checkedLabelReference.setText(MainForm.intVerifiedNews);//update text
}});
System.out.println(MainForm.intVerifiedNews);
}
}
}
Generically you'll want to pass reference to the MainForm or form object that you want to update into your Checked class so that you have access to its update methods directly.
public class Checked implements Runnable {
public Checked(MainForm form1) {
// store form (or the object representing the text box directly) to update later
}
public void run() {
}
}

JavaFx Program throws java.lang.reflect.InvocationTargetException

This is my first question here so donĀ“t be to mad at me if something is wrong. I am currently programming an idle like game for java with help of JavaFx.
The code here under was written with eclipse mars and JavaFx. Eclipse shows to me that the code is right but when I want to start the program it throws this block of error messages:
public class Main extends Application{
private static final Color color = Color.web("#464646");
Button button3 = new Button("D");
DropShadow shadow = new DropShadow();
Label label = new Label();
public static void main(String[] args) throws Exception {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception{
Scene scene = new Scene(new Group());
primaryStage.setTitle("Button Sample");
primaryStage.setWidth(300);
primaryStage.setHeight(190);
label.setFont(Font.font("Times New Roman", 22));
label.setTextFill(color);
Image imageDecline = new Image(getClass().getResourceAsStream("../not.png"));
Image imageAccept = new Image(getClass().getResourceAsStream("../ok.png"));
VBox vbox = new VBox();
vbox.setLayoutX(20);
vbox.setLayoutY(20);
HBox hbox1 = new HBox();
HBox hbox2 = new HBox();
Button button1 = new Button("Accept");
button1.setStyle("-fx-font: 22 arial; -fx-base: #b6e7c9;");
button1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
label.setText("Accepted");
}
});
Button button2 = new Button("Accept");
button2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
label.setText("Accepted");
}
});
button3.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
label.setText("Declined");
}
});
button3.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
button3.setEffect(shadow);
}
});
button3.addEventHandler(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
button3.setEffect(null);
}
});
hbox1.getChildren().add(button2);
hbox1.getChildren().add(button3);
hbox1.getChildren().add(label);
hbox1.setSpacing(10);
hbox1.setAlignment(Pos.BOTTOM_CENTER);
Button button4 = new Button();
button4.setGraphic(new ImageView(imageAccept));
button4.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
label.setText("Accepted");
}
});
Button button5 = new Button();
button5.setGraphic(new ImageView(imageDecline));
button5.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
label.setText("Declined");
}
});
hbox2.getChildren().add(button4);
hbox2.getChildren().add(button5);
hbox2.setSpacing(25);
vbox.getChildren().add(button1);
vbox.getChildren().add(hbox1);
vbox.getChildren().add(hbox2);
vbox.setSpacing(10);
((Group) scene.getRoot()).getChildren().add(vbox);
primaryStage.setScene(scene);
primaryStage.show();
}}
I hope anyone here has a hint or a solution for this problem :) Would be very nice from you.
Best Greetings,
Mike
I think your problem has to do with the input streams you use for creating your Image objects:
... = new Image(getClass().getResourceAsStream("../not.png"));
When I start your application in Eclipse, I get an InvocationTargetException as well. It is caused by a NullPointerException because the PNG files cannot be found.
Try to start your application without creating the Image objects and see if you still get any exceptions.

Categories