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.
Related
I'm wanting to get rid of the text that is already set in my JTextField when I click inside the JTextField (focus on the JTextField).
Here's my code:
if (newSerial.isFocusOwner())
{
newSerial.setText("");
}
How do I get this code to run whilst I still have my JOptionPane.showMessageDialog running?
I'm not sure if I understand exactly what you are trying to do, but based on my interpretation of your question, you have a text field that you want to update while a JOptionPage message dialog is displayed.
JOptionPane dialogs block the Swing Event Dispatch Thread (EDT), so you can't update the UI while they are being displayed, unless you do it from a different thread (but that's not great - Swing components should be updated on the EDT). If I read your question correctly, the easiest option might be to replace your JOptionPane.showMessageDialog(...) can with a JDialog that isn't a modal dialog, and therefore, won't block the EDT.
I am working on a program that is meant to keep track of footraces. The program is set up so that a right click(though this may be changed) at any time will indicate a runner has passed the finish line. This is important so that you can do things and still mark a runner as passing at any point. To finish the race and compile results, there is a button. To prevent a misclick from prematurely stopping the timer, I have a dialog that confirms while the timer is still running. This dialog is also right-clickable to mark a runner as passing. I have a method that gets the input from the dialog as a boolean.
public static boolean showDialog(Frame parent, boolean modal,String text,RacePanel r)
{
ConfirmBox c=new ConfirmBox(parent,modal,text);//this makes the dialog
for(Component comp:c.getComponents())//this adds a listener for right-click events, to record passing runners
r.addListener(comp);
c.setVisible(true);
return c.yes;//yes is the boolean that should be returned
}
I originally had the dialog modal, so that the setVisible method would wait for the dialog to close. However, this made the program ignore mouse clicks on the rest of the screen. When I set it as not modal, this showDialog method returned immediately, which was always false. I don't actually care if the dialog is modal or not.
Is there a way to get MouseEvents with a modal dialog up or make a non-modal dialog wait until input?
Thank you in advance for your advice.
Couple of solutions:
Use hot keys to react - will be faster. so F11 means stop race, with F12 to confirm it. And F9 to indicate a runner has passed the finish line
There are JNI packages for this like at http://code.google.com/p/jintellitype/
Have the user click the button and type a key or world like "end" for a sample see http://code.google.com/p/baby-smash/source/browse/src/quick/KeyBoardListen.java Do not like a dialog box as they take time to render and can increase to the timer.
If you must use a dialog box then implement your own. in that class take an instance of your main class (or interface that your controller implements) then call a method on the controller when window is acted on (yes or no pressed or window closed - default). In the window close do not close the window but just hide it. this will mean you can show it faster next time. You can also load this class on start up to make it ready in the background
If you just want mouse events can try extending JFrame and then over ride (javadoc of java.awt.Component):
protected void processMouseEvent(MouseEvent e)
Processes mouse events occurring on this component by dispatching them to any registered MouseListener objects.
This method is not called unless mouse events are enabled for this component. Mouse events are enabled when one of the following occurs:
A MouseListener object is registered via addMouseListener.
Mouse events are enabled via enableEvents.
You will need to use listeners to listen for changes in the dialog class's state. For instance a WindowListener can listen for the dialog's window closing. If you want to listen for other state changes in the dialog's classes, consider creating "bound" properties or fields by use of a PropertyChangeListener.
In the JavaDocs for Dialog(Dialog,String,modal) it says the following:
modal - if true, dialog blocks input to other app windows when shown
If I understand correctly, if I pass a true argument to the constructor of a Dialog, will it just pause all the program until the user gives some kind of input to the application using this dialog?
For example suppose that we have this function in a class and a JDialog called test.
public void function(){
/*line*/ test t = new test(null, true);
while(true){
System.out.println("print stuff");
}
}
If I call this function, it will pause, at line, then since the initial dialog is empty, if for example I close the dialog, then the while loop will be executed.
Is the phrase "the program pauses until the user gives an input using the dialog" is a somewhat correct description of what the modal variable is useful for?
Its partially correct, but.
But it isn't enough to call teh constructor, but you need to show the dialog after the constructor like this:
t.setVisible(true);
and yes, after this, the while loop does not start till the dialog isn't closed ( setVisible(false) )
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.
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.