How to load Swing and AWT components in advance? - java

Similar to this question I have the problem that the first JFrame I open takes way longer than ones afterward. I have an application that opens JFrames based on user input in the console. Because of this, I would have time to load the JFrame stuff in advance in a separate thread. What function of Swing or AWT should I call for this initialization to be executed (the other StackOverflow answer refers to some sun package which is no longer in the JRE/JDK)?

Swing: Just call everything you normally need to setup the GUI but don't invoke setVisible(true) on the JFrame until you want to display it. Note that the GUI should be created on the EDT, i.e. using SwingUtilities.invokeLater.

Related

Prevent JOption from blocking child JFrame

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.

When closing the JFrame main method execution should not be stopped [duplicate]

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

When I dispose and reopen a JFrame, it doesn't show anything

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

Close window - but don't stop program - JAVA

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

Java: second window is blank

I have a weird issue... I'm a relatively new "enthusiast" Java programmer (I used to make my living hacking Perl, in a previous career), working on my first semi-real application. "Main-Class" is the MyApp class, which creates a UserInputDialog instance.
UserInputDialog is a class I wrote that extends JFrame, implements ActionListener and KeyListener, uses FlowLayout, and presents the user with a JLabel, JTextField, and Cancel/OK JButtons. When the JTextField generates a KeyEvent where keyReleased() == KeyEvent.VK_ENTER, or when the "OK" JButton generates an ActionEvent, UserInputDialog does some input validation, calls setVisible(false), and then calls MyApp.doSomething( JTextFieldInstance.getText() ).
That all works perfectly. But now I'm trying to add a progress window to MyApp, as doSomething() can occasionally take a fair amount of time to complete.
I created the ProgressWindow class, which extends JFrame, uses BorderLayout, and tosses a JProgressBar in .NORTH and a JScrollPane (wrapping a JTextArea) in .CENTER. ProgressWindow works perfectly when instantiated from ProgressWindowTester and fed test data. It also works fine if I copy-and-paste the test for loops from ProgressWindowTester into MyApp and don't have MyApp instantiate UserInputDialog (i.e., there's nothing inherent in MyApp that's causing this behavior; it seems to be some sort of interaction I'm not understanding, between UserInputDialog and ProgressWindow).
But when I try to use ProgressWindow in MyApp as intended, i.e., ProgressWindow setVisible(true), I get a blank Swing window (of the proper size, and with the title bar set properly). The JProgressBar and JScrollPane / JTextArea components don't appear. The ProgressWindow methods are being called by MyApp properly (System.err.println() messages show proper interaction), everything appears to be working fine, just, the components that should be visible in ProgressWindow ... aren't.
I can post code snippets, but it's kind of convoluted, and I'm probably just missing something obvious...
I'm familiar with the concept of separating UI and business logic generally (e.g., I used HTML::Template and Class::DBI and CGI::Application when building Perl applications), but I'm not sure I'm "doing it right" in Java...
Thanks in advance!
Oh, I get exactly the same behavior on the two environments I've tried the code in: javac 1.6.0_29 on Mac OS X 10.6.8 ("Snow Leopard"); and javac 1.7.0_02[1] on the Fedora 15 Linux distribution, kernel 2.6.31.10-3, LXDE desktop environment.
[1] Downloaded directly from oracle.com; I;m not using OpenJDK (I know JDK 7 is based on OpenJDK) or gcj or anything like that
You've got a concurrency in Swing issue where you're trying to do a long running process on the Swing event thread or EDT. Since this thread is responsible for drawing all components and for processing user input, if it is tied down by your long-running process, your GUI will be effectively frozen until the process is complete. The key is to use a background thread such as that provided by a SwingWorker for long-running processes, so the event thread doesn't get locked. Check out Concurrency in Swing for more information on this. Also check out the JProgressBar Tutorial for other insights on how to use progress bars with background threads.
Also, you'll not want to use a JFrame where a dialog, such as a JDialog, is much more appropriate. Also, you'll want to avoid use of KeyListeners with Swing. Much better would be to simply add an ActionListener to your JTextField since its default behavior is to respond to presses of the key.
Oh, and welcome to StackOverflow.com!

Categories