Is there a possibility to prevent a JOptionPane dialog from blocking the interaction with the rest of the program, especially child JFrames? In my GUI, I launch a JFrame and want a message dialog to pop up after the child is closed to remind the user of something, but they launch parallel and the reminder blocks the child frame from being used.
Like here:
popupObjMan newPopup1 = new popupObjMan(gatewayAbstract, gatewayAbstractID);
JOptionPane.showInternalMessageDialog(this, "REMINDER: DO REFRESH");
I've tried to set the popup always on top, but this doesn't quite do the job.
I have no problem with them launching parallel (I'd even prefer it), but I could not work my head around it yet.
I just started Java programming ,so sorry in case that'd be something obvious.
A JOptionPane normally need to be modal. It shows something important and waits till the user answers with whatever option you give him (e.g. ok-button, yes/no-buttons, ...)
But there are several ways to reach your target.
(a)
Normally a JOptionPane creates a modal window.
You need a modeless window which does not block other windows.
https://docs.oracle.com/javase/tutorial/uiswing/misc/modality.html
(b)
You can start different threads to work for your different windows. They can have windows which are shown whenever the responsible thread commands them to. This is a bit difficult and can lead to memory-troubles.
(c)
You can write your own message-panels (e.g. notificaton) which are shown when and how long you like.
Bigger projects use different of these ways to achieve their goals.
A JOptionPane is a component, just like a JPanel. As a component it can be added to any other panel.
The JOptionPane API provides static methods to create a show the JOptionPane on a modal JDialog by default. You can't change this behaviour.
However, you can manually add the JOptionPane to a non-modal JDialog that you create. This is extra work as you now need to handle the closing of the dialog and processing the clicked button.
If you really want to do this then read the JOptionPane API. There is a section on Direct Use which demonstrates the basic code needed to add the JOptionPane to a JDialog.
Related
I need my JFrame to freeze/ become inaccessible, similar to how it would with a model JDialog or setEnabled(false).
In most cases I would use JDialog but in this instance I am running a dialog through a C library.
Going down the setEnabled(false) line also doesn't work because it, on setEnabled(true), will send the window to the back. And even using toFront() will cause the window to go to the back for a split second then come to the front again.
Is there a better way to go about doing this, or an I stuck with the slight imperfection of the window flickering.
Also if you are familiar with the library I am using LWJGL's NativeFileDialog wrapper.
I have found a pretty good solution to this issue, originally answered as part of this post. It takes the idea of using a JDialog, but instead of displaying some message it is completely transparent, invisible to the user.
final JDialog modalBlocker = new JDialog();
modalBlocker.setModal(true);
modalBlocker.setUndecorated(true);
modalBlocker.setOpacity(0.0f);
modalBlocker.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
Then we can simply display our modal and show our file dialog
// Using invoke later we show our dialog after our frame has been blocked
// by setVisible(true)
SwingUtilities.invokeLater(()->{
// show dialog
});
modalBlocker.setVisible(true);
modalBlocker.dispose(); // immediately release resources
Then we can call modalBlocker.setVisible(false) at any point to stop the modality effect on our frame.
Again this is the solution that worked for me, it is not mine. The code was written to integrate JavaFX with Swing by Sergei Tachenov, all credit goes to him!
I have a fairly simple Java Application I created with JFrames. There is more than one JFrame in my program. I have a menu launching at the beginning of the program. After going through the menu, I have the menu JFrame disposed.
The main JFrame has a menu button that should launch the exact same menu at a later time. However, when you launch the menu from inside of the ActionListener (when you press the menu button), the JFrame doesn't launch properly. None of the components show up and colors are off.
However, when the menu is launched from outside of the ActionListener, the JFrame shows up perfectly. I have tried multiple methods to fix this, but none of them have worked.
My full program code is available by clicking here.
The main class is "LetsMultiply5.java". This class also sets up the ActionListener.
The JFrame causing the problem is "MenuWindow.java".
"LetsMultiply5.java" calls the "Booter.java" class, which then calls the "MenuWindow.java".
"MainWindow.java" is the JFrame that has the "Menu" button.
For proof, "SpeedModer.java" calls the menu window after it has been disposed, and works.
================================EDIT================================
Also, I'd like to let you know that I realize my code is a little bit messy. I am not sure how else to write the code for this program.
I am forced to use Thread.sleep(x); because the Swing timers aren't what I am looking for. The Swing timers activate an ActionListener when the timer goes off. I need a system that will wait a second before continuing on with the code.
I realize that the while (repeater==0) loop with ActionListeners inside of it seems crazy, but that was the only way I could get it to work. If I put a single ActionListener and just had the while loop do no code inside of it, nothing happens when I press the button.
I would, as MadProgrammer mentioned:
Advice: Scrap your current approach and start again.
However, the way that I have my program currently coded is the only way that I know how to get what I need to do done. I read the tutorials, but still don't know how to improve the code in the way that you told me.
I thank everyone for trying to tell me to improve my bad "Java grammar", but as far as I am concerned, I am not going to continue this program for the next 20 years and make my millions off of it.
I have looked at the Swing timers before and I understand the whole new Timer(speed, this); concept, but I don't understand how this would make my code any better.
If anyone would like to show me how to fix my ActionListeners or Thread.sleep(x); lines, please tell me. Thank you.
You're blocking the Event Dispatching Thread with Thread.sleep(3000); - Don't do this, it will prevent the UI from been painted
See Concurrency in Swing for more details about the problem and How to use Swing Timers for a possible solution
You may also want to consider having a look at The Use of Multiple JFrames, Good/Bad Practice? and consider using CardLayout or JTabbedPane
If you need to block the user temporarily (to display a error message or gather important details), consider using a modal JDialog. See How to Make Dialogs for more details
In my program it opens a window if an action is happened. After I have filled out information in this window, and entered a button, the window dispose().
The window is picked up in a program outside my main program, but when I close this window, my main program stops. How can I prevent this from happening?
Thanks for your help!
You can set the defalaultCloseOperation property of the second frame to DO_NOTHING_ON_CLOSE or DISPOSE_ON_CLOSE
Don't even use two frames. Use a modal JDialog instead for a secondary frame. See more at How to Use Dialogs. Read more about Modality. And for a good read, see The Use of Multiple JFrames, Good/Bad Practice?
Forget about number 1. and go straight to 2.
If using JFrame or extending it you can use setDefaultCloseOperation() method like:
frame.setDefaultCloseOperation(HIDE_ON_CLOSE);
// or
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
The dispose command is from the AWT Bundle, and this may cause problems, as you are attempting to "close" a swing window with an AWT command.
You can close the window with this command:
windowName.setVisable(false);
windowName is the name of the object representing the window. If you are extending a class, and have no object, you can use this
More Information on the Dispose Method:
"In general java.awt.Window.dispose() is used on a GUI component that is
a subclass of Window, in order for that specific GUI Window object (and
its children) to properly release and destroy native UI resources (such
as the screen). Garbage collection (and the eventual exiting of the
entire VM) may happen as a result of dispose(), but is not directly
connected with the dispose() call itself." From: https://www.java.net/node/684412
windowName.setVisable(false);
doesn't seems to be a good choice. What if user want to exit the program?
check this question - How to hide a JFrame in system tray of taskbar
This is a crosspost to the thread in Javaranch (includes some images): http://www.coderanch.com/t/567472/GUI/java/Optimal-solution-creating-multiple-dialog
I'm trying to develop a simple swing desktop application where I imagine alot of different dialog's jumping around to fetch user input. Would need to present labels, textfields, passwordfields, combobxes, checkboxes etc in various dialog windows.
For example: creating the database firsthand, creating the first admin account, adding users, changing user accounts etc.
I have an understanding that JOptionPane is used to create simple quick & easy modal dialog's. I would really like to know why one would choose one over another in this case. Which one is more preferable to use: JOptionPane vs. JDialog
Also I could use some pointers how one should appropriately design and implement this.
Thank you.
Here's a statement I found on the Java website that says one key point about the difference between the two.
How to make Dialogs
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.
So it sounds like you would use JOptionPane if you want a user to have to make a choice and close the box before returning to the main screen. If you use a JDialog box, then they can just click around it and get back to the main screen without making a choice. For example, say you wanted to make a user choose the number of results before clicking submit, you wouldn't want them to be able to click around that window and click submit. You would use JOptionPane to force them to select a value first before going back to submit.
Check out http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html it pretty much has everything you would need.
As i understand it, JOptionPane is great for what it can do, but you can't really change the functionality beyond that (not easily). JDialog is better to inherit from if you want to create your own custom Dialogs.
I have this main JFrame (call it DrinkChooser) that shows another complex confirmation JFrame (call it ConfirmWin).
The ConfirmWin has only two JButtons, confirm and cancel.
I want to do this:
(in DrinkChooser, assume drinksChoosen is a Drink[])
public void handleAction(){
int choice = ConfirmWin.showDrinkConfirmation(drinksChoosen);
if(choice == ConfirmWin.CONFIRM)
//Handle confirmation.
else
//handle cancel, do nothing.
}
I want to achieve an effect that is as close as possible to the "JOptionPane effect", which is that the original DrinkChooser gets suspended, and the ConfirmWin returns the choice of the user.
Thanks.
Have a look at the trail How to Make Dialogs.
A Dialog window is an independent subwindow meant to carry temporary notice apart from the main Swing Application Window. Most Dialogs present an error message or warning to a user, but Dialogs can present images, directory trees, or just about anything compatible with the main Swing Application that manages them.
For convenience, several Swing component classes can directly instantiate and display dialogs. To create simple, standard dialogs, you use the JOptionPane class.
Here is a possibly related question:
Java - How to create a custom dialog box?
Don't forget that the value argument of all JOptionPane.showXXXX methods can be a JComponent. If you pass a component (in your example it might be a JList with a custom renderer), it will be embedded within the dialog and can be used to customize the appearance.