JavaFX: set an overlapping text on a button when clicked - javafx

I'm creating a simple lottery game where I can chose numbers from 1 to 42. I would like to mark the chosen number with a red "X" (instead of using an effect) but the user should still see the chosen number beneath the "X". When the user clicks the marked number again, the "X" should disappear.
The GUI looks like this:
enter image description here
How can I display a second text on a button in the way that the first text is still visible?
Thanks for your help
kind regards
Joel

You can set the Graphic of a button to a StackPane and then add an element to the StackPane. Since the children of a StackPane are all displayed on top of each other, this yields the effect that you want. My example just shows the concept, I would probably write a new class that extends Button in your use scenario :)
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
public class NewFXMain extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Pane pane = new Pane();
StackPane buttonPane = new StackPane();
Label label = new Label("42");
buttonPane.getChildren().add(label);
Button button = new Button();
button.setGraphic(buttonPane);
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if(buttonPane.getChildren().size() == 1){
Label labelX = new Label("X");
labelX.setStyle("-fx-text-fill: red;");
buttonPane.getChildren().add(labelX);
}
else
buttonPane.getChildren().remove(1);
}
});
pane.getChildren().addAll(button);
primaryStage.setScene(new Scene(pane, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Related

How to select the next text field after a key pressed (ENTER) in javafx?

I am making a login GUI and after I enter the username, I want to hit ENTER key and it will select the password text field. How can I achieve this?
My attempt:
#FXML
void userNameKeyPressed(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB) {
passWord.requestFocus();
}
}
I think you'll need to compile a more complete example. Eg maybe a simple fxml and where it goes wrong. Here is an example that works, and it uses most of the ingredients you are.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import javafx.scene.input.KeyEvent;
public class TextFields extends Application{
public static void main(String[] args){
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("text field");
TextField a = new TextField();
TextField b = new TextField();
a.setOnKeyPressed( evt ->{
System.out.println(KeyCode.ENTER + ", " + evt.getCode());
if(evt.getCode().equals(KeyCode.ENTER)){
System.out.println("entered");
b.requestFocus();
}
});
BorderPane root = new BorderPane();
root.setLeft(a);
root.setRight(b);
primaryStage.setScene(new Scene(root, 300, 100));
primaryStage.show();
}
}
This code creates a frame with 2 text fields, if you press enter in the left one, you will move to the right one.

How to make a suttering window in JavaFx?

I need a window that can be move up down in my main window. Mainly IDE(IntelliJ, CodeBlock, Netbeans etc) output window feature.
I use TitledPane. By using this I can give a height that is expanded when I click the pane, but I can't expand the pane in any height.
see this - not expanded:
and this- expanded:
My code is here
Try using SplitPane. I guess this is what you want. You can learn more from the following link
https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/SplitPane.html
import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
SplitPane splitPane = new SplitPane(new Pane(), new Pane());
splitPane.setDividerPositions(0.5);
splitPane.setOrientation(Orientation.VERTICAL);
primaryStage.setScene(new Scene(splitPane,400,400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Simple way to create a vertical ButtonBar using JavaFX Scene Builder/Gluon

How do I make a vertical ButtonBar in JavaFX 8?
I want exactly the same concepts of the ButtonBar component, but ButtonBar is horizontal, I want vertical. All the buttons must be same size.
If I use a VBox I have to set the width of the buttons and of the VBox manually.
Is there a simpler way to do that without having to set widths?
You need two things: to set fillWidth to true on the VBox, and to set maxWidth on each button. The most convenient approach is probably a simple subclass of VBox:
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
public class VerticalButtonBar extends VBox {
public VerticalButtonBar() {
setFillWidth(true);
}
public void addButton(Button button) {
button.setMaxWidth(Double.MAX_VALUE);
getChildren().add(button);
}
}
and then you can do things like
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class VerticalButtonBarExample extends Application {
#Override
public void start(Stage primaryStage) {
VerticalButtonBar bar = new VerticalButtonBar();
bar.addButton(new Button("A"));
bar.addButton(new Button("Button"));
BorderPane root = new BorderPane();
root.setLeft(bar);
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
which looks like
See Adding a custom component to SceneBuilder 2.0 if you want to make the VerticalButtonBar visible to SceneBuilder.
As far as I can see, ButtonBar has no way to change this, so there is nothing SceneBuilder can do about it.
You might want to file a feature request for ButtonBar: http://bugs.java.com/

How to show ProgressIndicator in center of Pane in Javafx

I have a Pane with some controls and a button. When I click on the button, I want show ProgressIndicator in center of pane without removing any controls.
When I am adding a ProgressIndicator to pane during onAction of button, it adds it below the button. I want it to overlay on the pane.
The picture below explains what I want.
Code
package fx;
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.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage arg0) throws Exception {
final VBox bx = new VBox();
bx.setAlignment(Pos.CENTER);
TextField userName = new TextField("User Name");
userName.setMaxWidth(200);
TextField email = new TextField("Email");
email.setMaxWidth(200);
Button submit = new Button("Submit");
submit.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
ProgressIndicator pi = new ProgressIndicator();
//adding here but it is adding at below of button
//how to do here
bx.getChildren().add(pi);
//Further process
}
});
bx.getChildren().addAll(userName, email, submit);
Scene c = new Scene(bx);
arg0.setScene(c);
arg0.setMinWidth(500);
arg0.setMinHeight(500);
arg0.show();
}
public static void main(String[] args) {
Main h = new Main();
h.launch(args);
}
}
You need to use a StackPane as your root layout instead of using a VBox. StackPane allows you to stack nodes on top of each other (z-order).
On the button's action you can create a new ProgressIndicator and add it to your StackPane. I have introduced another VBox as the parent to the indicator, because I did not want the indicator to capture all the available space. You can disable the already present VBox to get the greying effect on button's action after the process is done you can enable the VBox again.
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.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage arg0) throws Exception {
StackPane root = new StackPane();
VBox bx = new VBox();
bx.setAlignment(Pos.CENTER);
TextField userName = new TextField("User Name");
userName.setMaxWidth(200);
TextField email = new TextField("Email");
email.setMaxWidth(200);
Button submit = new Button("Submit");
submit.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
ProgressIndicator pi = new ProgressIndicator();
VBox box = new VBox(pi);
box.setAlignment(Pos.CENTER);
// Grey Background
bx.setDisable(true);
root.getChildren().add(box);
}
});
bx.getChildren().addAll(userName, email, submit);
root.getChildren().add(bx);
Scene c = new Scene(root);
arg0.setScene(c);
arg0.setMinWidth(500);
arg0.setMinHeight(500);
arg0.show();
}
public static void main(String[] args) {
launch(args);
}
}

JavaFX ListView and MouseEvent

I have a ListView and I want it to change the selected item when I click a different item. For example, I have:
result.getSelectionModel().select(0);
I want to change that .select(0) to .select(x), where x is the index on that ListView, from a mouse click. I'm not sure if I explained it correctly.
Hope you can help, thanks!
The default behaviour of a ListView is to select the item the user clicks. There is nothing you need to code to achieve this.
Just run the following sample and click on the list items and you will see the selection change.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
public class ListViewViewer extends Application {
#Override
public void start(Stage stage) {
ListView<String> list = new ListView<>();
ObservableList<String> items = FXCollections.observableArrayList(
"Single", "Double", "Suite", "Family App");
list.setItems(items);
list.getSelectionModel().select(0);
stage.setScene(new Scene(list));
stage.show();
list.requestFocus();
}
public static void main(String[] args) {
launch(args);
}
}

Resources