I'm having issues figuring out how to open one window when another closes if the other window is initiated within a sub class. Here is the clumsy code I am trying to use, but it halts the setting visible of the sub classe's window. Perhaps due to it being within an action event or perhaps it is halting the main thread.
tutorial = new tutorialWindow();
this.setVisible(false);
tutorial.setLocationRelativeTo(null);
tutorial.setVisible(true);
tutorial.setCurrentUser(users.getCurrentUser());
while(tutorial.isOpen() == true ) {
}
this.setVisible(true);
users.updateUser(tutorial.getCurrentUser());
My thoughts were that it would just get stuck in the section of code until the other window closes and would then appear again when the tutorialWindow has a Open boolean set to false due to it breaking the while loop.
Im sure this is a matter of using correct threads, or perhaps the various notify methods but as of now I am not sure how to do that.
You could do it using WindowListener. In the following sample WindowAdapter implements WindowListener and I just override the public void windowClosed(final WindowEvent e) method, opening the second window.
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class TestJFrame {
public static void main(final String args[]) {
JFrame jFrame1 = new JFrame();
jFrame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jFrame1.add(new JLabel("First JFrame"));
jFrame1.pack();
final JFrame jFrame2 = new JFrame();
jFrame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jFrame2.add(new JLabel("Second JFrame"));
jFrame2.pack();
jFrame1.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(final WindowEvent e) {
jFrame2.setVisible(true);
}
});
jFrame1.setVisible(true);
}
}
Related
Update: I've decided the simplest thing to do at the moment would be to use separate JPane's and not JFrame's for the sub-menu's. I'll create them all together and set the others to invisible, and toggle that way. The menus aren't that complex that this would be too much of a problem.
I am creating a GUI that opens another JFrame window from a button click in another. I am just not sure of the right way to approach closing the main window when one of the buttons is clicked, but not closing the whole program. Neither am I sure how to get the second window visible (the line of code I tried from another example isn't working). The second frame that is brought up will give the user options to do things and will actually call another program/class to run on a button clicked within it (the result of one of the options is a long program so I think I need to run it on another thread.). After the program has finished running, the user will have the option to return to the main menu, which would close the second menu (and kill it), or exit the program (and thus kill the main menu and clean everything up). From the main menu, they will also have the option to close the program, where everything will be cleaned up. This is what I have so far:
Main GUI:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class GUIMain implements ActionListener {
GUIMain(){
JFrame jFrm = new JFrame("Data Mining Application");
jFrm.setSize(800,600);
jFrm.setLayout(new BorderLayout());
jFrm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
prepareGUI(jFrm.getContentPane());
jFrm.pack();
jFrm.setVisible(true);
}
private void prepareGUI(final Container pane){
JPanel mainPanel = new JPanel(new GridLayout(3,2,50,50));
JButton b1 = new JButton("Pre-processing");
b1.addActionListener(this);
mainPanel.add(b1);
pane.add(mainPanel,BorderLayout.CENTER);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GUIMain();
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()){
case "Pre-processing":
PreProcessingGUI window = new PreProcessingGUI();
window.getFrame.setVisible(true); //not working
break;
// etc
default:
break;
}
}
}
The class and JFrame that is called:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PreProcessingGUI implements ActionListener {
PreProcessingGUI(){
JFrame jFrm = new JFrame("Pre-processing");
jFrm.setSize(800,600);
jFrm.setLayout(new BorderLayout());
jFrm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
prepareGUI(jFrm.getContentPane());
jFrm.pack();
}
private void prepareGUI(final Container pane) {
//do stuff
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
PreProcessingGUI window = new PreProcessingGUI();
// Not surewhat to do here either as the program is not recognising the getFrame method
//window.getFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
#Override
public void actionPerformed(ActionEvent e) {
// do stuff
}
}
Well I don't work much with Swing but I can help you a bit:
When you try to show the second window in GUIMain.actionPerformed you seem to try to get the frame with a public variable having a method (getFrame).
window.getFrame.setVisible(true);
This variable doesn't exist! It is not defined anywhere. There is no magic here!
You should implement a getFrame() method in PreProcessingGUI and use it in instead of your variable.
In GUIMain.actionPerformed:
window.getFrame().setVisible(true);
In PreProcessingGUI
public class PreProcessingGUI implements ActionListener {
private JFrame jFrm; //You asssing is as you the constructor
PreProcessingGUI(){
jFrm = new JFrame("Pre-processing");
...
}
public getFrame(){
return jFrm;
}
...
In addition to that, I would say you should consider using JDialog (and optionally make it modal) instead of a JFrame.
I am pretty new in Java Swing development and I have the following problem.
I am working on an application that use Swing JDesktop framework.
So I have the following 2 classes:
1) GUI.java:
package com.test.login2;
import org.jdesktop.application.SingleFrameApplication;
public class GUI extends SingleFrameApplication {
// Estensione di JFrame:
private MainFrame mainFrame = null;
#Override
protected void startup() {
System.out.println("GUI ---> startUp()");
mainFrame = new MainFrame();
mainFrame.setVisible(true);
}
// Save session state for the component hierarchy rooted by the mainFrame:
#Override
protected void shutdown() {
System.out.println("ShutDown event intercepted by the GUI ---> sutdown() method");
}
public static void main(String[] args) {
System.out.println("GUI ---> main()");
/* Creates an instance of the specified Application subclass (SingleFrameApplication),
* sets the ApplicationContext application property, and then calls the new Application's startup method.
*/
launch(GUI.class, args);
}
}
As you can see in this class there is the main() method that simply perform this operation:
launch(GUI.class, args);
Reading on the official docimentation: launch() doc
Creates an instance of the specified Application subclass, sets the
ApplicationContext application property, and then calls the new
Application's startup method. The launch method is typically called
from the Application's main. The applicationClass constructor and startup methods run on the event dispatching thread.
So the startup() method is executed and there is created and show a new MainFrame object
2) So this is the MainFrame code (it simply extends a classic Swing JFrame):
package com.test.login2;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.test.login.LoginFrame;
import net.miginfocom.swing.MigLayout;
public class MainFrame extends JFrame {
private static final int FIXED_WIDTH = 1000;
private static final Dimension INITAL_SIZE = new Dimension(FIXED_WIDTH, 620);
private final Action actionLogOut = new AbstractAction() {
{
putValue(Action.NAME, ("LogOut"));
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("MainWindows ---> actionPerformed()");
JButton button = (JButton)e.getSource();
Window window = SwingUtilities.windowForComponent(button);
//window.setVisible(false);
//window.dispose();
}
};
public MainFrame() {
super();
setPreferredSize(INITAL_SIZE);
setResizable(false);
setTitle("My Application");
setLayout(new MigLayout("fill"));
add(new JButton(actionLogOut)); // Add the LogOut JButton to the current MainFrame object
pack();
setLocationRelativeTo(null); // Center the window
}
}
At this stage this is not very important the presence of the JButton and of the relative listener.
My problem is the following one:
As you can see in the GUI.java class is definied a shutdown() method (that is definied in the SingleFrameApplication abstact class).
shutdown() method doc
Reading the documentation:
Save session state for the component hierarchy rooted by the
mainFrame.
So the main() method of GUI.java class perform the operation that execute the startup() method that create and show the MainFrame object (and untill here it is clear)
Then I would that when I click on the X button (the button that close the JFrame), the shutdown() method (of the GUI.java class) is performed. I can't intercept this event and this is a big problem for me
Someone can help me?
Tnx
Andrea
I use a window listener something like this. You can use this right in the constructor for your MainFrame class
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
//do all your saving
System.exit(0);
}
});
do note that the System.exit(0); command will close your entire application. So this exact code shouldnt be used in a situation where you want to just close a jframe and not close the entire application.
I am sorry, for I believe that this question has been asked already, but none of the answers have actually helped me out.
I have a class with gui, it contains a JFrame with several textfields and buttons. Here's the main() I'm trying to get working:
Gui interface1 = new Gui();
interface1.setSize(200,200);
interface1.setVisible(true);
//hold main execution
//wait for the pressed button in gui
//close the jframe
//proceed with main()
call_some_functions();
I have tried setting default close operation to HIDE_ON_CLOSE but that doesn't seem to be what I want. I'm using a framework and I need main() to be alive for quite a long time.
Basically, I need jframe to hold the main() for the time of user input and updating parameters, then close itself without terminating the process and continue with main() as if nothing has happened.
Thanks in advance for any help.
Uses a JDialog instead of JFrame and make the JDialog modal, using JDialog#setModal to true
See How to use dialogs for more information
Use :
frame.setDefaultCloseOperation(frame.HIDE_ON_CLOSE);
EG:
import javax.swing.JFrame;
import javax.swing.JTextField;
public class TestFrame {
public static void main(String aa[])
{JFrame frame =new JFrame();
JTextField field=new JTextField("hello buddy..nuthin happnd");
frame.setDefaultCloseOperation(frame.HIDE_ON_CLOSE);
frame.add(field);
frame.pack();
frame.setVisible(true);
}
UPDATE AS PER YOUR NEEDS:
import javax.swing.JFrame;
import javax.swing.JTextField;
public class TestFrame {
public static void main(String aa[])
{
JFrame frame =new JFrame();
JTextField field=new JTextField("hello buddy..nuthin happnd");
frame.setDefaultCloseOperation(frame.HIDE_ON_CLOSE);
frame.add(field);
frame.pack();
frame.setVisible(true);
frame. addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentHidden(java.awt.event.ComponentEvent evt) {
formComponentHidden(evt);
}
});
}
private static void formComponentHidden(java.awt.event.ComponentEvent evt) {
somefunction();
}
public static void somefunction()
{
System.out.println("hii!! i am hidden!!");
}
}
I have a game that uses a JFrame that displays the game info. The window updates whenever a player sends a move object to the server. It works perfectly fine for any number of move objects. However once the 3nd turn starts it hits a wall and here is what happens:
The Jframe completely stops responding to left and right mouse clicks (it makes a windows ding sound when you try to click)
The JFrame still responds to mouse scrolls and keyboard inputs
The JFrame vanishes from the alt-tab program list.
NO error message or stack trace.
Using souts it appears that the code reaches all points of necessary code properly
I can't even click the "X" Window button or right-click close on the task bar
The 3rd turn object is structurally identical to previous turn objects
what on earth can cause a program to do this??
The event dispatch thread has thrown an exception. It is automatically restarted, but your program remains in the state you describe. See also How can I catch Event Dispatch Thread (EDT) exceptions and this answer.
Addendum: How uncaught exceptions are handled and Uncaught exceptions in GUI applications may be helpful. Also check for empty exception handlers.
Addendum: Here's an example.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
/** #see https://stackoverflow.com/a/9935287/230513 */
public class Fail extends JPanel {
private static final JLabel label = new JLabel(
"12345678901234567890", JLabel.CENTER);
public Fail() {
this.setLayout(new GridLayout(0, 1));
this.add(label);
this.add(new JButton(new AbstractAction("Kill me, now!") {
#Override
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();
b.setText(String.valueOf(1 / 0));
}
}));
new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
label.setText(String.valueOf(System.nanoTime()));
}
}).start();
}
private void display() {
JFrame f = new JFrame("Example");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Fail().display();
}
});
}
}
Check if your frame class do not overrides isEnabled() method.
I spent couple of hours searching for exception but the responce was pretty trivial: I have implemented interface with such method.
I just wrote this test code in my CustomUIPanel class:
public static void main(String[] args) {
final JDialog dialog = CustomUIPanel.createDialog(null,
CustomUIPanel.selectFile());
dialog.addWindowListener(new WindowAdapter() {
#Override public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
It works correctly if CustomUIPanel.main() is the program's entry point, but it makes me wonder something: what if another class called CustomUIPanel.main() for testing? Then my call to System.exit(0) is incorrect.
Is there a way to tell the Swing event dispatch thread to exit automatically if there are no top-level windows?
If not, what's the right thing for a JDialog/JFrame to do upon closing if the goal is for the program to exit when all the top level windows are closed?
You can use the setDefaultCloseOperation() method of JDialog, specifying DISPOSE_ON_CLOSE:
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
See also 12.8 Program Exit.
Addendum: Incorporating #camickr's helpful answer, this example exits when either the window is closed or the close button is pressed.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
/** #see http://stackoverflow.com/questions/5540354 */
public class DialogClose extends JDialog {
public DialogClose() {
this.setLayout(new GridLayout(0, 1));
this.add(new JLabel("Dialog close test.", JLabel.CENTER));
this.add(new JButton(new AbstractAction("Close") {
#Override
public void actionPerformed(ActionEvent e) {
DialogClose.this.setVisible(false);
DialogClose.this.dispatchEvent(new WindowEvent(
DialogClose.this, WindowEvent.WINDOW_CLOSING));
}
}));
}
private void display() {
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new DialogClose().display();
}
});
}
}
Not sure about when using a JDialog.
But when using a JFrame you should use frame.dispose(). If the frame is the last open frame then the VM will exit.
Note a dialog does not have an EXIT_ON_CLOSE option since it should not generally exit the VM.
When closing the dialog you could always get the dialogs parent frame. Then you could dispatch an event to the frame to tell it to close itself. Something like:
WindowEvent windowClosing = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
//Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowClosing);
frame.dispatchEvent(windowClosing);
Use
this.dispose();
It should work.
Well,
You could use a JFrame instead. JDialog is supposed to be used as popup of an application that runs in an JFrame to catch the users attention and to pause the main application.
If the JFrame is closed, you can call System.exit(0)
dialog has a getParent() method, which I guess, is set to null in your case here CustomUIPanel.createDialog(null,
you can use that to exit conditionally.
Here is what I would recommend : dialog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);