I know that in order to prevent JOptionpane from hiding behind any of the frame we have to give the current frame as parent frame to JOptionpane.
I have a JTree with popupmenu
it has popup menu follows
Add
Rename
Delete
when I click the delete menu i'll call the showDeleteConfirmation() to confirm the action to delete or not
But the problem if I use currentMainframe(the one which jtree is present) as parent frame for JOptionpane and when I click the JPopumenu is not hiding(still in focus) so I have to click on Joptionpane once (to hide the popupmenu) and then only I can select the options
If I use null as parentframe it is working perfectly(onclicking the the menuitem it is automatically hiding).
How to solve the issue
//Have to click anywhere on JOptionpane to gain focus(also to hide popupmenu)
public static Boolean showDeleteConfirmation() {
if (deleteConfirmation) {
int value = JOptionPane.showConfirmDialog(currentMainFrame, "Are you sure want to delete?", "Delete", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
return value == JOptionPane.YES_OPTION;
}
return true;
}
//This is working perfectly
public static Boolean showDeleteConfirmation() {
if (deleteConfirmation) {
int value = JOptionPane.showConfirmDialog(null, "Are you sure want to delete?", "Delete", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
return value == JOptionPane.YES_OPTION;
}
return true;
}
I manually called JPopupmenu.hide() before calling that function.It solved the problem
Related
I am working with Swing right now and I do not get this to work properly.
What I need is the following:
I've got a class "Client" that is able to connect to a TCP server.
If the connection fails (wrong IP for example), then it will show an error dialog that can be closed by clicking on the "OK" Button.
However if the client connected successfully, a window should popup that runs until my client receives a specific message from the server.
My code looks like this:
if(ip != null) {
Client c = new Client();
try{
c.connect(ip, 56556);
JOptionPane msg = new JOptionPane("Connecting...", JOptionPane.INFORMATION_MESSAGE);
JDialog dlg = msg.createDialog("Connecting...");
dlg.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dlg.setVisible(true);
c.addIncomingMessageHandler(new IncomingMessageHandler(){
#Override
public void incomingMessage(Connection<?> cnctn, Object o) {
dlg.setVisible(false);
dlg.dispose();
}
});
}catch(Exception e) {
int n = JOptionPane.showOptionDialog(this, "Oops! Something went wrong!",
"Title", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE,
null, new Object[] {"OK"}, JOptionPane.OK_OPTION);
}
}
So the exception is throws if c.connect() fails.
c.addIncomingMessageHandler() is a listener that listens to any incoming messages to the client. If the server sends something, this method will be called. If that's the case, the JDialog will be closed. But this window can be closed right now by clicking on the OK-Button.
I'd like to rename that button and add a function.
The new text should be "Cancel" and if the button is pressed, the client should be closed (c.disconnect) and the window itself should be closed as well.
How could I do that?
From the Documentation:
Stopping Automatic Dialog Closing
By default, when the user clicks a JOptionPane-created button, the dialog closes. But what if you want to check the user's answer before closing the dialog? In this case, you must implement your own property change listener so that when the user clicks a button, the dialog does not automatically close.
DialogDemo contains two dialogs that implement a property change listener. One of these dialogs is a custom modal dialog, implemented in CustomDialog, that uses JOptionPane both to get the standard icon and to get layout assistance. The other dialog, whose code is below, uses a standard Yes/No JOptionPane. Though this dialog is rather useless as written, its code is simple enough that you can use it as a template for more complex dialogs.
Besides setting the property change listener, the following code also calls the JDialog's setDefaultCloseOperation method and implements a window listener that handles the window close attempt properly. If you do not care to be notified when the user closes the window explicitly, then ignore the bold code.
final JOptionPane optionPane = new JOptionPane(
"The only way to close this dialog is by\n"
+ "pressing one of the following buttons.\n"
+ "Do you understand?",
JOptionPane.QUESTION_MESSAGE,
JOptionPane.YES_NO_OPTION);
final JDialog dialog = new JDialog(frame,
"Click a button",
true);
dialog.setContentPane(optionPane);
dialog.setDefaultCloseOperation(
JDialog.DO_NOTHING_ON_CLOSE);
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
setLabel("Thwarted user attempt to close window.");
}
});
optionPane.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (dialog.isVisible()
&& (e.getSource() == optionPane)
&& (prop.equals(JOptionPane.VALUE_PROPERTY))) {
//If you were going to check something
//before closing the window, you'd do
//it here.
dialog.setVisible(false);
}
}
});
dialog.pack();
dialog.setVisible(true);
int value = ((Integer)optionPane.getValue()).intValue();
if (value == JOptionPane.YES_OPTION) {
setLabel("Good.");
} else if (value == JOptionPane.NO_OPTION) {
setLabel("Try using the window decorations "
+ "to close the non-auto-closing dialog. "
+ "You can't!");
}
Click here!
Related question.
I'm showing a ConfirmDialog with some input fields. When save fails (validation fails) I want to show a MessageDialog box but I don't want the ConfirmDialog box to disappear. How do I do this?
Below is my actionPerformed method to open the ConfirmDialog (when I click a button with this method as it's event handler)
#Override
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(null, panel, "New transaction",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
// save transaction
Transaction transaction = new Transaction();
// ...
if (transaction.save()) {
// close the ConfirmDialog is OK, save was successful
} else {
// don't close the ConfirmDialog, save failed
JOptionPane.showMessageDialog(panel, "Please fix the errors");
}
}
}
You can't use the static methods of the JOptionPane class to create the dialog.
You need to create your own dialog and then use the JOptionPane as the contentPane of your dialog.
Read the section from the Swing tutorial on Stopping Automatic Dialog Closing for example code on how this can be done.
I've designed (using the GUI designer within Netbeans) a small dialog with two radio buttons and a number spinner.
If I press Enter while the focus is on one of the radio buttons, the dialog correctly closes, but if the focus is on the spinner, I have to Tab away from it in order to use the Enter key.
How do I instruct the dialog that Enter really means "accept and close"?
Alternatively, how do I instruct (each) input field to relay an Enter to the "accept and close" handler?
Similarly, how do I instruct the dialog that Esc really means "cancel and close" even when the focus is on the spinner (or other field)?
how do I instruct (each) input field to relay an Enter to the "accept and close" handler?
The easiest approach is to define a "default button" on the dialog. Then when Enter is pressed the default button will be activated. Check out Enter Key and Button for different ways to do this.
how do I instruct the dialog that Esc really means "cancel and close"
Use Key Bindings to invoke the Action of your Cancel button.
First you define an Action to be used by the button:
public class CancelAction extends AbstractAction
{
public CancelAction()
{
super("Cancel");
putValue( Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_C) );
}
#Override
public void actionPerformed(ActionEvent e)
{
Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
if (window != null)
{
WindowEvent windowClosing = new WindowEvent(window, WindowEvent.WINDOW_CLOSING);
window.dispatchEvent(windowClosing);
}
}
}
Then you add the Action to the button so the user can use the mouse:
CancelAction cancelAction = new CancelAction();
cancelButton.setAction( cancelAction );
dialog.add(cancelButton);
Now you can use Key Bindings to bind the Escape key to the CancelAction so the user can use the keyboard:
KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeKeyStroke, "ESCAPE");
getRootPane().getActionMap().put("ESCAPE", cancelAction);
I suspect the reason I had problems is that a spinner is really a compound control, and the text (well, number) field is an component of that. So I needed to hook up the events to that subcomponent, rather than to the spinner itself:
// Make Ok/Cancel work when JSpinner has focus
getSpinnerField(jSpinnerOffset).addActionListener(new java.awt.event.ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
doOk();
}
});
where "getSpinnerField()" is just a shorthand in a private method:
private JFormattedTextField getSpinnerField(JSpinner spinner) {
return ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
}
Doing this, the Esc key automagically becomes able to dismiss the dialog.
I have a small problem trying to figure out how to check if a user presses a button in a custom JOptionPane.
My dialog is based on an inputDialog with custom texts for the YES, NO and CANCEL buttons ("Select", "Cancel", "Open Editor").
I tried searching for a solution, but all I found was questions that used the static JOptionPane functions.
Here is my code I am using for now:
public SelectItemDialog(Component parent) {
super("Please select an item:", YES_NO_CANCEL_OPTION, PLAIN_MESSAGE, Editor.getIcon("bookmark"),
new String[] { "Select", "Cancel", "Open Item Editor" }, "Select"
);
setWantsInput(true);
setSelectionValues(null); // Would replace with an Object array
setInitialSelectionValue(null);
setComponentOrientation(getRootFrame().getComponentOrientation());
JDialog dialog = createDialog(parent, "Select Item");
selectInitialValue();
dialog.setVisible(true);
dialog.dispose();
Object obj = getInputValue();
if(obj instanceof Item) {
this.openEditor = false;
this.item = (Item) obj;
} else {
this.openEditor = (obj.equals( CANCEL_OPTION));
this.item = null;
}
}
The check for CANCEL_OPTION is not working at all, same with UNDEFINED_OPTION.
Any ideas?
Actually I just had to use the Object returned by the JOptionPane itself: getValue(), problem solved!
Is this the intended functionality or am I doing something wrong?
All I'm doing is creating a GXT Button and calling setMenu to attach a GXT menu. On first click, the menu shows properly, on second click, the menu disappears on MouseDown, but reappears on MouseUp. The only way to get the menu to hide is to click away from the button.
I confirmed that it isn't anything strange with a particular button in my code by adding another button:
Button button = new Button("test");
Menu menu = new Menu();
button.setMenu(menu);
add(button);
If this is intended, is there a suggestion on how to add a listener to close the menu on second click?
I am guessing that it is working as intended since the menu always hides as soon as it loses focus. What I did below is override the onAutoHide method in the menu to not hide if the button with the specified ID is pressed (change accordingly). This gives me the ability to check if the menu is shown in the onClick method of the button - and then not show it again. Be warned though...I am in no way an expert and this is a hack :)
Button button = new Button("Test") {
#Override
protected void onClick(ComponentEvent ce) {
ce.preventDefault();
focus();
hideToolTip();
if (!disabled) {
ButtonEvent be = new ButtonEvent(this);
if (!fireEvent(Events.BeforeSelect, be)) {
return;
}
if (menu != null) {
if (!menu.isVisible())
showMenu();
else
hideMenu();
}
fireEvent(Events.Select, be);
}
}
};
button.setId("TESTBUTTONID");
Menu menu = new Menu() {
#Override
protected boolean onAutoHide(PreviewEvent pe) {
if (pe.getEventTypeInt() == Event.ONMOUSEDOWN
&& !(pe.within(getElement()) || (fly(pe.getTarget())
.findParent(".x-ignore", -1) != null))
&& !(fly(pe.getTarget()).findParent(".x-btn", -1) != null
&& fly(pe.getTarget()).findParent(".x-btn", -1).getId()
.equalsIgnoreCase("TESTBUTTONID"))) {
MenuEvent me = new MenuEvent(this);
me.setEvent(pe.getEvent());
if (fireEvent(Events.AutoHide, me)) {
hide(true);
return true;
}
}
return false;
}
};
button.setMenu(menu);
RootPanel.get().add(button);