How to properly produce a label when a button is clicked [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
In the code below I have a project that creates 3 buttons called sinister, medium, and dexter. The buttons are properly displayed but are not functional. How do I get the button called sinister in the program to display a label saying “left” when clicked?
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.geometry.Pos;
import javafx.event.EventHandler;
import javafx.event.ActionEvent;
public class latinTranslator extends Application
{
private Label myLabel;
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(Stage primaryStage) {
Button leftButton = new Button("Sinister");
Button centerButton = new Button("Medium");
Button rightButton = new Button("Dexter");
//align centerbutton
centerButton.setAlignment(Pos.CENTER);
//event handler
leftButton.setOnAction(new ButttonClickHandler());
centerButton.setOnAction(new ButttonClickHandler());
rightButton.setOnAction(new ButttonClickHandler());
//label, button and its spacing;
VBox Vbox = new VBox(20,leftButton, centerButton,rightButton );
//create scene
Scene scenebox = new Scene(Vbox,300,500);
//alignment
Vbox.setAlignment(Pos.CENTER);
primaryStage.setScene(scenebox);
//set scene to stage
primaryStage.setTitle("Latin Translator");
//window
primaryStage.show();
}
class ButttonClickHandler implements EventHandler<ActionEvent>
{
#Override
public void handle(ActionEvent event)
{
}
}
}

First of all, you need to add myLabel to the scene graph. Then, in the event handler, you can set the text of myLabel.
In the below code, I have indicated changes I made in method start with comments. Look for the following comments:
ADDED THIS LINE
CHANGE HERE
I have also added the code for method handle in class ButttonClickHandler
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.geometry.Pos;
import javafx.event.EventHandler;
import javafx.event.ActionEvent;
public class LatinTranslator extends Application {
private Label myLabel;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
myLabel = new Label(); // ADDED THIS LINE
Button leftButton = new Button("Sinister");
Button centerButton = new Button("Medium");
Button rightButton = new Button("Dexter");
// align centerbutton
centerButton.setAlignment(Pos.CENTER);
// event handler
leftButton.setOnAction(new ButttonClickHandler());
centerButton.setOnAction(new ButttonClickHandler());
rightButton.setOnAction(new ButttonClickHandler());
// label, button and its spacing;
VBox Vbox = new VBox(20, myLabel, leftButton, centerButton, rightButton); // CHANGE HERE
// create scene
Scene scenebox = new Scene(Vbox, 300, 500);
// alignment
Vbox.setAlignment(Pos.CENTER);
primaryStage.setScene(scenebox);
// set scene to stage
primaryStage.setTitle("Latin Translator");
// window
primaryStage.show();
}
class ButttonClickHandler implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent event) {
Object source = event.getSource();
if (source instanceof Button) {
Button button = (Button) source;
String text = button.getText();
if ("Sinister".equals(text)) {
myLabel.setText("left");
}
}
}
}
}
Run the code and click on button Sinister and the word left will appear above the button.
This is how it looks before clicking button Sinister
And this is how it looks after clicking button Sinister

Related

problem when trying JavaFX EventHandler ActionEvent with JOptionPane on Mac

after run this and press {play} button java stops and not respond on Mac
so I don't know what is the problem , I tried it in another another device (macOS )and same result.
any one have an idea !
import javafx.application.Application;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;
import javax.swing.*;
public class MyFX_event_1 extends Application{
public static void main(String[] args) { Application.launch(args); }
public void start(Stage primaryStage){
// Create a pane and set its properties
HBox pane = new HBox(10);
Button btn1 = new Button("PLAY");
MyHandlerClass handler1 = new MyHandlerClass();
btn1.setOnAction(handler1);
pane.getChildren().addAll(btn1);
// Create a scene and place it in the stage
Scene scene = new Scene(pane, 100, 100);
primaryStage.setTitle("HandleEvent"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
class MyHandlerClass implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
JOptionPane.showMessageDialog(null , "game will start");}
}
}

JavaFx - Method Undefined

I have to create a program using JavaFX that creates a pane with a ball in it. There are four buttons that move the ball either left, right, up, or down. I don't understand why when I go to define each method (like .left() shown) the method call above remains an error that tells me it is undefined.
Main class:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class MoveTheBall extends Application {
#Override
public void start(Stage primaryStage) {
StackPane pane = new StackPane();
Circle circle = new Circle(20);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);
pane.getChildren().add(circle);
HBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button btLeft = new Button("Left");
Button btRight = new Button("Right");
Button btUp = new Button("Up");
Button btDown = new Button("Down");
hBox.getChildren().add(btLeft);
hBox.getChildren().add(btRight);
hBox.getChildren().add(btUp);
hBox.getChildren().add(btDown);
BorderPane borderPane = new BorderPane();
borderPane.setCenter(pane);
borderPane.setBottom(hBox);
BorderPane.setAlignment(hBox, Pos.CENTER);
Scene scene = new Scene(borderPane, 300, 200);
primaryStage.setTitle("Move The Ball");
primaryStage.setScene(scene);
primaryStage.show();
}
}
Buttons class:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class ControlBall extends Application {
private MoveTheBall moveTheBall = new MoveTheBall();
#Override
public void start(Stage primaryStage) {
HBox hBox = new HBox();
hBox.setSpacing(5);
hBox.setAlignment(Pos.CENTER);
Button btLeft = new Button("Left");
Button btRight = new Button("Right");
Button btUp = new Button("Up");
Button btDown = new Button("Down");
hBox.getChildren().add(btLeft);
hBox.getChildren().add(btRight);
hBox.getChildren().add(btUp);
hBox.getChildren().add(btDown);
btLeft.setOnAction(new LeftHandler());
btRight.setOnAction(new RightHandler());
btUp.setOnAction(new UpHandler());
btDown.setOnAction(new DownHandler());
BorderPane borderPane = new BorderPane();
borderPane.setCenter(moveTheBall);
borderPane.setBottom(hBox);
BorderPane.setAlignment(hBox, Pos.CENTER);
Scene scene = new Scene(borderPane, 200, 150);
primaryStage.setTitle("Move The Ball");
primaryStage.setScene(scene);
primaryStage.show();
}
class LeftHandler implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
moveTheBall.left(); // error because no class yet
}
}
class RightHandler implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
moveTheBall.right(); // error because no class yet
}
}
class UpHandler implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
moveTheBall.up(); // error because no class yet
}
}
class DownHandler implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
moveTheBall.down(); // error because no class yet
}
}
}
class moveTheBall extends StackPane {
private Circle ball = new Circle(20);
public moveTheBall() {
getChildren().add(ball);
ball.setStroke(Color.BLACK);
ball.setFill(Color.WHITE);
}
public void left() {
ball.setCenterX(-2.0);
ball.setCenterY(-2.0);
}
}
The line borderPane.setCenter(moveTheBall); is giving me problems as well. "The method setCenter(Node) in the type BorderPane is not applicable for the arguments (MoveTheBall)"
I'm pretty new to JavaFX, but I'm gonna do the best I can here.
I would suggest instead of doing totally separate classes for controlling the ball, moving the ball, and handling each button, look into using lambda expressions to simplify the code and reduce your room for error. For example, you can set what the btRight button does by writing a line like this:
btRight.setOnAction(e -> {
//if the ball is inside the right limit
//Move the ball to the right
});
You can write these expressions directly into your start() method, and avoid defining inner classes, as well as a separate class for the control.
As far as why you are getting an error, my best guess (as i said, I'm new to this) is that moveTheBall() is a constructor for the MoveTheBall class, but it is being called as a method.
Hope this helps.

TextField right alignment issue javafx

I have textfield that containing a value and that value should be Right alignment.
When i run the application it display the text left alignment but i set the Right alignment.
and problem with 3rd textfield.
After clicking the update button it works fine.
So may i know why it is behave different.
Code:
import java.io.File;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public class TextFieldAlignment extends Application {
TextField rText;
File file;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
rText = new TextField("updated right1 updated right2 updated right3 updated right4");
rText.setAlignment(Pos.CENTER_RIGHT);
Button btn = new Button("update");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
rText.setText("updated right1 updated right2 updated right3 updated right4");
// applyWorkaround();
}
});
final Label labelFile = new Label();
Button btn2 = new Button();
btn2.setText("Open FileChooser'");
btn2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
//Set extension filter
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("AVI files (*.exml)", "*.exml");
fileChooser.getExtensionFilters().add(extFilter);
//Show open file dialog
file = fileChooser.showOpenDialog(null);
// rText.setText(file.getPath());
}
});
VBox root = new VBox();
root.getChildren().addAll(rText, btn, btn2);
stage.setScene(new Scene(root, 200, 300));
stage.show();
}
}
Put the setalignment and settext after you add the TextField to the Scene.
Ref: Java API docs for Node
Node objects may be constructed and modified on any thread as long
they are not yet attached to a Scene. An application must attach nodes
to a Scene, and modify nodes that are already attached to a Scene, on
the JavaFX Application Thread.

Handling events from within a PopupWindow

I've made my own TimePicker that is supposed to work very much like DatePicker. I would like to know the best way to handle an event such as selecting a time and confirming it from the PopupWindow.
I could:
Make my TimePicker's popup node (a separate FXML and controller) define an interface and force the TimePicker parent to implement the methods to handle the selected date. (I'd MUCH like to avoid using interfaces in this manner. It seems like a terribly way to do things.)
Register some kind of custom EventHandler and listener to the popup window? Then, if I click OKAY after selecting a date from the PopupWindow, an event can be fired all the way up to the TimePicker.
Implement some kind of callback-like function. In android, for example, there were options for going to another screen solely to retrieve a result. I'm not sure if JavaFX has that kind of thing. The screens are quite separated from each other.
Just expose a ReadOnlyProperty representing the value. The user of your popup can then just observe the property.
Here's a proof of concept using a DatePicker:
import java.time.LocalDate;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Popup;
import javafx.stage.PopupWindow;
import javafx.stage.Stage;
public class DatePickerPopupExample extends Application {
#Override
public void start(Stage primaryStage) {
Label dateLabel = new Label(LocalDate.now().toString());
Button changeButton = new Button("Change");
HBox root = new HBox(5, dateLabel, changeButton);
root.setAlignment(Pos.CENTER);
changeButton.setOnAction(event -> {
DatePickerPopup popup = new DatePickerPopup();
popup.valueProperty().addListener((obs, oldDate, newDate) -> {
dateLabel.setText(newDate.toString());
});
Bounds buttonBds = changeButton.getBoundsInLocal();
Point2D loc = changeButton.localToScreen(buttonBds.getMaxX(), buttonBds.getMinY());
popup.showPopup(primaryStage, loc.getX(), loc.getY());
});
Scene scene = new Scene(root, 250, 150);
primaryStage.setScene(scene);
primaryStage.show();
}
public class DatePickerPopup {
private final ReadOnlyObjectWrapper<LocalDate> value = new ReadOnlyObjectWrapper<>();
private final Popup popup ;
public ReadOnlyObjectProperty<LocalDate> valueProperty() {
return value.getReadOnlyProperty();
}
public final LocalDate getValue() {
return valueProperty().get();
}
public DatePickerPopup(LocalDate date) {
value.set(date);
DatePicker picker = new DatePicker(date);
Button okButton = new Button("OK");
okButton.setOnAction(event -> {
popup.hide();
value.set(picker.getValue());
});
Button cancelButton = new Button("Cancel");
cancelButton.setOnAction(event -> {
popup.hide();
});
BorderPane root = new BorderPane();
root.setCenter(picker);
HBox buttons = new HBox(5, okButton, cancelButton);
buttons.setPadding(new Insets(5));
buttons.setAlignment(Pos.CENTER);
root.setBottom(buttons);
popup = new Popup();
popup.getContent().add(root);
}
public DatePickerPopup() {
this(LocalDate.now());
}
public void showPopup(Stage owner, double x, double y) {
popup.show(owner, x, y);
}
}
public static void main(String[] args) {
launch(args);
}
}

JavaFx :Default Message for Empty ListView

When there is no record in any table it shows a message 'No content in table', which is by default functionality of TableView in JavaFx.
So here my question is, does the same can be possible with ListView in JavaFx ? Like, if there is no item in any ListView then it will show a message same as TableView, instead of a blank/empty fields.
You have to try this:-
listView.setPlaceholder(new Label("No Content In List"));
its 100% working....
JavaFX8 has a setPlaceholder(...) method for ListView.
In earlier versions, you need to roll your own somehow. This is a bit of a hack: it wraps the ListView in a stack pane, with a white rectangle and the placeholder displayed over the top of the list view. The placeholder and rectangle have their visible property bound, so they are only visible if the list is empty.
There may be easier ways that I'm not seeing right away...
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class ListViewPlaceholderTest extends Application {
#Override
public void start(Stage primaryStage) {
final ListView<String> listView = new ListView<>();
final IntegerProperty counter = new SimpleIntegerProperty();
final Button addButton = new Button("Add item");
addButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
counter.set(counter.get()+1);
listView.getItems().add("Item "+counter.get());
}
});
final Button removeButton = new Button("Remove");
removeButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
listView.getItems().remove(listView.getSelectionModel().getSelectedIndex());
}
});
removeButton.disableProperty().bind(Bindings.equal(listView.getSelectionModel().selectedIndexProperty(), -1));
final HBox buttons = new HBox(5);
buttons.setPadding(new Insets(10));
buttons.getChildren().addAll(addButton, removeButton);
final BorderPane root = new BorderPane();
root.setCenter(createPlaceholderForListView(listView, new Label("No content in List")));
root.setBottom(buttons);
final Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private Node createPlaceholderForListView(ListView<?> listView, Node placeholder) {
final StackPane pane = new StackPane();
final Rectangle rect = new Rectangle(0, 0, Color.WHITE);
rect.widthProperty().bind(listView.widthProperty());
rect.heightProperty().bind(listView.heightProperty());
pane.getChildren().addAll(listView, rect, placeholder);
placeholder.visibleProperty().bind(Bindings.isEmpty(listView.getItems()));
rect.visibleProperty().bind(placeholder.visibleProperty());
rect.setMouseTransparent(true);
return pane ;
}
}
With fxml:
<ListView fx:id="foundContentList">
<placeholder>
<Label text="Nothing found" />
</placeholder>
</ListView>
Not entirely sure but I don't think there is a setPlaceholder method(to set the default message when no content in table) for ListView.
The workaround that I use is to create an Object in the list that indicate "No content" and show that on the listview and also disable it.
For example:
ObservableList noContent= FXCollections.observableArrayList("No content found");
ListView listView = new ListView(noContent);
listView.setDisable(true);

Categories