Poor performance with JFileChooser

What does it say if you run this with a profiler? (NetBeans is good for profiling on-startup tasks)


public static void main(String[]a) {
    JFileChooser fc = new JFileChooser("./resources/levels");
}

Where is the time being spent? Remember to include javax.swing etc in the profiled classes.

does [icode]SwingUtilities.isEventDispatchThread()[/icode] yield true just before you create it ?

it should. if not, try creating like that :

SwingUtilities.invokeLater(new Runnable()
{
  @Override public void run()
  {
    JFileChooser chooser = ...
  }
});

if you want to block the main thread during that operation - use [icode]SwingUtilities.invokeAndWait()[/icode] instead.

o/

I’ve never used a profiler and am running eclipse atm. I’m at work right now so I can’t spend time on it for the next few hours. Can you recommend a good profiler for eclipse? Or should I download and import into netbeans?

I’ll use JVM Monitor and get back to you, maybe I can do it on a break.

FYI, this is NOT FIXED the look and feel didn’t have any effect.

Yes it returns true, there is a new thread.

mhm … try invokeLater in actionPerformed anyway. just a guess :slight_smile:

a good profiler i jvisual, it’s sitting in the /bin directory of you java jdk. thats basically what is embedded into netbeans. i bet there is an addon for eclipse to achieve the same - if not, use the standalone version, same good.

C:\Program Files (x86)\Java\jdk\bin\jvisualvm.exe - or 64bit version, needs to match the running application.

I normally just use jvisualvm, but I can’t find a way outside of netbeans to profile right from program start.
Although I guess you can set a breakpoint in eclipse and attach jvvm while it’s waiting at the breakpoint.

Again, can you provide an MCVE that demonstrates the problem? This shouldn’t be a disconnected snippet, but it should be just enough code that we can copy and paste it as-is and run it on our own machines. With what you’ve provided so far, the best anyone can do is guess.

I would guess that you’re doing something with threading or the EDT, but there’s no way to diagnose that without an MCVE.

ActionListener.actionPerformed() is always called on the EDT. All Swing event listeners are. You only need to worry about SwingUtilities.invokeLater()/invokeAndWait() when you are off in your own thread, or something like the main application thread.

Something that can cause random hangs in windows filesystems is attempting to access floppy drives, CD drives, or network drives that don’t exist. Domain-related woes especially. You might want to whip open Explorer and see if it has trouble at the same time.

Cas :slight_smile:

yes, but no.

if boot off things in the EDT right ahead it can still hang and screw you over. invokeLater from the EDT ensures the new action is queued to the end, rendering the current EDT process not block. :cranky:

edit

on the other side, if you run invokeAndWait from the EDT you make it hang 100%.

'Tis true. I recall back in the 1.4 days (I think), I hacked JFileChooser code (perhaps FileSystemView) to return a hard-coded display name of “A:” for a floppy drive (if on Windows) instead of letting Java do whatever native call to determine the drive name. Terrible I know, but I recall back then there was some issue where Java would actually access the drive (you’d hear the physical drive access) before fetching the drive’s name. It just wasn’t worth it back then, when Swing had so many other things going against it performance-wise.

I’ve also seen JFileChooser hang for long periods of time while trying to access information about certain mounted drives in both Linux and AIX. Always in native calls, never in something you could control.

I’m not quite sure I understand what you’re saying here. If a Swing EventListener class is not triggered on the EDT, you have found a bug in the JDK (or perhaps you have a custom JComponent going rogue and not playing by the rules). I am assuming of course that the programmer is doing “the right thing,” starts their Swing app on the EDT, etc.

If you’re stating that running long-running processes in an ActionListener on the EDT causes the EDT to appear to hang, that is certainly true. But if you’re performing long-running tasks you should run them off the EDT in the first place, perhaps via SwingWorker. Delaying a long-running task by calling SwingUtilities.invokeLater() when you’re already on the EDT only delays when that long-running task will run on the EDT, it doesn’t cause it not to occur. The UI will still hang for the same length of time, only perhaps after performing a few other tasks.

Yes, again, I’m assuming the programmer isn’t doing something stupid.

I’m not really sure what you’re trying to say here, but if the EDT is already hung on a long-running process, using invokeLater() won’t help you at all.

Erm, no. You’ll get an error because you can’t call invokeAndWait() from the EDT.

Lot of disinformation in this thread, which is why OP needs to post something that we can run instead of just throwing out random guesses.

yes, you will get a Error for calling invokeAndWait from the EDT.

i was not clear enough i guess : “on the other side, if you could run invokeAndWait from the EDT you would make it hang 100%.”

this is the opposite of “invokeLater from the EDT ensures the new action is queued to the end” - which can be very handy - if the current EDT code (not a long run process, nothing to do with SwingWorkers) - requires to finish (before new components are created or changed). that’s too complicated.

things like https://github.com/Insubstantial can cause this.

usually you “should” not care about this things, yet you should always care about what is happening on which thread and what is allowed on which thread, especially with Swing.

sigh It doesn’t matter how small the program is, this always happens. I thought that it could be jogl, because I think it uses the awt eventqueue, but even when I copy and paste the tut programs off the internet this still happens.

Anyway since you guys want an MCVE here you go

package FFS02_Leveled;
public class LevelEdMain 
{
	static Thread thread;
	static LevelEd leveled;
	public static void main(String[] args)
	{		
		leveled = new LevelEd();
		thread = new Thread(leveled, "Main-Level Editor Thread");
		thread.start();
	}
}
package FFS02_Leveled;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.filechooser.FileNameExtensionFilter;

public class LevelEd extends JFrame implements GLEventListener, KeyListener, MouseListener, MouseMotionListener, Runnable
{	
	private static final long serialVersionUID = 3669760361816887841L;
	
	//STANDARD VARIABLES
	private long 					g_last_time;
	private GL2 					g_gl;
	private GLU 					g_glu;
	protected GLCanvas 				g_glcanvas;
	
	
	public LevelEd() 
	{
		super("FFS02Leveled");

		Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();//Get monitor dimensions
		float scale = 1.0f;//Set the scaling of the window
		
		//Set the window width and height
		int window_width = (int) (dimension.width * scale);
		int window_height = (int) (dimension.height * scale) - 48;
		
		init(window_width, window_height);//Initialize our variables
		startOpenGL();
	}
	
	public synchronized void display(GLAutoDrawable gld)
	{
		GL2 g_gl = gld.getGL().getGL2();
	}
	
	public void dispose(GLAutoDrawable arg0)
	{
	}
	
	public void init(GLAutoDrawable gld)
	{		
		//Make a new glu, glut, and gl for using OpenGL
		g_gl = gld.getGL().getGL2();
		g_glu = new GLU();

		g_gl.glClearColor(0.1f, 0.1f, 0.1f, 1.0f);//Set the default background color

		g_gl.glEnable(GL.GL_DEPTH_TEST);
		g_gl.glEnable(GL.GL_CULL_FACE);
		g_gl.glDepthFunc(GL.GL_LEQUAL);

	    int sample_buffers[] = new int[1];
	    int samples_for_buffer[] = new int[1];

	    g_gl.glGetIntegerv(GL.GL_SAMPLE_BUFFERS, sample_buffers, 0);
	    g_gl.glGetIntegerv(GL.GL_SAMPLES, samples_for_buffer, 0);
		g_gl.glEnable(GL.GL_MULTISAMPLE);

		g_gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
		
		g_gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
	}
	
	public void init(int window_width, int window_height)
	{
		int w = 80;
		int h = 24;
		JMenuBar menu_bar = new JMenuBar();
		setJMenuBar(menu_bar);

		JMenu menu_file = new JMenu("File");
		menu_file.setPreferredSize(new Dimension(50, h));
		menu_bar.add(menu_file);
		
		JMenuItem file_load = new JMenuItem("Load");
		file_load.setPreferredSize(new Dimension(w, h));
		file_load.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e)
			{	
				JFileChooser fc = new JFileChooser("./resources/levels");
				fc.setDialogTitle("Open .lvl File");
				fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
				FileNameExtensionFilter filter = new FileNameExtensionFilter("Level File", "lvl");
				fc.setFileFilter(filter);
				int return_val = fc.showOpenDialog(null);
				if(return_val == JFileChooser.APPROVE_OPTION)
				{
					
				}
			}
		});
		menu_file.add(file_load);
	}
	public synchronized void keyPressed(KeyEvent e)
	{
	}
	public void keyReleased(KeyEvent e)
	{
	}
	public void keyTyped(KeyEvent e)
	{
	}
	public void mouseClicked(MouseEvent arg0) 
	{
	}
	public void mouseDragged(MouseEvent arg0) 
	{
	}
	public void mouseEntered(MouseEvent arg0) 
	{
	}
	public void mouseExited(MouseEvent arg0) 
	{
	}
	public void mouseMoved(MouseEvent arg0) 
	{
	}
	public void mousePressed(MouseEvent arg0) 
	{
	}
	public void mouseReleased(MouseEvent arg0) 
	{
	}
	public void reshape(GLAutoDrawable gld, int x, int y, int width, int height)
	{
	}
	
	public void run() 
	{
		boolean running = true;
		g_last_time = System.nanoTime();
		final double ns = 1_000_000_000.0 / 60.0;//Limits to 60 updates per second
		double delta = 0;

		double delta_time = 0;
		double limiter = 0.15;
		double previous_time = 1.0;
		double current_time = System.nanoTime() * 0.000000001;
		
		while(running)
		{
			long new_time = System.nanoTime();
			delta += (new_time - g_last_time) / ns;
			g_last_time = new_time;

			current_time = System.nanoTime() * 0.000000001;//Convert to Seconds
			delta_time = delta_time > limiter ? limiter : current_time - previous_time;
			previous_time = current_time;
			
			while(delta >= 1)
			{
				update(delta_time);
				delta--;
			}
			g_glcanvas.display();
		}
		
	}	
	
	private void startOpenGL()
	{
		g_glcanvas.addGLEventListener(this);
		g_glcanvas.addKeyListener(this);
		g_glcanvas.addMouseListener(this);
		g_glcanvas.addMouseMotionListener(this);
	}
	public synchronized void update(double delta_time) 
	{
	}
	
}

Hi, am facing the same issue.could anyone answer the problem ? thanks.

Since I happen to be on…I never found a solution to this problem. However, in my current project I don’t have this issue. I could speculate reasons why was hanging then and it’s not hanging now, but I think that would not be worth anyone’s time at the moment (particularly mine, to go find that project and spin it up).

In the future please start a new thread and post specifics to your issue.