Question

Suppose I have a set of codes to display a JFrame, a JPanel, and a JLabel. This works fine if I run it as a script file. It just shows a tiny window with a label that says "A label" exactly like you would expect:

frame = javax.swing.JFrame('Test');
panel = javax.swing.JPanel();
label = javax.swing.JLabel('A label');
panel.add(label);
frame.add(panel);
frame.setDefaultCloseOperation(javax.swing.JFrame.HIDE_ON_CLOSE);
frame.pack();
frame.setVisible(true);

The problem comes when I compile this as an exe file with the deploytool. It will compile and I can run the program, but the frame will show up for about 3 seconds or so then disappear. If I run from inside Matlab with !main.exe, there is no error message when the window disappears (I don't want to say it crashes because there is no error message). Neither is there one if I run the executable from the Windows command prompt (same results -- shows for a few seconds and then crashes).

Any ideas what is going on here? I can compile other files just fine. Is the problem because I included the javax.swing elements?

Many thanks for your help.

UPDATE

This feels like a really cheap hack, but having a while loop that pauses Matlab as long as the JFrame is open does the trick. So now the question is, is there a better way to do this?

Was it helpful?

Solution

The problem is probably that your main M-code function finishes executing, and since there are no figures up, Matlab decides to exit. In a Java Swing program, what would happen is that things would keep going until all the Swing windows are closed or you explicitly terminate the program. Since this is a Matlab program, the layer that's "in control" is the Matlab handle graphics layer, so you need to either have the main function executing or a figure up. (In interactive Matlab, it'll keep running as long as you have the IDE up, but there's no IDE in a compiled Matlab program, so when its work is done, it exits.)

The "Right Thing" to do from MathWorks' perspective is to probably buy the Matlab Builder JA toolbox, build the Matlab part of your program in to a Java library, include that in a main program which you write in Java. That way the Java layer is "in control" of the main execution sequence, and the "stay running as long as there are Java windows open" logic you're expecting will be in effect.

If you want to hack this to make it work in your current program structure, your invisible figure window might be a good one. Though you will need to make it Visible to have it work; invisible figures don't count for keeping a Matlab GUI running. You may be able to hide it from the user by changing its position to move it entirely off the user's screen.

Then you need to terminate the program somehow. Some part of your code is going to know when the program should end. That sounds like it's the Java part of your code. From there, you could just call java.lang.System.exit(). If you need to do Matlab-layer stuff, you could exit from M-code by communicate the "it's time to exit" back to your Matlab code, which could then call exit() or close that figure. You could do this by setting a public class variable in one of your Java classes, and have a Matlab timer object that checked that variable every 500 milliseconds or so.

If the condition that ends the program is that all your Java Swing windows get closed, that's a little tougher. Because the Matlab figure window itself is a Java AWT or Swing window, so as long as that's open you're not getting down to zero windows. What you could do is have that Matlab timer, instead of looking for a class variable, check the list of open Java windows and see if the Matlab figure is the only one left, and if so, close it or exit explicitly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top