i have a small program where an element is draged and dropped, when the drop is performed i open a dialog (extends Jframe) where some text should be entered. The Problem is, that i want to wait for this dialog to be closed (actually the ok button to be pressed so i can read out the data from the textfield), than analyse what the user has entered and based on that i will decide if the drop is rejected or allowed.
public void drop(DropTargetDropEvent e) {
try{
//popup
Popup p = new Popup();
p.setParmeter("enter a new name: ");
p.setVisible(true);
//programm wont wait before the user has pressed ok in the popup
System.out.println("value: " + p.getValue());
repaint();
} else {
e.rejectDrop();
}
}
I hope you get the idea. Popup is a dialog extended from a JFrame. The problem is, that p.getValue() is executed before the User gets to press the ok button. I tried using a boolean variable and a loop to check if something was entered in the popup but it doesnt work, the dialog is desplayed but there is not textfield or ok button, so the only thing i can do is to kill it. I'm pretty new to gui's so i really would appreciate the help. Thanks in advance.
If possible you should re-implement Popup to inherit from JDialog instead of JFrame, and call JDialog's setModal(true) method, which will prevent subsequent code from running until the dialog is dismissed.
Alternatively, check out the static convenience methods in JOptionPane, which eliminate the need to implement your own bespoke dialog class in many cases. For example (from the JOptionPane API):
Show an information panel with the options yes/no and message 'choose one':
JOptionPane.showConfirmDialog(null, "choose one", "choose one", JOptionPane.YES_NO_OPTION);
Java has built-in dialog support. Yon don't want to extend JFrame. See the tutorial on how to make dialogs.
Related
I'm currently working on a chess game for a school project. When you promote a pawn, it opens a dialog box that allows the player to select which piece they would like to promote to. However, when the player clicks "cancel" or "X", then the box simply returns null, and the user cannot promote their piece. I was wondering if I could remove/disable the cancel button and the "X" button. Here is my code:
private String createDialog() {
hideLabels();
Object[] options = {"Queen", "Knight", "Bishop", "Rook"};
String selection = (String)JOptionPane.showInputDialog(frame, "What would you like to promote to?, ", "Promote", JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
return selection;
}
Instead of using a JOptionPane which doesn't give you much control over the functionality you can create your own custom JDialog and add your own components and buttons to the dialog.
You can't remove the close button, but you can prevent the close button from doing anything by adding:
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
Or if you really want to use a JOptionPane then check out the section from the Swing tutorial on Stopping a Dialog From Closing which shows how you check to make sure a valid value has been entered.
The goal of my code is to get the user input and when the user would like to save the data, they press the OK option. However, if the user has input some data, and would no longer like to continue, they then just press the red cross exit button via the top right corner to exit without saving?
How do I go about this?
Here's my code:
JOptionPane.showMessageDialog(null, myPanel, "Edit Fruit", JOptionPane.INFORMATION_MESSAGE);
...
if (!(JOptionPane.OK_OPTION))
{
//If the user exits the option pane via the red cross, exit the loop.
break;
}
EDIT: This code does not work as I'm only looking for when a JOptionPane.showMessageDialog is closed via the red cross and not an OK button:
addWindowListener(new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent e)
{
System.out.println("Closed");
e.getWindow().dispose();
}
});
The code still executes even when I press the OK option in my JOptionPane. I only want to listen for the exit via the red cross.
Thanks for your help.
Firstly, it's not a very standard UI to do something only if the user closes a window by the red x - as opposed to closing the window by typing Alt-F4, or double clicking the icon, or Alt-Space-C, and so on; so I'll assume you just meant closing without pressing the OK button rather than by the red x specifically.
You have code which can detect when the window is closed.
You have code can detect when the user presses the OK button.
So set a flag to indicate the OK button was pressed, and if the flag is not set when the window closed, then the user closed the window without pressing the OK button.
Another quick search with the keywords "JOptionPanel close listener" takes me to another question.
How can I add a listener on the ok button of JOptionPane?
The accepted answer suggests to check the return value of the method showOptionDialog.
But you can use the method JOptionPane.showOptionDialog with a single
DEFAULT_OPTION for the OK button. The showOptionDialog will return 0
if OK was clicked and -1 if the user closed the dialog.
int res = JOptionPane.showOptionDialog(null, "Hello", "Test",
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE, null, null, null);
System.out.println(res);
You don't need a listener because the javadoc says:
Each showXxxDialog method blocks the caller until the user's
interaction is complete.
Here, there is no difference between close with rea cross, with key combinations, etc., as the first answer suggests. But, I guess maybe you don't need.
I have a dilema. This might sound stupid but i have no idea how to do this.
I have a password class and a main screen. My main screen has a button that when pressed pops up the password class. Here is the call to the passwordClass from an actionlistener on my main class.
public PasswordClass login(){
pressMe.setVisible(true);
String player="?";
final String playerT = player;
boolean nameCorrect = false;
final PasswordClass hold = new PasswordClass(null);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
PasswordClass.createAndShowGUI();
}
});
return hold;
}
the return statement isn't anything related to this I never used it but I had it their for testing purposes. In my password class i have a boolean that tells me if the user input matches the correct login info. i call it worked i run the password class and i had the problem that while the window is popping up my code to check if it worked is running simultaneously. This is a problem because i only want to check if it worked after the user has pressed ok. Here is the code
public void actionPerformed(ActionEvent ae)
{
else if(ae.getActionCommand().equals("Login")){
login();
}
else if(ae.getActionCommand().equals("Press Me To Continue")){
if(PasswordClass.worked){
//worked is a static variable from the PasswordClass class
}
pressMe.setVisible(false);
}
}
So whenever OK is pressed on The PasswordClass JFrame a little button pops up and asks a SECOND time for it to save. I want it to save from the first OK button. The reason i make another button is because i don't know how to stop and wait for the OK button to be pressed. My if loop to check if it worked already returns false automatically before the user presses OK. That is my problem and I am really confused on how to solve it.
Any help? If any more code is needed I will provide it but i think this is enough.
The reason i make another button is because i don't know how to stop and wait for the OK button to be pressed
Use a modal dialog of some kind, see How to Make Dialogs for more details
Conceptually, you want to display a modal dialog, which prompts the user for some information, while blocking at the point in your code that the dialog was made visible. When the dialog is dismissed (for what ever reason), you'll want to check the results from the dialog and take appropriate actions based on what the user did
There needs to be some form of synchronization between the objects (not necessarily related to the statement of that name).
If the code that wants to check the result wants to block until the result is set, you could use a CountDownLatch: the actionPerformed method calls CountDownLatch.countDown() while the other code calls CountDownLatch.await().
On the other hand, if the code checking the result does not want to block, then a simple two-boolean approach would work well. Have one boolean indicate whether the button press complete and the other to tell whether OK was the button pressed.
I want to my custom message class to behave the same way like JOptionPane in the following snippet does:
int reply = JOptionPane.showConfirmDialog(
null,
"Is the weather beautifull?",
"Question",
JOptionPane.YES_NO_OPTION
);
if (reply == JOptionPane.YES_OPTION) {
// do something in response to yes...
} else {
// do something in response to no...
}
So what I exactly want is, that I create my own message object, show it and the react on the button press done by the user in pseudo code like this:
show my question message;
wait for user button press without blocking UI thread;
do something depending on which button the user pressed;
I tried serverall things to have my message box acting like the JOptionPane with Futures, Wait/Notify etc, but I always ended up in blocking my UI thread.
What is JOptionPane's secret to do this? :)
See the docs:
A Dialog can be modal. When a modal Dialog is visible, it blocks user
input to all other windows in the program. JOptionPane creates
JDialogs that are modal. To create a non-modal Dialog, you must use
the JDialog class directly.
See modal window:
...requires users to interact with it before they can return to
operating the parent application
About the implementation, I guess that swing blocks the EDT and creates another thread for the modal dialog.
I want to pop up a dialog box that says "Saving..." and once the operation is completed, it simply disappears. While the saving is in progress, I dont want the user to be able to do anything. I also dont want an OK button.
What is the name of the Java class that allows me to do this?
I think JDialog is what you want - be sure to call setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE) on it since unlike a JFrame, its default behaviour is HIDE_ON_CLOSE.
Here's the final code I found that roughly simulated what I wanted to do:
// Create dialog box
JDialog dialog = new JDialog(new JFrame(), "Saving...");
// IMPORTANT: setLocationRelativeTo(null) is called AFTER you setSize()
// otherwise, your dialog box will not be at the center of the screen!
dialog.setSize(200,200);
dialog.setLocationRelativeTo(null);
dialog.toFront(); // raise above other java windows
dialog.setVisible(true);
// Sleep for 2 seconds
try
{
Thread.sleep(2000);
} catch (InterruptedException ex)
{
Logger.getLogger(JavaDialogBox.class.getName()).log(Level.SEVERE, null, ex);
}
// Then "close" the dialog box
dialog.dispose();
Lastly, found these 3 links to be quite helpful when writing the above code:
Center the dialog to screen
How to create JDialog
How to pause execution
You might also consider using a javax.swing.JProgressBar within your dialog so you can show progress is happening. If you have enough information during the save process to give a percentage complete you can show that, and if not you can show it as indeterminate (moving back and forth until complete). Then dispose the dialog once the save process is complete -- this would be nice user experience enhancement over showing a static text message for a fixed amount of time. Here's a tutorial with demo Java code showing an example dialog: http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html.
I think what you may want is a modal JDialog. They make it fairly easy to block user interaction for your whole application and you have some extra control.
The code snippet you posted will potentially have issues if your save operation takes longer than 2 seconds. I'd suggest calling your save() function in the place where you currently have the Thread.sleep(). That way, you know that no matter how long the save takes, the UI will be blocked.