3

I have a JFrame that I create in the main function. I want to add a JTextField to it. The problem I'm having is that the JFrame is created and then - with about a second delay - the JTextField is added. Is there a way I can draw the text field to my window and then show all at once? Thanks in advance!

For reference, here is my code:

public class Window {

public static final JFrame window = new JFrame();
public static final JTextField input = new JTextField();

private static void loadWindow(){

    window.setSize(800, 600);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setLayout(new FlowLayout());
    input.setPreferredSize(new Dimension(400, 60));

    window.add(input);
    window.setVisible(true);

}

public static void main(String[] args){

    loadWindow();

}

}

Here's the timeline of what's happening:

First second:

enter image description here

Second after:

enter image description here

Ood
  • 1,445
  • 4
  • 23
  • 43
  • No part in this snippet is pointing to the fact, that some delay is occurring. Though if you are trying to add controls to a `JFrame` or to an already visible `JFrame`, then try `frame.pack()` after adding component, that will suffice, IMHO. – nIcE cOw Jun 12 '14 at 11:31
  • The JFrame is not visible, it is exactly as shown in the example. I don't know why this delay is occurring. I am using Mac OSX and the JFrame is visible before the text field is. – Ood Jun 12 '14 at 11:33
  • Where is this `JTextField` in question initialized? Are you running the Swing's code on `Event Dispatcher Thread-EDT` and not from main thread? – nIcE cOw Jun 12 '14 at 11:35
  • Please take a look at the edit. – Ood Jun 12 '14 at 11:38
  • 3
    Are you running the Swing's code on `Event Dispatcher Thread-EDT` and not from main thread? If `frame.setVisible(true)` is the last call, then, I have never seen such a thingy before, a small runnable example will be quite helpful :-) – nIcE cOw Jun 12 '14 at 11:41
  • Have you run the debugger? How big is your program? – Clark Kent Jun 12 '14 at 11:41
  • It is very small and indeed very weird. I have run the debugger and everything seems normal. – Ood Jun 12 '14 at 11:44
  • Could you post all of the code so I can recreate it? Also, which version of Java are you running? – Clark Kent Jun 12 '14 at 11:46
  • where is the loadWindow() method being called from. – Davie Brown Jun 12 '14 at 11:47
  • 1
    Please take a look at the edit. – Ood Jun 12 '14 at 11:49
  • 2
    Try instantiating the JFrame and JTextField within the loadWindow() method. i.e calling new ..() on them rather than in the class. Also not so sure why these would be final. – Davie Brown Jun 12 '14 at 11:53
  • I have previously tried this and it was the same result so I reverted back to this version. – Ood Jun 12 '14 at 11:54
  • Which IDE and version are you using? Which version of Java are you running? How are you calling the application? – Clark Kent Jun 12 '14 at 11:55
  • I am using the latest version of NetBeans and the latest Java SDK. I am calling the application from the IDE. – Ood Jun 12 '14 at 11:58
  • I'm not exactly sure, but shouldn't you set the size of the text field directly instead of setting its preferred size. – succcubbus Jun 12 '14 at 12:02
  • Thank you! Removing that line did the trick! However, my text field has no size now. – Ood Jun 12 '14 at 12:03
  • Really... I was not able to reproduce the error with the code you posted. – Clark Kent Jun 12 '14 at 12:04
  • Do setSize() to set the size of the textfield – succcubbus Jun 12 '14 at 12:05
  • It may be an OS related problem. I have tried the same code several times and always had this error. – Ood Jun 12 '14 at 12:05
  • try updateUI();/window.revalidate(); window.setVisible(true); – Tusar Jun 12 '14 at 12:10
  • The current code works fine for me. The only time it lags the appearance of `JTextField` was the first time and I guess it had to do with the compilation. How long is the delay? Is it systematic? – Eypros Jun 12 '14 at 12:18
  • It is always about one second. – Ood Jun 12 '14 at 12:19
  • If you don't run Swing on EDT, you cannot expect it to work. Wrap your `loadWindow()` call in [SwingUtilities.invokeLater(Runnable)](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html#invokeLater%28java.lang.Runnable%29). Also, instead of what you are doing now, extend a JFrame and instantiate that. No need for static swing components... – predi Jun 12 '14 at 12:36
  • I did note, during my testing, that the field seems to become visible when the cursor is first painted, hence the second (or so) delay – MadProgrammer Jun 12 '14 at 21:10
  • Instead of `public static final JTextField input = new JTextField(); .. input.setPreferredSize(new Dimension(400, 60));` set a large font for the height and use `new JTextField(20);` for the width. Then add it to a panel with a large `EmtpyBorder`. Then add that panel to the frame and call `pack()`. **Do it all on the EDT.** – Andrew Thompson Jun 13 '14 at 03:08

3 Answers3

2

Chalk this one to weirdness...

I changed

public static final JTextField input = new JTextField();

to

public static final JTextField input = new JTextField(20);

And it worked fine...

I would however encourage you...

  • to avoid using setPreferredSize as it won't always work on every platform as you don't control the rendering pipelines which can affect the amount of space a component will need in order to render properly
  • Start your UI's in the EDT...

For example...

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        }

        loadWindow();
    }
});
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

I don't believe you would want the JFrame and JTextField to have the final access modifiers. How final keyword works Try removing these.

Community
  • 1
  • 1
Davie Brown
  • 717
  • 4
  • 23
-1

Use setSize() to configure the size of Components. setPreferrredSize() will be applied at an unknown time or whenever you call pack on the component.

succcubbus
  • 874
  • 1
  • 7
  • 24
  • Once the window is realised, the layout manager will be called to perform a layout, discarding any changes you made with `setSize` – MadProgrammer Jun 12 '14 at 12:33
  • Your right. I tend to use null for the layout. That's where setSize() will do the trick. – succcubbus Jun 12 '14 at 12:41
  • *"I tend to use null for the layout."* -1. Please stop making comments on Java GUI construction until you discover the pitfalls of `null` layouts. – Andrew Thompson Jun 13 '14 at 03:10