4

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?

Will
  • 1,078
  • 1
  • 8
  • 8
  • Have you checked if any errors are being logged to the [Java console](http://www.java.com/en/download/help/javaconsole.xml)? Or if you're getting crash dumps – wherever those would show up on Windows. – horchler Feb 20 '14 at 01:49
  • 1
    What happens if you do something like `pause(30)` at the end, or also create a regular Matlab figure? I'm not familiar with the compiler/deploytool, but it strikes me that the Matlab side of things may be reaching the end of the program, tearing down the JVM and exiting because it simply doesn't realise it has anything to wait for (since you've gone behind its back and created Swing objects directly). – Notlikethat Feb 20 '14 at 01:59
  • When the GUI closes, is the exe still running? I think you deployed m-function finised, thus the JVM is closed, while via matlab GUI the JVM remains open. – Daniel Feb 20 '14 at 02:04
  • @Notlikethat that's on the right track. If I pause for X number of seconds, the program will run for X and then stop after that. If I create a Matlab figure window, the program runs until I close the window. I thought of making an invisible figure to just keep it running but then there is no way to terminate the executable, is there? – Will Feb 20 '14 at 12:43
  • That cheap hack of `pause` in a loop will work, but it will tie up the main Matlab execution loop. It brings up the question of why you are building an all-Swing GUI from Matlab in the first place. What's the end goal of the program you're building here? – Andrew Janke Mar 24 '14 at 16:30
  • I started by using the Matlab GUIDE. But I found it to be hard to customize and thought it would be easier to do in Swing, then import into Matlab. The whole thing feels cheap put together like it is, but it works for now. I am sure there is a better way to do it, I just don't know what it is. – Will Mar 26 '14 at 13:26
  • 1
    Have a look at the "GUI Layout Toolbox" on File Exchange. It'll give you more sophisticated Swing-like customization abilities while still coding at the M-code Handle Graphics level. (That'll be even more important once you start working with lots of callbacks.) http://blogs.mathworks.com/pick/2010/06/18/gui-layout-part-7/ – Andrew Janke Mar 27 '14 at 06:51

1 Answers1

2

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.

Andrew Janke
  • 23,508
  • 5
  • 56
  • 85