I need to print user input in my console (Javafx NetBeans).
This is my code, and strangely is only printing the label name: "Address". Earlier when I only had 2 fields it would only print the last entry, and it would not print the first entry by user when button pressed.
How can I print all the input from user in console?
package customerentry2;
import javafx.geometry.Insets;
import javafx.application.Application;
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.Stage;
/**
*
* #author 718358
*/
public class CustomerEntry2 extends Application {
Stage window;
Scene scene;
Button button;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception
{
window = primaryStage;
window.setTitle("Customer Entry");
Label nameLabel = new Label("First Name: ");
Label nameLabel2 = new Label("Last Name: ");
Label addressInput = new Label("Address: ");
TextField nameInput = new TextField();
TextField nameInput2 = new TextField();
TextField addressInput3 = new TextField();
button = new Button("Save");
button.setOnAction(e -> System.out.println(nameInput.getText()));
button.setOnAction(e -> System.out.println(nameInput2.getText()));
button.setOnAction(e -> System.out.println(addressInput3.getText()));
//Layout
VBox layout = new VBox(10);
layout.setPadding(new Insets(20, 20, 20, 20));
layout.getChildren().addAll(nameLabel, nameInput, nameLabel2, nameInput2, addressInput, addressInput3, button);
scene = new Scene(layout, 300, 250);
window.setScene(scene);
window.show();
}
/**
* #param args the command line arguments
*/
}
The problem is happening because each time you call setOnAction it replaces the existing EventHandler, rather than adding an additional one. There's two ways you can fix this.
You can either take care of all three printlns in one EventHandler, like this:
button.setOnAction(e -> {System.out.println(nameInput.getText());
System.out.println(nameInput2.getText()));
System.out.println(addressInput3.getText());
});
Or you can use addEventHandler to add more EventHandlers to the button without replacing the existing ones. That would look like this:
button.addEventHandler(ActionEvent.ACTION,
(ActionEvent e) -> System.out.println(nameInput.getText()));
button.addEventHandler(ActionEvent.ACTION,
(ActionEvent e) -> System.out.println(nameInput2.getText()));
button.addEventHandler(ActionEvent.ACTION,
(ActionEvent e) -> System.out.println(addressInput3.getText()));
Either one should work for you. The first one is a little shorter and easier to read, but the second way is more flexible if you plan to dynamically add and remove the handlers.
Related
I have been trying to display buttons and some text with javafx but it whont work it just displays over eachother in the middle of the screen:
I have been trying to use vbox and ive also tried to use hbox but both dont change how it looks when i run it
(when i run it i get no erors)
(also im using vs code if that has anything to say)
Here is my code so far:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class App extends Application {
#Override
public void start(Stage primaryStage) {
// buttons
VBox vboxBtn = new VBox();
vboxBtn.setPadding(new Insets(10, 10, 10, 10));
vboxBtn.setSpacing(10);
Button btnRoom = new Button("changeRoom");
Button btnMap = new Button("changeMap");
vboxBtn.getChildren().addAll(btnRoom, btnMap);
// text
VBox vboxTxt = new VBox();
vboxTxt.setPadding(new Insets(10, 10, 10, 10));
vboxTxt.setSpacing(10);
Text txtRoom = new Text("Room");
Text txtMap = new Text("Map");
vboxTxt.getChildren().addAll(btnRoom, btnMap);
String currentRoom = "None";
String currentMap = "None";
// button for switching maps
btnMap.setText("Change the map");
// button click
btnMap.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
System.out.println("Hello world");
}
});
// text for maps
txtMap.setText("Map: " + currentMap);
// button for switching rooms
btnRoom.setText("Hello world");
// button click
btnRoom.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello world");
}
});
// text
txtRoom.setText("Room: " + currentRoom);
StackPane root = new StackPane();
root.getChildren().add(btnRoom);
root.getChildren().add(btnMap);
root.getChildren().add(txtRoom);
root.getChildren().add(txtMap);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I think the problem is you are adding butons and txts to the pane instead of Vboxes and Hboxes.
I believe you want them on a 4x4 grid, to do that you need to add your virtual boxes to a hbox then add that hbox to a pane, or u could use a grid.
Or you could set their locations, I dont know if this is possible with code, but you can do that in screenbuilder.
PS: check out screenbuilder for javafx.
I'm working on a text box that will give information about a subject in it, but I want 1 long string to have all of the information stored in it. I would like for this string to be returned to the "next line" in that box, I'm essentially trying to create a text box in JavaFX
So I did some more digging, and it turns out, the thing I'm looking for is called a "Text Area"
package com.jenkov.javafx.controls;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TextAreaExperiments extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("TextArea Experiment 1");
TextArea textArea = new TextArea();
VBox vbox = new VBox(textArea);
Scene scene = new Scene(vbox, 200, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
source received from: http://tutorials.jenkov.com/javafx/textarea.html
If you're basically looking to create a TextField try following:
Label label1 = new Label("Name:");
TextField textField = new TextField ();
HBox hb = new HBox();
hb.getChildren().addAll(label1, textField);
hb.setSpacing(10);
My question is, how I can easily wait on the result of a window in witch the user is entering some informations?
Basic Problem:
public static char[] getPassword(String message) {
run = true;
showWindow(message); // JFrame or FX-Window
/* DOES NOT WAIT HERE !!! */
// Working on the insert data of "password1"
if (pwMatches()) {
return password1;
} else {
return null;
}
}
https://pastebin.com/06itDs1X - only pseudo code, untested! Real code is to complex.
The task:
FX-Window is running (main stage)
User should enter a new password in a stage (pw stage)
after entering the password, the main stage should go on
The Problem:
main stage does not wait, goes on before password is entered
simple demo code: https://pastebin.com/560v1wmd
results
main 1
main 2
s1
s2
The solutions:
1: https:// pastebin.com/kCAep2gr
2: https:// pastebin.com/MSJ0kHfU
results the correct order
main 1
s1
s2
main 2
Problem:
Solution 1 needs much modifications in the code.
I used this, but would ask for a better solution or is this the best?
Solution 2 does not work for JavaFX (Thread is no FX-Thread)
Question:
Any easy solution for JavaFX or is Solution 1 the best?
This sample app halts interactions on the Main Stage until a password is entered. The password is password. Note: passwordStage.initModality(Modality.APPLICATION_MODAL);//This is important if you don't want the user to interact with other windows
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
/**
*
* #author blj0011
*/
public class JavaFXApplication22 extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Stage passwordStage = getPasswordStage();
passwordStage.initModality(Modality.APPLICATION_MODAL);//This is important if you don't want the user to interact with other windows
passwordStage.initOwner(primaryStage);
passwordStage.showAndWait();
}
});
BorderPane root = new BorderPane();
root.setCenter(new StackPane(new Label("Main Center")));
root.setTop(new StackPane(new Label("Main Screen")));
root.setRight(new StackPane(new Label("Main Right")));
root.setLeft(new StackPane(new Label("Main Left")));
root.setBottom(new StackPane(btn));
Scene scene = new Scene(root, 500, 400);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public Stage getPasswordStage()
{
Stage stage = new Stage();
TextField textField = new TextField();
textField.setPromptText("Enter password here");
Button button = new Button("login");
button.setOnAction(e -> {
if(textField.getText().equals("password"))
{
stage.close();
}
});
VBox vbox = new VBox(new StackPane(textField), new StackPane(button));
StackPane stackPane = new StackPane(vbox);
Scene scene = new Scene(stackPane,300, 200);
stage.setTitle("Login Screen");
stage.initStyle(StageStyle.UNDECORATED);
stage.setScene(scene);
return stage;
}
}
As stated in the title, I have fxml files, I have a UI that is set up with three labels/buttons up top and the lower half of the window has a pane. Every time a label/button is clicked, the pane must switch to that corresponding fxml file. So in other words, the pane must always be in the same position, kind of like a tabbed layout but without tabs.
I know I can achieve this with just loading a new instance of an fxml file but, I want to avoid that because when a user click on a tab he previously was on, he should be able to see his earlier input.
I have some main.java that starts the program. Some controller.java that controls the UI when it is first loaded, and some fxml file corresponding to that initial view. How can I go about implementing this transition functionality? P.S. I am very novice at JavaFX.
Here is a MCVE of how you can achieve it.
It can of course be implemented using FXML :
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class StageTest extends Application{
private Pane pane1, pane2, mainPane;
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Switch Panes");
Button button1 = new Button("Show Pane 1");
button1.setOnAction(e -> showPane1());
Button button2 = new Button("Show Pane 2");
button2.setOnAction(e -> showPane2());
HBox buttonsPane = new HBox(5.);
buttonsPane.getChildren().addAll(button1, button2);
pane1 = getPane("PANE ONE");
pane2 = getPane("PANE TWO");
mainPane = new StackPane(pane1);
BorderPane root = new BorderPane();
root.setTop(buttonsPane);
root.setCenter(mainPane);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
private void showPane1() {
mainPane.getChildren().clear();
mainPane.getChildren().add(pane1);
}
private void showPane2() {
mainPane.getChildren().clear();
mainPane.getChildren().add(pane2);
}
private Pane getPane(String txt) {
VBox pane = new VBox();
pane.getChildren().addAll(new TextArea(txt+" add text here: "));
return pane;
}
public static void main(String[] args) {
launch(args);
}
}
I have a TextField in my program that will have data entered by the user, but I also have a variable value somewhere else that I need to permanently display at the end of my TextField. It cannot disappear when the user enters any data in the TextField. Can anyone give me a good implementation? Thanks.
[UserInput (miles)]
**Above is an example of what I am talking about. "Miles" needs to always be in the TextField while the UserInput is changing.
EDIT: "Implementation" was a bad choice of words. Let me rephrase, I can set up the field myself, but I am having trouble finding a way to set permanent text in a textfield. Just wondering if anyone knows an easy way.
You could put a transparent textfield over a label and bind the 2 together. Something like this but with better styling.
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Text extends Application {
#Override
public void start(Stage primaryStage) {
TextField txtUser = new TextField();
txtUser.setStyle("-fx-background-color: transparent;-fx-border-color:blue;");
Label txtBG = new Label(" (miles)");
Label labelUser = new Label();
labelUser.textProperty().bind(txtUser.textProperty());
Label labelAll = new Label();
labelAll.textProperty().bind(Bindings.concat(
labelUser.textProperty())
.concat(txtBG.textProperty()));
StackPane sp = new StackPane();
sp.getChildren().addAll(txtBG, txtUser);
sp.setPrefSize(100, 12);
VBox root = new VBox();
root.getChildren().addAll(sp,labelUser,labelAll);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("transparent text test");
primaryStage.setScene(scene);
primaryStage.show();
}
}
I would use a HBox instead of a stack pane but it's one way to satisfy the requirement that "miles" is 'inside' the texfield's borders.
This is a small example doing what you want ! I have used the focus property of textfield to add and remove miles from it !
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TextBinding extends Application {
#Override
public void start(Stage primaryStage) {
final TextField user = new TextField();
TextField demo = new TextField();
user.setStyle("-fx-background-color: transparent;-fx-border-color:blue;");
user.focusedProperty().addListener(new ChangeListener<Boolean>()
{
#Override
public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldPropertyValue, Boolean newPropertyValue)
{
if (newPropertyValue)
{
user.setText(user.getText().replace(" miles", ""));
}
else
{
user.setText(user.getText().concat(" miles"));
}
}
});
VBox root = new VBox();
root.getChildren().addAll(user,demo);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("transparent text test");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String args[]) {
launch(args);
}
}