I want to click a button in order to make a popup window appear with a tableview element inside it. Can anyone tell me how to do it?
Thanks in advance.
This is the code for simple popup window in JavaFX.
Hope this helps.
public class PopupExample extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(final Stage primaryStage) {
primaryStage.setTitle("Popup Example");
final Popup popup = new Popup();
popup.setX(300);
popup.setY(200);
popup.getContent().addAll(new Circle(25, 25, 50, Color.AQUAMARINE));
Button show = new Button("Show");
show.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
popup.show(primaryStage);
}
});
Button hide = new Button("Hide");
hide.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
popup.hide();
}
});
HBox layout = new HBox(10);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
layout.getChildren().addAll(show, hide);
primaryStage.setScene(new Scene(layout));
primaryStage.show();
}
}
What kind of popup window do you need? Implemented with using a new Stage or Popup control? JavaFX has a control named Popup, read about it to see does it meet your needs. An entry point for Stage version could be Dialog with CLOSE button.
Related
I need to implement a text editor JavaFX, but I have a problem with the creation of the function of adding the image in the text editing area.
It's exactly that when you click the button it was possible to add an image as the screenshot:
Now, I tried to use WebView where I put TextArea code below:
private WebView view;
private WebEngine engine;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
view = new WebView();
engine = view.getEngine();
engine.loadContent("<body><textarea id='content'></textarea><p id='ding' style='display:none;'></p></body>");
view.setPrefHeight(240);
Button btn = new Button("Click Me!");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
append();
engine.executeScript(
"document.getElementById('ding').innerHTML=document.getElementById('content').value;"
);
}
});
Button btn2 = new Button("Click Me 2!");
btn2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
append();
engine.executeScript(
"document.getElementById('ding').innerHTML=document.getElementById('content').value;"
);
}
});
StackPane root = new StackPane();
root.getChildren().addAll(view, btn, btn2);
Scene scene = new Scene(root, 300, 250);
stage.setScene(scene);
stage.show();
}
private void append() {
Document doc = engine.getDocument();
Element el = doc.getElementById("ding");
String s = el.getTextContent();
s += "<img src='http://bluebuddies.com/gallery/Historical_Smurfs/jpg/Smurfs_Historical_Figure_20506_Abraham_Lincoln.jpg'/>";
el.setTextContent(s);
System.out.println(s);
}
After clicking the button adds to the text in the text area link to the photo but unfortunately TextArea This is not supported and when I wanted to use some html editor problem so that I will not have the opportunity to extract all the text correctly with the formatting.
I tried solutions such as RichTextFX but unfortunately he does not have the ability to add images. The HTML editor also did not meet my expectations because I have entered text later saved to a file, for example type: docx. extract text from this editor with formatting is unfortunately difficult.
Are there any other solutions to create word processing with advanced features in JavaFX?
Ideally it was that it could be solved with normal controls TextArea without the use of WebView.
I'm experiencing some weird behavior while trying to show a dialog on my application when my Stage is on fullscreen mode.
Everything works OK while I'm launching my application as a standalone app. When I run from the browser, the modal dialog takes the Stage out of fullscreen. Although, it doesn't go really "out" of fullscreen mode... The code still thinks it's fullscreen (fullscreenProperty == true), but it doesn't show as fullscreen. And after closing the dialog, if you press ESC (which would take you out of fullscreen mode), the application crashes.
Here's a sample code:
public class Test1 extends Application {
#Override
public void start(final Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Stage dialogStage = new Stage(StageStyle.UTILITY);
dialogStage.initModality(Modality.APPLICATION_MODAL);
dialogStage.setScene(new Scene(VBoxBuilder.create().
children(new Text("Hi"), new Button("Ok.")).
alignment(Pos.CENTER).padding(new Insets(5)).build()));
dialogStage.initOwner(primaryStage);
dialogStage.show();
System.out.println(primaryStage.isFullScreen());
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Rectangle2D r = Screen.getPrimary().getBounds();
Scene scene = new Scene(root, r.getWidth(), r.getHeight());
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.setFullScreen(true);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
Any idea how to solve this? Or any idea of what I can use instead of a Stage dialog?
Thanks in advance.
I want to disable a button for a specific time in JavaFX application. Is there any option to do this? If not, is there any work around for this?
Below is my code in application. I tried Thread.sleep, but i know this is not the good way to stop the user from clicking on next button.
nextButton.setDisable(true);
final Timeline animation = new Timeline(
new KeyFrame(Duration.seconds(delayTime),
new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
nextButton.setDisable(false);
}
}));
animation.setCycleCount(1);
animation.play();
You could use the simple approach of a thread that provides the relevant GUI calls (through runLater() of course):
new Thread() {
public void run() {
Platform.runLater(new Runnable() {
public void run() {
myButton.setDisable(true);
}
}
try {
Thread.sleep(5000); //5 seconds, obviously replace with your chosen time
}
catch(InterruptedException ex) {
}
Platform.runLater(new Runnable() {
public void run() {
myButton.setDisable(false);
}
}
}
}.start();
It's perhaps not the neatest way of achieving it, but works safely.
You could also be using the Timeline:
final Button myButton = new Button("Wait for " + delayTime + " seconds.");
myButton.setDisable(true);
final Timeline animation = new Timeline(
new KeyFrame(Duration.seconds(delayTime),
new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent actionEvent) {
myButton.setDisable(false);
}
}));
animation.setCycleCount(1);
animation.play();
The method to disable a JavaFX control is:
myButton.setDisable(true);
You can implement the time logic programmatically in any way you wish, either by polling a timer or by having this method invoked in response to some event.
If you have created this button instance through FXML in SceneBuilder, then you should assign the button an fx:id so that its reference is automatically injected into your controller object during the loading of the scene graph. This will make it easier for you to work with in your controller code.
If you have created this button programmatically, then you'll already have its reference available in your code.
Or you could use a Service and bind the running property to the disableProperty of the button do you want to disable.
public void start(Stage stage) throws Exception {
VBox vbox = new VBox(10.0);
vbox.setAlignment(Pos.CENTER);
final Button button = new Button("Your Button Name");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Service<Void> service = new Service<Void>() {
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
Thread.sleep(5000);//Waiting time
return null;
}
};
}
};
button.disableProperty().bind(service.runningProperty());
service.start();
}
});
vbox.getChildren().addAll(button);
Scene scene = new Scene(vbox, 300, 300);
stage.setScene(scene);
stage.show();
}
But the Timeline solution given by Uluk Biy, looks more elegant.
I have this code which displays confirmation dialog to exit application.
public class DialogPanels
{
public void initClosemainAppDialog(final Stage primaryStage)
{
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>()
{
#Override
public void handle(WindowEvent event)
{
event.consume(); // Do nothing on close request
// Dialog Stage init
final Stage dialog = new Stage();
dialog.initModality(Modality.APPLICATION_MODAL);
// Frage - Label
Label label = new Label("Exit from the program");
// Button "Yes"
Button okBtn = new Button("Yes");
okBtn.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
//primaryStage.close();
//dialog.close();
//Platform.exit();
System.exit(0);
}
});
// Button "No"
Button cancelBtn = new Button("No");
cancelBtn.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
primaryStage.show();
dialog.close();
}
});
// Layout for the Button
HBox hbox = new HBox();
hbox.setSpacing(10);
hbox.setAlignment(Pos.CENTER);
hbox.getChildren().add(okBtn);
hbox.getChildren().add(cancelBtn);
// Layout for the Label and hBox
VBox vbox = new VBox();
vbox.setAlignment(Pos.CENTER);
vbox.setSpacing(10);
vbox.getChildren().add(label);
vbox.getChildren().add(hbox);
// Stage
Scene scene = new Scene(vbox);
dialog.setScene(scene);
dialog.show();
}
});
}
}
The problem is that when close the main application the dialog box is displayed and the main stage is hidden. I want to display the dialog box in front of the main stage. Can you help me to correct this?
UPDATE
I tested this code, it's working but when the dialog is displayed the mainstage is not responsible(frozen). How I an make the mainstage responsible when I display dialog?
Consume the closing event and set the owner of the stage if you do not want to see another window when the windows are minimized:
#Override
public void handle(WindowEvent event)
{
event.consume(); // Do nothing on close request
// Dialog Stage init
final Stage dialog = new Stage();
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(primaryStage);
// other stuff
}
});
You need to set the proper relationships between primaryStage and dialog stage. Here's a hint to get you going:
...
dialog.initOwner(primaryStage);
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.showAndWait();
You can find more information in Oracle's JavaFX 2 JavaDocs.
More example code (edit)
I'm using setOnHiding(..) instead of setOnCloseRequest(..):
stage.setOnHiding(new AskUserIfHeReallyWantsToQuitWindowHandler(stage));
I extracted your code into a seperate event handler class and fixed the issues I mentioned (sorry, I am little short on time right now):
public class AskUserIfHeReallyWantsToQuitWindowHandler implements EventHandler<WindowEvent> {
private final Stage primaryStage;
public AskUserIfHeReallyWantsToQuitWindowHandler(final Stage primaryStage) {
Objects.requireNonNull(primaryStage);
this.primaryStage = primaryStage;
}
#Override
public void handle(final WindowEvent event) {
event.consume();
final Stage dialog = new Stage();
final Button okBtn = new Button("Yes");
okBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent event) {
dialog.close();
primaryStage.close();
}
});
// Button "No"
final Button cancelBtn = new Button("No");
cancelBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent event) {
dialog.close();
Platform.runLater(new Runnable() {
#Override
public void run() {
primaryStage.show();
}
});
}
});
// Layout for the Button
final HBox hbox = new HBox();
hbox.setSpacing(10);
hbox.setAlignment(Pos.CENTER);
hbox.getChildren().add(okBtn);
hbox.getChildren().add(cancelBtn);
// Layout for the Label and hBox
final VBox vbox = new VBox();
vbox.setAlignment(Pos.CENTER);
vbox.setSpacing(10);
vbox.getChildren().add(new Label("Do your really want to exit?"));
vbox.getChildren().add(hbox);
// Stage
final Scene scene = new Scene(vbox);
dialog.setScene(scene);
dialog.initOwner(primaryStage);
dialog.initModality(Modality.NONE);
dialog.showAndWait();
}
}
I have this very simple modal dialog:
public class DialogPanels
{
public void initClosemainAppDialog(final Stage primaryStage)
{
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>()
{
#Override
public void handle(WindowEvent event)
{
event.consume(); // Do nothing on close request
// Dialog Stage init
final Stage dialog = new Stage();
// If you want to freeze the background during dialog appearence set Modality.APPLICATION_MODAL
// or to allow clicking on the mainstage components set Modality.NONE
// and set dialog.showAndWait();
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(primaryStage);
// Frage - Label
Label label = new Label("Exit from the program");
// Button "Yes"
Button okBtn = new Button("Yes");
okBtn.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
//primaryStage.close();
//dialog.close();
//Platform.exit();
System.exit(0);
}
});
// Button "No"
Button cancelBtn = new Button("No");
cancelBtn.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
primaryStage.show();
dialog.close();
}
});
// Layout for the Button
HBox hbox = new HBox();
hbox.setSpacing(10);
hbox.setAlignment(Pos.CENTER);
hbox.getChildren().add(okBtn);
hbox.getChildren().add(cancelBtn);
// Layout for the Label and hBox
VBox vbox = new VBox();
vbox.setAlignment(Pos.CENTER);
vbox.setSpacing(10);
vbox.getChildren().add(label);
vbox.getChildren().add(hbox);
// Stage
Scene scene = new Scene(vbox, 450, 150, Color.WHITESMOKE);
dialog.setScene(scene);
dialog.show();
}
});
}
}
I want to add image and to make it to look like this:
But I admin that it's too complex for my short knowledge to get the appropriate result. Can you show me how I can split the dialog, add second background and make my code to look the same as this example please?
Have a look at the ControlsFX project, they have some sophisticated dialogs and it's open source, so you can look up how it's done. For example, your dialog looks like this confirmation dialog of ControlsFX:
There is also support for custom dialogs.
€dit:
With the "show Masthead" option enabled it actually looks exactly like it: