I want to retrieve several integers from the same text field, but I can't figure out how to do it. Anyone?
Here is a clearer solution. This will throw and error for incorrect input.
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.VBox;
import javafx.stage.Stage;
/**
*
* #author blj0011
*/
public class JavaFXApplication37 extends Application {
#Override
public void start(Stage primaryStage) {
Label info = new Label("Enter some numbers. Each seperated by one space");
TextField tf = new TextField();
Label label = new Label();
Button btn = new Button();
btn.setText("Sum Numbers");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if(tf.getText().length() > 0)//Only run if the text field is not empty
{
String[] stringOfNumbers = tf.getText().split(" ");//The numbers must be seperated by one space. This get the string of numbers and seperates them based on the space between each numbers
//sum up the numbers
double sum = 0;
for(int i = 0; i < stringOfNumbers.length; i++)
{
sum = sum + Double.parseDouble(stringOfNumbers[i]);//This sums the numbers and convert the strings to doubles
}
label.setText("The sum equals: " + sum);//This prints the sum of the doubles
}
}
});
VBox root = new VBox();
root.getChildren().addAll(info, tf, label, btn);//This adds all the nodes to the VBox
Scene scene = new Scene(root, 300, 250);//This adds the VBox to the Scene
primaryStage.setTitle("Sum Numbers");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
I noticed this question asked to handle integers. In this code change double to int and Double to Integer.
I am adding this solution since your solution did not contain a button
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* #author blj0011
*/
public class JavaFXApplication37 extends Application {
#Override
public void start(Stage primaryStage) {
Label info = new Label("Enter some numbers each seperated by one space");
Label label = new Label();
TextField tf = new TextField();
tf.textProperty().addListener((observable, oldValue, newValue) -> {
try
{
if(newValue.length() > 0)//Only run if the text field is not empty
{
String[] stringOfNumbers = tf.getText().split(" ");//The numbers must be seperated by one space. This get the string of numbers and seperates them based on the space between each numbers
//sum up the numbers
int sum = 0;
for(int i = 0; i < stringOfNumbers.length; i++)
{
sum = sum + Integer.parseInt(stringOfNumbers[i]);//This sums the numbers and convert the strings to doubles
}
label.setText("The sum equals: " + sum);//This prints the sum of the doubles
}
else
{
label.setText("");//if no text in textfield set label to empty string
}
}
catch(NumberFormatException ex)
{
label.setText("");//any number format error set label to empty string
}
});
VBox root = new VBox();
root.getChildren().addAll(info, tf, label);//This adds all the nodes to the VBox
Scene scene = new Scene(root, 300, 250);//This adds the VBox to the Scene
primaryStage.setTitle("Sum Numbers");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Related
Is there a way to create tableview with vertical headings ? I don't see any option in javafx to do this.
You can set the graphic to a Label which is rotated, and set the text to an empty string.
private void makeColumnHeader(TableColumn<?,?> column) {
Label label = new Label();
label.setText(column.getText());
column.setText("");
label.setRotate(90);
column.setGraphic(label);
}
Here's a complete example:
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
private void makeColumnHeader(TableColumn<?,?> column) {
Label label = new Label();
label.setText(column.getText());
column.setText("");
label.setRotate(90);
column.setGraphic(label);
}
#Override
public void start(Stage stage) throws IOException {
TableView<Item> table = new TableView<>();
TableColumn<Item, Number> idColumn = new TableColumn<>("Id");
idColumn.setCellValueFactory(data -> new SimpleIntegerProperty(data.getValue().id()));
TableColumn<Item, String> itemColumn = new TableColumn<>("Item");
itemColumn.setCellValueFactory(data -> new SimpleStringProperty(data.getValue().name()));
makeColumnHeader(idColumn);
makeColumnHeader(itemColumn);
table.getColumns().add(idColumn);
table.getColumns().add(itemColumn);
for (int i = 1 ; i <= 20; i++) table.getItems().add(new Item(i, "Item "+i));
BorderPane root = new BorderPane(table);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static record Item(int id, String name){}
public static void main(String[] args) {
launch();
}
}
Note that setting the column's text to an empty string can have undesirable side effects. For example, the tableMenuButton relies on the text in the table columns to display the menu items. Add table.setTableMenuButtonVisible(true); to the code above to see the problem.
A slightly more robust solution is to bind the text of the label in the graphic to the text in the column, and then use CSS to hide the default text:
private void makeColumnHeader(TableColumn<?,?> column) {
Label label = new Label();
label.textProperty().bind(column.textProperty());
label.setRotate(90);
column.setGraphic(label);
}
and in an external style sheet:
.table-column > .label {
-fx-content-display: graphic-only;
}
I had to adapt the solution from #James_D to properly size the label by applying a minWidth and wrapping it in a Group: (Tested with openjfx19)
private void makeColumnHeader(TableColumn<?, ?> column, String text) {
Label label = new Label();
label.setText(text);
label.setRotate(-90);
label.setMinWidth(80);
column.setGraphic(new Group(label));
column.getStyleClass().add("rotated");
}
I have the following code that runs at program startup. It serves to show a toast informing which people are birthday on the current day, through an excel file. However, when there is more than one birthday person, he shows several toasts at once, one on top of the other. I wanted a way to wait, while a toast disappears, to show the next one
Arquivo arquivo = new Arquivo();
ObservableList<String> listaDatas = arquivo.pegarListaString(1, 8); //take people's birthday dates
String data = Agenda.dateParaString(LocalDate.now()).substring(0, 5); //today's day
String data2 = Agenda.dateParaString(LocalDate.now().plusDays(1)).substring(0, 5); //tomorrow
int index = 0;
for(String valor: listaDatas) {
if (valor.length() > 4) {
if (valor.substring(0, 5).equalsIgnoreCase(data)) {
Agenda.mostrarToastTexto("Hoje é aniversário de " + arquivo.pegarValor(1, index, 0), 2000);
} else if(valor.substring(0, 5).equalsIgnoreCase(data2)) {
Agenda.mostrarToastTexto("Amanhã é aniversário de " + arquivo.pegarValor(1, index, 0) , 2000);
}
}
index++;
}
I already tried to use a "Thread.sleep" and also the class Timer, but to no avail.
Here is one approach using code from here.
This code uses Timeline to show a different name every two seconds.
import com.jfoenix.controls.JFXSnackbar;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
*
* #author blj0011
*/
public class JavaFXApplication207 extends Application
{
#Override
public void start(Stage primaryStage)
{
StackPane root = new StackPane();
JFXSnackbar snackbar = new JFXSnackbar(root);
List<String> listaDatas = new ArrayList();
listaDatas.add("Kim");
listaDatas.add("John");
listaDatas.add("Chris");
AtomicInteger counter = new AtomicInteger();
Timeline threeSecondsWonder= new Timeline(new KeyFrame(Duration.seconds(3), new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
snackbar.show("Happy birthday " + listaDatas.get(counter.getAndIncrement()) + "!", 2000);
}
}));
threeSecondsWonder.setCycleCount(listaDatas.size());
threeSecondsWonder.play();
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}
Update: using JFXSnackbar in the answer.
I'm trying to keep the Elipsis String (...) on my Label (lbl) but I want it to be set to an empty String when the window gets too small. I'm using the code here to show an example. I'm using the ResizeHelper class found here: Allow user to resize an undecorated Stage.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
/**
*
* #author bparmeter
*/
public class NewFXMain extends Application {
#Override
public void start(Stage primaryStage) {
Label lbl = new Label();
lbl.setText("Hello World");
AnchorPane root = new AnchorPane();
AnchorPane.setBottomAnchor(lbl, 0.0);
AnchorPane.setTopAnchor(lbl, 0.0);
AnchorPane.setRightAnchor(lbl, 0.0);
AnchorPane.setLeftAnchor(lbl, 0.0);
root.getChildren().add(lbl);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.show();
ResizeHelper.addResizeListener(primaryStage);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Not the best solution but it works...
lbl.widthProperty().addListener((ov, o, n) -> {
final Text t = new Text(lbl.getText().charAt(0)+"...");
t.applyCss();
final double width = t.getLayoutBounds().getWidth();
lbl.setEllipsisString(width>=lbl.getWidth() ? "" : "...");
});
Is there anyway I can do a for loop to create multiple textfields. Say I want like 20 text fields...do I have to create them individually?
It's not really clear what your question is. Just write a for loop and create each TextField inside it.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TwentyTextFields extends Application {
#Override
public void start(Stage primaryStage) {
final int numTextFields = 20 ;
TextField[] textFields = new TextField[numTextFields];
VBox root = new VBox(5);
for (int i = 1; i <= numTextFields; i++) {
TextField tf = new TextField();
String name = "Text field "+i ;
tf.setOnAction(e -> {
System.out.println("Action on "+name+": text is "+tf.getText());
});
root.getChildren().add(tf);
textFields[i-1] = tf ;
}
Scene scene = new Scene(new ScrollPane(root), 250, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I have a problem with my button size in JavaFX. I want to have fixed size buttons but when I change text on the buttons, changes button size aswell.
I have 5 buttons and 5 random numbers between 1 - 20. Buttons with single digit is smaller then buttons with two digits. I want both same size.
What can I do?
Here is one way to do this. The buttons go in a TilePane, the TilePane goes in a group so that everything in it remains at it's preferred size. A preferred size is set on each button.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.TilePane;
import javafx.stage.Stage;
import java.util.Random;
public class FixedSizes extends Application {
private static final int NUM_BUTTONS = 5;
private static final int MAX_BUTTON_VALUE = 20;
private static final Random random = new Random(42);
#Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(generateButtonLayout()));
stage.show();
}
private Parent generateButtonLayout() {
TilePane layout = new TilePane();
layout.setHgap(10);
layout.setPrefColumns(NUM_BUTTONS);
layout.getChildren().setAll(createButtons());
layout.setPadding(new Insets(10));
return new Group(layout);
}
private Button[] createButtons() {
Button[] buttons = new Button[NUM_BUTTONS];
for (int i = 0; i < buttons.length; i++) {
buttons[i] = createButton();
}
return buttons;
}
private Button createButton() {
Button button = new Button(generateButtonText());
button.setOnAction(event -> button.setText(generateButtonText()));
button.setPrefWidth(50);
return button;
}
private String generateButtonText() {
return "" + (random.nextInt(MAX_BUTTON_VALUE) + 1);
}
public static void main(String[] args) {
launch(args);
}
}