Open another window on clicking OK button of Alert in JavaFX - javafx

private void showAlert(Alert.AlertType alertType, Window owner, String title, String message) {
Alert alert = new Alert(alertType);
alert.setTitle(title);
alert.setHeaderText(null);
alert.setContentText(message);
alert.initOwner(owner);
//alert.show();
Optional<ButtonType> result = alert.showAndWait();
if ((result.isPresent()) && (result.get() == ButtonType.OK))
{
System.out.println("ALL OK..!");
//Open another window on clicking the OK button
}
}
On this particular section, on clicking OK button, I want to open another window.
Usually Button type is used for which an event can be defined by
buttonName.setOnAction( event -> {
//Action to do
} );
Now how do I define this OK as a button Type?

Related

Toolbar from MasterDetailPage

How can I get navigation back button event if I have MasterDetailPage?
Toolbar toolbar = FindViewById(Resource.Id.toolbar) return null
If want to get event of the hardware back button, you can use OnBackButtonPressed method in ContentPage to get navigation back button event as follow:
protected override bool OnBackButtonPressed()
{
Console.WriteLine("Press back button.");
return base.OnBackButtonPressed();
}
Event that is raised when the hardware back button is pressed. This event is not raised on iOS.
=====================================Update==================================
Else if want to get back event from ToolBar , you should use Android.Support.V7.Widget for Toolbar.
In Acitivity OnCreate:
Android.Support.V7.Widget.Toolbar toolbar = this.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
Override OnOptionsItemSelected method :
public override bool OnOptionsItemSelected(IMenuItem item)
{
if(item.ItemId == Android.Resource.Id.Home)
{
Console.WriteLine("Here is back button event.");
}
return base.OnOptionsItemSelected(item);
}

How to handle multiple tapping on toolbar item in xamarin forms?

I want to implement enable/disable property of toolbar item.
Here is the scenario,
On toolbar item activation I want to open dialog box.
issue:
When I tapped the toolbar item multiple times then it call multiple times dialog box. Please give some solution to handle the multiple calling of dialog box.
To prevent the multiple clicks, you can use a variable, to prevent calling the Dialog while waiting for the result confirmation.
first, in your class declare a variable canTap;
private bool _canTap = true;
Assuming your method when tapping the toolbar is like this:
private void ItemTapped(object sender, EventArgs args)
{
if(_canTap)
{
_canTap= false;
Device.BeginInvokeOnMainThread(async () => {
var response = await
UserDialogs.Instance.ConfirmAsync(new ConfirmConfig { Message = "Are you sure you want to logout from this app?", Title = "Logout", OkText = "YES", CancelText = "NO" );
if(response)
{
}
else
{
}
_canTap = true;)};
}

How to add error popup for empty TextField input in Scenebuilder

I am making an application using Scenebuilder with JavaFX.
I have three inputs for a TableView:
Two TextField input1, input2.
One DatePicker.
When one or more of the input fields is empty and i click on the addButton, the object is added to the TableView.
How do I show an error popup which appears whenever i click on addButton and at least one field (input1, input2) is empty ?
addButton.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
if ((input1.getText() != null && !input1.getText().isEmpty()) &&
(input2.getText() != null && !input2.getText().isEmpty())){
//ADD CODE TO ADD THE ITEM HERE!
} else {
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Input fields empty");
alert.setContentText("Please fill all input fields");
alert.showAndWait();
}
}
});
PS : Here you can find different Alert Types depending on your needs.

How do I minimize a javafx stage on close to the system tray?

I have an application with 2 stages, I dont want users to close the 2nd stage, just iconify it.
At present I am using the oncloseRequest handler to minimize the window -
secondaryStage.setOnCloseRequest(event -> {
secondaryStage.setIconified(true);
event.consume();
});
I would like to show an icon in the system tray when a user closes the window. And the user should be able to reopen the window from the tray.
Also, how do I ensure when the primary stage is closed, the 2nd stage also closes?
Set the following property in start method
Platform.setImplicitExit(false);
Then set the on close event
secondaryStage.setOnCloseRequest(event -> {
// Your code here
});
To make a system tray try following code:
Original document link: https://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html
//Check the SystemTray is supported
if (!SystemTray.isSupported()) {
System.out.println("SystemTray is not supported");
return;
}
final PopupMenu popup = new PopupMenu();
URL url = System.class.getResource("/images/new.png");
Image image = Toolkit.getDefaultToolkit().getImage(url);
final TrayIcon trayIcon = new TrayIcon(image);
final SystemTray tray = SystemTray.getSystemTray();
// Create a pop-up menu components
MenuItem aboutItem = new MenuItem("About");
CheckboxMenuItem cb1 = new CheckboxMenuItem("Set auto size");
CheckboxMenuItem cb2 = new CheckboxMenuItem("Set tooltip");
Menu displayMenu = new Menu("Display");
MenuItem errorItem = new MenuItem("Error");
MenuItem warningItem = new MenuItem("Warning");
MenuItem infoItem = new MenuItem("Info");
MenuItem noneItem = new MenuItem("None");
MenuItem exitItem = new MenuItem("Exit");
//Add components to pop-up menu
popup.add(aboutItem);
popup.addSeparator();
popup.add(cb1);
popup.add(cb2);
popup.addSeparator();
popup.add(displayMenu);
displayMenu.add(errorItem);
displayMenu.add(warningItem);
displayMenu.add(infoItem);
displayMenu.add(noneItem);
popup.add(exitItem);
trayIcon.setPopupMenu(popup);
try {
tray.add(trayIcon);
} catch (AWTException e) {
System.out.println("TrayIcon could not be added.");
}
Example system tray image:
To invoke method of Javafx from awt event handler you may follw the following way:
yourAwtObject.addActionListener(e -> {
Platform.runLater(() -> primaryStage.show());
});
Also, how do I ensure when the primary stage is closed, the 2nd stage
also closes?
You can use something like this to close the secondary stage when the primary stage is closed:
primaryStage.setOnCloseRequest((WindowEvent we) -> {
secondaryStage.close();
}

Enter Key Event Is Not Working On Dialog In Javafx?

I have tried the below code, it works fine with mouse event, but when I use key event i.e ENTER Key on any button than its not showing the result.
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle(null);
alert.setHeaderText(null);
alert.setGraphic(null);
alert.setContentText("Choose your option.");
ButtonType buttonTypeOne = new ButtonType("One");
ButtonType buttonTypeTwo = new ButtonType("Two");
ButtonType buttonTypeThree = new ButtonType("Three");
alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree);
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == buttonTypeOne) {
System.out.println("One");
} else if (result.get() == buttonTypeTwo) {
System.out.println("Two");
} else if (result.get() == buttonTypeThree) {
System.out.println("Three");
}
I do not recommend making all buttons respond to enter, as that is counter to how most UI dialogs work.
Normally, a button with focus will fire when you press space, not enter. There are however special buttons that will activate on specific keys: A default button will fire on enter and a cancel button will fire on esc. Usually you will have only one of each of these special types of buttons in your dialog, so that they can be fired via the special keyboard accelerator, regardless of which button currently has focus.
Additionally, different desktop OS systems have different standards on placement of default and cancel buttons in a dialog system. This is to assist the user in easily finding these special buttons in any dialog. The JavaFX dialog system implements some logic internally for locating buttons in dialogs where the user would expect to see them across different desktop operating systems.
Let's say you want the button types from your example to be defined as default or cancel buttons and placed in the correct position for such buttons for your OS, then you can do as below:
ButtonType buttonTypeTwo = new ButtonType(
"Two",
ButtonBar.ButtonData.OK_DONE
);
ButtonType buttonTypeThree = new ButtonType(
"Three",
ButtonBar.ButtonData.CANCEL_CLOSE
);
Note the JavaFX system has automatically changed the position of the buttons and some of the color highlighting. When the user presses enter, then "Two" will fire, when the user presses esc, then "Three" will fire. If you run the same code on Windows or Linux, likely the buttons will be positioned differently, according to whatever button positioning standard is used for those OSes.
If you don't want JavaFX to reposition your buttons according to OS standards, but you want them to still respond to enter and esc keys, then you can lookup the buttons and directly modify the button attributes like below:
Button buttonTwo = (Button) alert.getDialogPane().lookupButton(buttonTypeTwo);
buttonTwo.setDefaultButton(true);
Button buttonThree = (Button) alert.getDialogPane().lookupButton(buttonTypeThree);
buttonThree.setCancelButton(true);
I recommend letting JavaFX appropriately position buttons of specific types rather than performing lookups as above.
I also recommend setting at least a CANCEL_CLOSE button or OK_DONE button in your JavaFX Alert, otherwise the user may have a difficult time actually closing the alert as the dialog will probably not respond to key presses as the user expects.
I don't know if this is not a kind of too much of a workaround, but at least it works:
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
[...]
ButtonType buttonTypeTwo = new ButtonType("Two");
ButtonType buttonTypeThree = new ButtonType("Three");
alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree);
//Create a button for every ButtonType you add to your alert and give it a Eventhandler
Button button1 = (Button) alert.getDialogPane().lookupButton(buttonTypeOne);
Button button2 = (Button) alert.getDialogPane().lookupButton(buttonTypeTwo);
Button button3 = (Button) alert.getDialogPane().lookupButton(buttonTypeThree);
button1.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER)
alert.setResult(buttonTypeOne);
}
});
button2.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER)
alert.setResult(buttonTypeTwo);
}
});
button3.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER)
alert.setResult(buttonTypeThree);
}
});
//go ahead with your code
Optional<ButtonType> result = alert.showAndWait();
[...]
You just create some Buttons and assigned them the actual buttons on your alert. In the next Step you can give every button an EventHandler which just (In this example) checks - when any key is released - if the key was ENTER and set the result.
I guess there are better solutions for this. But it's the easiest way which comes to my mind currently. Hope it helps you.
Here how i solved it.
it works fine below is my confirm alert function.
public static boolean confirmAlert(String title, String msg){
ButtonType buttonTypeYes = new ButtonType("Yes", ButtonBar.ButtonData.OK_DONE);
ButtonType buttonTypeNo = new ButtonType("No",ButtonBar.ButtonData.CANCEL_CLOSE);
Alert alert = new Alert(Alert.AlertType.NONE, msg,buttonTypeNo,buttonTypeYes);
alert.setTitle(title);
Button button1 = (Button) alert.getDialogPane().lookupButton(buttonTypeYes);
button1.setDefaultButton(false); //***set default to false***
Button button2 = (Button) alert.getDialogPane().lookupButton(buttonTypeNo);
button1.setOnKeyReleased(event -> {
if(event.getCode() == KeyCode.ENTER)
alert.setResult(buttonTypeYes);
});
button2.setOnKeyReleased(event -> {
if(event.getCode() == KeyCode.ENTER)
alert.setResult(buttonTypeNo);
});
alert.showAndWait();
return alert.getResult()==buttonTypeYes;
}
you don't need to set default method, On which ever button you want to enter key
Alert confirmAlert = new Alert(Alert.AlertType.CONFIRMATION, "", ButtonType.YES, ButtonType.NO);
confirmAlert.setHeaderText("Are You Sure Want To Delete ?");
Button bt1 = (Button) confirmAlert.getDialogPane().lookupButton(ButtonType.YES);
Button bt2 = (Button) confirmAlert.getDialogPane().lookupButton(ButtonType.NO);
bt2.addEventHandler(KeyEvent.ANY,(event) -> {
if(event.getCode() == KeyCode.ENTER){
confirmAlert.setResult(ButtonType.NO);
}
});
Optional <ButtonType> action = confirmAlert.showAndWait();
if(action.get() == ButtonType.NO){
System.err.println("Action You Want");
}

Resources