I have a class with only static methods and one of them opens a JOptionPane error message dialogue using a JFrame object as component.
This is the class + method:
public class miscMethods
{
static JFrame errorWindow = null;
public static void ErrorPopup(String message)
{
errorWindow = new JFrame();
errorWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
errorWindow.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(errorWindow, message, "Error", JOptionPane.ERROR_MESSAGE);
errorWindow = null;
}
}
The ErrorPopup method is used inside a JavaFX controller and other places, called like this:
import static code.miscMethods.ErrorPopup;
...
ErrorPopup("This is the error message");
Problem is that the application's process won't close when I close the the program from the window's ✕ after the popup appears, because the JFrame was created and shown.
I know the JFrame is the culprit, so I added the errorWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
but it doesn't seem to do anything, since the program isn't closing.
In this question: JFrame and why stay running
The accepted answer talks about non-daemon threads, but the only thread I open is a daemon one, so unless JavaFX open one then it can't be that I believe.
So, why does the process keep running and how can I solve it?
I'm still new to Java so if I made a mistake and/or my code shows bad practices please do point them out!
Edit: I'm using a JFrame because I need the setAlwaysOnTop, since using
JOptionPane.showMessageDialog(null, message, "Error", JOptionPane.ERROR_MESSAGE); opens it not on top of the JavaFX window. If there's a better way let me know.
This:
errorWindow = null;
does nothing of use since the object is still displayed. You want this instead:
errorWindow.dispose();
Actually, even better, simply get rid of errorWindow altogether and pass null as the first parameter to the JOptionPane.
Related
I need to create a JDialog, or a JFrame class (it doesn't particularly matter so long as it's a graphical interface) - that can be used in a static command that is called from the within the actionPerformed(ActionEvent) handler and will stall that process until the user provides their selections from the user interface.
Obviously it is possible to do, because this is exactly what the dialogs JOptionPane creates does. But when I try to stall the thread until the user has completed the selection process, the interface doesn't display properly.
Here is the part of my code that I'm having trouble with:
public static Results queryForResults(String message, int propertyOne,
int propertyTwo){
MyCustomDialog mcd = new MyCustomDialog(message, propertyOne,propertyTwo);
mcd.show();
// complete() is a boolean property of my MyCustomDialog class that turns
// true when the interface has been completed.
while(!mcd.complete()){
synchronized(mcd){
try{
mcd.wait(10000L);
} catch(InterruptedException e) {
e.printStackTrace();
return null;
}
}
}
mcd.dispose();
// My MyCustomDialog class has a getResults() property which returns
// a Results object (i.e. another custom class I've made to contain
// the selections made by the user.)
return mcd.getResults();
}
The dialog outer frame appears, but it's insides don't. They just seem to be a screen capture of whatever was on the screen beneath the dialog when it appeared. I get the impression that this isn't working because I'm not supposed to be stalling the Swing Event thread with the wait command. So how do you do it?
There is no need for a while loop. A modal JDialog will cause execution to stop in your ActionLIstener until the dialog is closed.
Also, don't use the show() method to display a dialog. You should be using the setVisible(true) method.
I have a main jFrame HomePage.java and many other classes which extend javax.swing.JInternalFrame. One of the classes (JInternalFrame) is Login.java. Now I check whether the password is correct in Login.java and if the password is correct, I load success.java. Now the problem arises when I have to load the success.java page.
I have a function in the HomePage.java whose purpose is to remove all internal frames and load success.java class. The function is as follows :-
public void LogIn(){
jDesktopPane1.removeAll();
System.out.println("Pos 2");
success frame = new success();
frame.setVisible(true);
jDesktopPane1.add(frame);
setContentPane(jDesktopPane1);
try {
frame.setSelected(true);
} catch (java.beans.PropertyVetoException e) {
}
}
I call the function in the Login.java page as follows :-
System.out.println("Pos 1 ");
(new HomePage()).LogIn();
The logic does not work. But, I receive the output as
Pos 1
Pos 2
which shows that the program flow was correct. I do not get any error also. Another weird factor is that when I calthe same LogIn() function from the menu in the jFrame itself, I get the desired output. Please solve my dilemma. Any help will surely be appreciated!
This code:
System.out.println("Pos 1 ");
(new HomePage()).LogIn();
Creates a new HomePage object and calls a method on it. Oh you are certainly calling the correct method, and it's going a HomePage instance, but it's not the correct HomePage instance, not the one that's displayed, because you've created a new one.
Short term solution: get a valid reference to the displayed HomePage instance and call your method on it. You could get it by passing it into the class that needs it as a constructor or method parameter, or you could use SwingUtilities.getWindowAncestor(...).
i.e.,
Window window = SwingUtilities.getWindowAncestor(Login.this);
if (window instanceof HomePage) {
HomePage validHomePageRef = (HomePage) window;
validHomePageRef.logIn();
}
Long term solution: don't create spaghetti code with GUI objects changing behaviors of other GUI objects, but instead refactor your code a la MVC or one of its variants, so the GUI can change the model and the other GUI objects can be notified of these changes via listeners and respond if they want.
How do I pop up message in window from java console application?If I use JOptionPane, then I need to pass component which is visible.But if I want to show some warning or error from console application(which does not have any window visible), Then I cant use JOptionPane. Also I want the displayed message to be shown on top of any other application(To get the attention of user ).
Thanks in advance.
You can use
JOptionPane.showMessageDialog(null, "Message goes here");
EDIT:
I tried
import javax.swing.JOptionPane;
public class Foo{
public static void main(String a[])
{
JOptionPane.showMessageDialog(null, "Message goes here");
}
}
and the output was
so your problem could be somewhere else?
If you really need a popup, make the component argument null and it will not have a parent.
I wrote a simple application and I want show delay of it with JProgressBar Plese help me ;
I want show JProgressBar with Joptionpane , with a cancel button and it should be modal
this is my source code :
class CustomFrame extends JFrame {
private JProgressBar progressBar;
public CustomFrame() {
long start = System.currentTimeMillis();
myMethod();
this.getContentPane().setLayout(null);
this.setSize(200, 200);
//JOptionPane. ?????
this.setTitle("JFrame");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
long end = System.currentTimeMillis();
System.out.print("\nTime: " + (end - start));
}
public void myMethod(){
try {
java.io.File file = new java.io.File("i://m.txt");
BufferedReader input =
new BufferedReader(new FileReader(file));
String line;
while ((line = input.readLine()) != null) {
if (line.indexOf("CREATE KGCGI=") != -1 ){
System.out.println(line);
}
}
input.close();
}
catch(Exception e){
e.printStackTrace();
}
}
Thanks ...
There are a couple things that you will need to do to get this to work:
You should be aware of threading issues in Swing. Your GUI painting should be done on the EventDispatchThread and disk I/O should be done in a worker thread. See this tutorial, the SwingWorker JavaDoc, and SwingUtilities.invokeLater for more detail
You will then want to get the size of your file (file.length())to determine how to scope your progress bar (myProgressBar.setMaximum(length))
When you iterate over the lines in your file, you will want to trigger an update to your progress bar (myProgressBar.setValue(myProgressBar.getValue()+lineLength)).
A couple points by way of critique:
your constructor shouldn't go off and do all of your work (ie load your file and pop up an option pane with the ability to cancel. the constructor should just do the work needed to create the object. you might want to consider having your constructor create your class, and then have the work that needs to be done to be called separately, or within something like an init() method.
It isn't clear what you are doing with the JFrame as superclass. JOptionPane is a class that will pop up a very basic modal dialog with some text, maybe an icon or input field. It isnt a panel that is embedded in a dialog.
As JOptionPane is a very basic construct for creating a basic message dialog, it might be easier to use a JDialog, which can also be made modal. JDialog will allow you to add buttons as you please, where as a standalone JOptionPane will require you to use Yes/No, or Yes/No/Cancel or OK/Cancel etc.
If you still want to use JOptionPane, and only show a cancel button, you can instantiate a JOptionPane (as opposed to using the utility show* methods), with the progressbar as the message, and the JOptionPane.CANCEL_OPTION as the optionType param. You will still need to put this into a JDialog to make it visible. See this tutorial for more details:
JOptionPane (constructor)
Creates a JOptionPane with the specified buttons, icons, message, title, and so on. You must then add the option pane to a JDialog, register a property-change listener on the option pane, and show the dialog. See Stopping Automatic Dialog Closing for details.
I have problem currently for my swing reminder application, which able to minimize to tray on close. My problem here is, I need JOptionPane dialog to pop up on time according to what I set, but problem here is, when I minimize it, the dialog will pop up, but not in the top of windows when other application like explorer, firefox is running, anyone know how to pop up the dialog box on top of windows no matter what application is running?
Create an empty respectively dummy JFrame, set it always on top and use it as the component for the JOptionPane instead of null. So the JOptionPane remains always on top over all other windows of an application. You can also determine where the JOptionPane appears on screen with the location of the dummy JFrame.
JFrame frmOpt; //dummy JFrame
private void question() {
if (frmOpt == null) {
frmOpt = new JFrame();
}
frmOpt.setVisible(true);
frmOpt.setLocation(100, 100);
frmOpt.setAlwaysOnTop(true);
String[] options = {"delete", "hide", "break"};
int response = JOptionPane.showOptionDialog(frmOpt, msg, title, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, "delete");
if (response == JOptionPane.YES_OPTION) {
removeRow();
}
frmOpt.dispose();
}
Old post, but I was struggling with this.
My problem was more with Javafx allowing the JOptionPane to go behind the current Java window.
Therefore I used the following which does what the original poster asked by putting the JOptionPane in front of all windows; even JAVAFX.
Firstly the old JOptionPane:
JOptionPane.showMessageDialog(null, "Here I am");
Now an JOptionPane that stays in front:
final JDialog dialog = new JDialog();
dialog.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(dialog, "Here I am");
And for fun here is everything in one long line:
JOptionPane.showMessageDialog(
((Supplier<JDialog>) () -> {final JDialog dialog = new JDialog(); dialog.setAlwaysOnTop(true); return dialog;}).get()
, "Here I am");
You can make a static method some where that will return the JDialog for you and then just call it in the JOptionPane to clean up your code a bit.
Are you using one of the canned JOptionPanes? (Like JOptionPane.showCOnfirmDialog(...))
You may want to look at extending JDialog and making your own dialog panel, and then calling myDialog.setAlwaysOnTop(true);
Windows is blocking this operation since XP.
The scenario before was like:
Your a tiping in some text in an editor and not recognize that another dialog is coming to front when you are tipping the text. The coming dialog gets the focus and you are tiping in the new dialog. Maybe you click enter after you are ready and do this in the wrong dialog, which is asking whether you realy want to delet your hard disk ;)
The come to front call in java is only working for java windows.
The possibibilty to notify the user of a new window is to implement a Frame, which will highlighted/flashing in the windows task bar.
Correction the post above..
I have resolve my problem as below:
this.setVisible(true); // show main frame
MyDialog dialog = New MyDialog(this, true); // show my custom dialog
dialog.setVisible(true);
this.setVisible(false);
it works fine for me :)
You might think about using a JFrame instead. It may give you a little more flexibility.
If you are using a JFrame and you want it to popup on top of the other windows use:
myFrame.setVisible(true);
myFrame.setState(Frame.NORMAL);
The setState will show the window to the user if it was in minimized state previously.