5

This code does work in every way but now it does not close fully, it seems to hang as I hit the "X" on the window. After I hit close, if I minimize the screen and then maximize it back up it just black. The only way I can get it to close fully is to exit Eclipse, my IDE.

Prior to this I had a different look and feel. I stole some code for the GUI, I made it in netbeans to make it look better than I could do by hand. So I would figure it has to do with the "nimbus" look and feel, but maybe I am not closing other objects properly an it is now a problem?

static CLUtilCompact app = null; // this
static AuxPPanel aux = null; // JPanel
static StatusPanel stat = null; // JPanel
static UserActPanel user = null; // JPanel
static InputPanel input = null; // JPanel
static Automator auto = null;   
        //public class Automator extends Thread 
       //   implements NativeMouseInputListener, NativeKeyListener  

public CLUtilCompact() 
{
    aux = new AuxPPanel();
    stat = new StatusPanel();
    user = new UserActPanel();
    auto = new Automator();
    input = new InputPanel();
    GlobalScreen.getInstance().addNativeKeyListener(auto);
    GlobalScreen.getInstance().addNativeMouseListener(auto);
    GlobalScreen.getInstance().addNativeMouseMotionListener(auto);
    auto.start();
}

public static void main(String[] args) 
{
    // Create the App, and panels
    app = new CLUtilCompact();
    // Let the panels have access to app now
    aux.setApp(app);
    stat.setApp(app);
    user.setApp(app);
    auto.setApp(app);
    app.updateOutput("Started");
    app.updateStatus("Started");
    input.setApp(app);

    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(CLUtilCompact.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(CLUtilCompact.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(CLUtilCompact.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(CLUtilCompact.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            app.setDefaultCloseOperation(EXIT_ON_CLOSE);
            app.setAlwaysOnTop(true);
            app.setVisible(true);
        }
    });
}

Class Automator run and close

public void run()
{
    try // to make the Global hook
    {
        GlobalScreen.registerNativeHook();
    }
    catch (NativeHookException ex){theApp.updateOutput("No Global Keyboard or Mouse Hook");return;}
    try // to create a robot (can simulate user input such as mouse and keyboard input)
    {
        rob = new Robot();
    } 
    catch (AWTException e1) {theApp.updateOutput("The Robot could not be created");return;}

    while(true) {}
}

public void OnClose()
{
    GlobalScreen.unregisterNativeHook();
}

EDIT: The little red box in eclipse closes it, but still on its own it does not.

  • What about when you press the `X` in the Eclipse console? – CodyBugstein May 13 '13 at 23:02
  • Not sure what you mean, do you literally mean when I close Eclipse? It all shuts down the program closes fully. The issue is when I have it as a runnable .jar, there is no way to close it. It doesn't even show up in task manager. –  May 13 '13 at 23:07
  • I mean [THIS](http://imgur.com/7QWidY2) little `X` – CodyBugstein May 13 '13 at 23:10
  • 2
    You've got a non-daemon thread running that is preventing Swing from exiting. What library are you using for your global listeners? I would look into that. – Hovercraft Full Of Eels May 13 '13 at 23:13
  • @Eels JNativehook it from google code, first result on google.` ` @Imray question edited at bottom –  May 13 '13 at 23:17
  • I'd say you need to unhook you native code... – MadProgrammer May 14 '13 at 00:35
  • I do don't I?, it is in the OnClose method of `Automator`. I "unregister" the global hook. Is this not what you mean? –  May 14 '13 at 12:55
  • You do have a listener that is invoking that OnClose method, otherwise it's just doing nothing. Additionally, that run() method has an infinite loop preventing app termination unless you mark the the thread that it belongs to as a daemon thread using `isDaemon(true)` on the thread itself – Anya Shenanigans May 16 '13 at 14:36
  • Could you put it in an answer with a little bit of code? I figured I was getting my OnClose called, so `CLUtilCompact` should `implement ActionListener` and listen for a `OnClose` event? Also, So in my EventQueue have something like `this.isDaemon(true)` ? –  May 16 '13 at 14:42
  • You should read the javadocs. You had a problem with a window not closing. If you do not know that is a java.awt.Frame or javax.swing.JFrame then you need a book or tutorial. if you know its a frame then head over to the javadocs JFrame has some notion of how to respond when the user attempts to close the window ... invoke the method setDefaultCloseOperation(int). http://docs.oracle.com/javase/6/docs/api/javax/swing/JFrame.html – tgkprog May 21 '13 at 17:44
  • Try adding this line to the `onClose` method `if (GlobalScreen.isNativeHookRegistered()) { GlobalScreen.unloadNativeLibrary(); }` – Extreme Coders May 23 '13 at 03:02
  • Also follow the general rules of mixing `JNativeHook` with `Swing` -- linked **[here](https://code.google.com/p/jnativehook/wiki/examples#Working_with_Swing)** – Extreme Coders May 23 '13 at 03:08

6 Answers6

8

Set default close action to "DISPOSE_ON_CLOSE" instead of EXIT_ON_CLOSE (general tip)

Hovercraft Full Of Eels comment is quite useful. If you have any undisposed windows or non-daemon threads, your application will not terminate

Check for all active frames.. use Frame.getFrames() If all Windows/Frames are disposed of, then debug to check for any non-daemon threads that are still running

One cruel but effective solution would be System.exit(0)

Class should implement WindowListener

// Use this method
public void windowClosed(WindowEvent e){
    System.exit(0);
}
Mady
  • 653
  • 4
  • 11
  • I'm a cruel person, but elegant sometimes. So from Eels comment and the other ones, it says I need to mark something as a Daemon with `isDaemon(true)`? Or is it that once I actually do call my OnClose method my Daemon process (global keyboard and mouse listeners) will be closed and my program will die and not be in the zombie mode? –  May 17 '13 at 16:15
  • i dont think you need to bother about the threads, the process will be claened up. if you have open files might be a good idea to flush and close them, other than that System.exit(0) is fine – tgkprog May 21 '13 at 17:46
  • see http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#exit%28int%29 – tgkprog May 21 '13 at 17:48
2

I'm going to venture a guess that this line of code

while(true) {}

could be your culprit.

ryvantage
  • 13,064
  • 15
  • 63
  • 112
1

Be sure to set the default close action to DISPOSE_ON_CLOSE instead of EXIT_ON_CLOSE

frameName.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

For more information: Basic Java Swing, how to exit and dispose of your application/JFrame

Community
  • 1
  • 1
Hexum2600
  • 149
  • 6
0
 http://stackoverflow.com/questions/2352727/closing-jframe-with-button-click

   JButton button = new JButton("exit");
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
   frame.setVisible(false);
            frame.dispose();

        }
0

Speculative. Having static (swing) classes could hold onto things, for Nimbus. As using static so often also is not so nice looking, try doing away with them, as fields of the JFrame app.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
-1

I had the same issue I just added this code in the end and when ever it comes up black and doesnt close I just type 1 and it gets fixed for the next time.

Scanner scan=new Scanner(System.in);
int exit=scan.nextInt();
if (exit==1) System.exit(0);