Placing Swing Window on top of JME window

I have an application that uses swing JFileChooser to open a file and read it in JME and visualize spatials on the scene.

code is below:

[java]
String fileName = VisitRecording.getLastVisitedDirectory();
JFileChooser fileChooser = null;
if (fileName != null) {
fileChooser = new JFileChooser(fileName);
} else {
fileChooser = new JFileChooser(".");
}

		// do stuff

[/java]

my problem is that the swing window almost always appears behind the JME window making the uneducated user wait for that filechooser to popup for a while before realizing that it’s actualy behind the JME.

any way I could add something to automatically always place the jframe window on top?

thanks in advance

Does swing allow for modal windows?

EDIT: Apparently, it would have to be displayed in a JDialog to make it modal. /shrug Perhaps this helps?

What doe the code look like where you open the dialog? What parent are you passing?

Without some tricks, JFileChooser is tricky because it keeps its real Dialog window internally. If you have a parent then you can bring it to the front (on the swing thread) and hope for the best.

If you aren’t already, you will want to only open the dialog on the swing thread.

@t0neg0d I do have it in a dialog and tried all possible ModalityTypes with no luck

@pspeed Check below. I am invoking on a separate thread the code needed to visualize spatials after loading the file.

Here’s my code:

[java]
public File loadImages() {

	JDialog dialog = new JDialog();
	dialog.setModalityType(ModalityType.APPLICATION_MODAL);

	if (traceFileName != null) {
		File file = new File(traceFileName);
		assert (file.exists());
		return file;
	} else {
		String fileName = VisitRecording.getLastVisitedDirectory();
		JFileChooser chooser;
		if (fileName == null)
			chooser = new JFileChooser(new File("."));
		else
			chooser = new JFileChooser(new File(fileName));

		AnimationFileFilter filter = new AnimationFileFilter();
		chooser.setFileFilter(filter);

		int returnVal = chooser.showDialog(dialog, "Select");
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = chooser.getSelectedFile(); 

			if (FileUtility.getFileExtension(file.getName()).equals(".images")) {

				/* put this on a non rendering thread */
				EventQueue.invokeLater(new Runnable() { 
					public void run() { 
						// do stuff here....../
					} 
				}); 
			}

			VisitRecording.saveLastVisitedDirectory(file.getParent());
			return file;
		} else {
			return null;
		}
	}

}[/java]

First, is all of that code being run on the swing thread. If not then it absolutely must be. No doubts about it. You will have major problems getting this to work right if you aren’t running your swing code on the swing thread in this case.

Second, modality has nothing to do with it because the window hierarchies between Swing/AWT and the OpenGL window are completely separate. You will be model on the Swing side which won’t matter because all of your swing windows are behind the OpenGL window.

The best you can do would be to try dialog.toFront(). If you are running on the swing thread, it should work ok. Though you may still want to put it (perhaps a second time) in SwingUtilities.invokeLater() just to make sure it happens after all of the current events are processed. In my experience, this will work most of the time though I’ve seen it still fail 1 out of 100 times or so (without the second toFront() call).

I did that (wasn’t on the swing thread before) but it still doesn’t work :S

[java]
public void loadImages() {
/* put this on a swing thread */
SwingUtilities.invokeLater(new Runnable() {
public void run() {

	JDialog dialog = new JDialog();
	dialog.setModalityType(ModalityType.APPLICATION_MODAL);
	  
	if (traceFileName != null) {
		 traceFile = new File(traceFileName);

	} else {
		String fileName = VisitRecording.getLastVisitedDirectory();
		JFileChooser chooser;
		if (fileName == null)
			chooser = new JFileChooser(new File("."));
		else
			chooser = new JFileChooser(new File(fileName));

		AnimationFileFilter filter = new AnimationFileFilter();
		chooser.setFileFilter(filter);

		dialog.toFront(); 
		
		int returnVal = chooser.showDialog(dialog, "Select");
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			 traceFile = chooser.getSelectedFile(); 

			if (FileUtility.getFileExtension(traceFile.getName()).equals(".images")) {

				/* put this on a non rendering thread */
				EventQueue.invokeLater(new Runnable() { 
					public void run() { 
						// DO STUFF HERE that calls the JME window
					} 
				}); 
			}

			VisitRecording.saveLastVisitedDirectory(traceFile.getParent());
		}
	}
	
		} 
		}); [/java]

Well, that’s what worked for me.

You could try another invokeLater() for the toFront() and/or setAlwaysOnTop(true).

I had to deal with this when clicking a button to open the file dialog from MonkeyScript. Calling toFront() on the file chooser’s parent was all I needed to do, though.

:S tried both still appears in the back

giving this a bump in case anyone had this issue :S

@homsi: I do it that way:

	SwingUtilities.invokeLater(new Runnable() {

		public void run() {
			AssemblerSideBar bar = new AssemblerSideBar(assembler);

// bar.setInputHandler(input);
JFrame frame = new JFrame();
frame.getContentPane().add(bar);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
My sidebar is created during simpleInitApp(), and if I make the view big enough it is created in front of the jme window

can you elaborate more? what do u mean create during simpleInitApp()? I want this to be called only when a user clicks on the file chooser button. Not sure I understood your point. Plus what the bar ur using?

SimpleApplication.simpleInitApp()

this is during initialization of the application.

The sidebar is a JPanel

public class AssemblerSideBar extends javax.swing.JPanel {

this also works on my side also when moving the call to be triggered from an input mapping.

mifth is using a filechooser in his SWE by doing this:

    mFileCm.setDialogType(JFileChooser.OPEN_DIALOG);
    mFileCm.setDialogTitle("Load Scene");
    mFileCm.setApproveButtonToolTipText("Open");
    mFileCm.setApproveButtonText("Open");
    mFileCm.setFileFilter(modFilter);
    int returnVal = mFileCm.showOpenDialog(null);

without any dialog stuff around it, sure you need the dialog, cause I do not see it is used (anything added to it…)
because I am in thee mood: http://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html

@ghoust said: SimpleApplication.simpleInitApp()

this is during initialization of the application.

The sidebar is a JPanel

public class AssemblerSideBar extends javax.swing.JPanel {

this also works on my side also when moving the call to be triggered from an input mapping.

mifth is using a filechooser in his SWE by doing this:

    mFileCm.setDialogType(JFileChooser.OPEN_DIALOG);
    mFileCm.setDialogTitle("Load Scene");
    mFileCm.setApproveButtonToolTipText("Open");
    mFileCm.setApproveButtonText("Open");
    mFileCm.setFileFilter(modFilter);
    int returnVal = mFileCm.showOpenDialog(null);

without any dialog stuff around it, sure you need the dialog, cause I do not see it is used (anything added to it…)
because I am in thee mood: How to Use File Choosers (The Java™ Tutorials > Creating a GUI With Swing > Using Swing Components)

The OP already has a file chooser, etc… it opens, it does it’s job, it just opens behind the application window.

I had this problem, too, when I worked on Script Monkey but I solved it using the methods I already provided. They are essentially the only way so if they aren’t working: 1) then they aren’t really being run properly, or 2) it is probably impossible to get working on OP’s machine.

@homsi: on what os are you trying to do this? I am runnig this on windows.