1

EDIT: Although I have never used (or even known about) SwingUtilities.InvokeLater() before today, implementing it did not solve the problem. The 1-second delay between the visibility of the JFrame and the appearance of the JLabel remains with the following, updated code.

public class DelayTest {

public static void main(String [] args) {
    new DelayTest();
}

public DelayTest() {
     SwingUtilities.invokeLater(new Runnable() 
        {
          public void run()
          {
              long start = System.currentTimeMillis();
            JFrame frame = new JFrame("Demo");
            Container content = frame.getContentPane();

            //sizing
            Dimension dimm = new Dimension(500, 200);
            frame.setPreferredSize(dimm);
            frame.setResizable(false);

            //content
            content.add(new JLabel("Hello, Delayed World"));
            System.out.println("Added Label at: " + 
                    (System.currentTimeMillis() - start) + " Milliseconds");

            //end
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            System.out.println("Finished execution at: " + 
                    (System.currentTimeMillis() - start) + " Milliseconds");
          }
        });
    }
}

I have, so far, done the following to try to resolve the error:

  • Updated my Computer (Mac OS X 10.11.6)
  • Updated Java (java version "1.8.0_111")
  • Erased and Re-Installed Eclipse (Java Neon.2)
  • Exported jar, just to see if the problem existed outside Eclipse
  • Tested using SwingUtilities.InvokeLater() as seen above (Hopefully I used it correctly)

I restarted several times throughout the process but nothing seemed to fix it. I'm hoping you can either help me find the error in my code that is delaying the Label (which I don't think exists,) or verify that my code works on your computer.

  • 2
    Possible duplicate of [Main Thread vs. UI Thread in Java](http://stackoverflow.com/questions/7156949/main-thread-vs-ui-thread-in-java) – NickL Jan 17 '17 at 19:36
  • Well, to start with, you're not created/shown the frame within the context of the EDT, so there could be a delay in the EDT becoming available and processing the required events. It may not fix the issue entrily, but I'd suggest wrapping the code in `SwingUtilities.invokeLater` and try again. – MadProgrammer Jan 17 '17 at 19:43
  • @MadProgrammer I appreciate the advice, but it does not seem to have worked in this case, assuming I'm using the method correctly (see my update above.) Still, I'm glad to know about this so I can start implementing it in my projects. – Mike Knooihuisen Jan 17 '17 at 20:13
  • 1
    Did you try calling `frame.validate();` right before `frame.setVisible(true);`? – Holger Jan 17 '17 at 22:48

2 Answers2

0

As it turns out, my problem was instantly fixed by specifying a LayoutManager for the content Container. I'm now assuming it to be a strange Java bug, perhaps only on Mac. The following code resolves my issue:

public class DelayTest {

public static void main(String [] args) {
    new DelayTest();
}

public DelayTest() {
     SwingUtilities.invokeLater(new Runnable() 
        {
          public void run()
          {
              //long start = System.currentTimeMillis();
            JFrame frame = new JFrame("Demo");
            Container content = frame.getContentPane();

            //NEW CODE
            content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
            //END NEW CODE

            //sizing
            Dimension dimm = new Dimension(500, 200);
            frame.setPreferredSize(dimm);
            frame.setResizable(false);

            //content
            content.add(new JLabel("Hello, Delayed World"));

            //end
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

          }
        });
    }
}

Having a GUI that does not use one Layout Manager or another is almost entirely pointless, which explains why I've never seen this problem before.

TL;DR: Always use a LayoutManager (and SwingUtilities.invokeLater(), apparently) even if you only need to display one component in the window.

  • Funny I tried with a `BorderLayout` and still got the same results (delayed JLabel). However, if you see my answer below the call to `frame.setSize(dimm);` over the call to `frame.setPreferredSize(dimm)` works as well. – Jayfray Jan 17 '17 at 20:40
  • The issue definitely seems to be related to `setPreferredSize`, removing that one line seems to make it work just fine. Since the frame uses a `BorderLayout` by default, I'd say you're seeing a side effect, not the solution - IMHO – MadProgrammer Jan 17 '17 at 20:52
0

Remove the call to frame.setPreferredSize(dimm); and after frame.setLocationRelativeTo(null); add the following:

frame.setSize(dimm);
Jayfray
  • 415
  • 3
  • 12
  • I wouldn't put `setSize` after `setLocationRelativeTo`, `setLocationRelativeTo` will rely on the size of the frame to position it correctly ;), but `setSize` definitely has an effect – MadProgrammer Jan 17 '17 at 20:55
  • Agreed. Calling `setSize` after `setLocationRelativeTo` causes the JFrame to render off-center but everything works as expected if you reverse the order. What is the etiquette here? Should I update my own answer or wait to select one of yours once it's correct? I don't think I get points for answering my own question anyway :) – Mike Knooihuisen Jan 17 '17 at 21:07