Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GUI elements not showing until resize of window

Tags:

java

swing

I have been experimenting with making GUIs in java as opposed to just using "static" all the time and come across the "SwingUtilities.invokeLater()" method. I manage to get everything setup but when it comes to run the application, nothing appears on the JPanel until I resize the window. Is there a fix for this or am I doing it wrong?

Heres my code:

public class main extends JPanel implements ActionListener{ 
public JLabel userLabel;
public JLabel passLabel;
public JTextField userField;
public JTextField passField;
public JButton login;
public JButton closeLogin;
public JButton help;

public main(){
    userLabel = new JLabel("Username: ");
    passLabel = new JLabel("Password: ");
    userField = new JTextField(16);
    passField = new JTextField(16);

    login = new JButton("Login");
    login.setActionCommand("login");
    login.setMnemonic(KeyEvent.VK_L);
    closeLogin = new JButton("Close");
    closeLogin.setActionCommand("closeLogin");
    closeLogin.setMnemonic(KeyEvent.VK_E);
    help = new JButton("Help");
    help.setActionCommand("helpLogin");
    help.setMnemonic(KeyEvent.VK_H);

    login.addActionListener(this);
    closeLogin.addActionListener(this);
    help.addActionListener(this);

    add(userLabel);
    add(userField);
    add(passLabel);
    add(passField);
    add(login);
    add(help);
    add(closeLogin);

}
public void actionPerformed(ActionEvent e){ 
}
public static void initComponents(){
    JFrame loginFrame = new JFrame("Encrypted Chat - Login");
    loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    main loginPanel = new main();
    loginPanel.setLayout(new FlowLayout());
    loginFrame.setSize(300, 125);
    loginFrame.setResizable(false);
    loginFrame.setVisible(true);        
}
public static void main(String args[]){
    SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            initComponents();
        }
    });
}

}

EDIT: I know the password JTextField is meant to be a JPasswordField.. so ignore it :P

like image 929
Andrei0427 Avatar asked Sep 06 '12 07:09

Andrei0427


3 Answers

Two basic advices:

1.) When you use swing, and stuff doesnt show up/update, you should call JPanel.revalidate() and JPanel.repaint() These two functions will update your panel. If you are using a JFrame and you didn't add any extra panels to it, then you can get the content panel by JFrame.getContentPane()

2.) When you finished adding Components to a panel/frame you should also call pack() on the frame, this will ensure, that all your Components have the prefered size.

like image 111
Balázs Édes Avatar answered Nov 17 '22 01:11

Balázs Édes


You never add your content to the JFrame. The minimal set of changes you need:

  public static void main(String args[]){
    final main main = new main();
    SwingUtilities.invokeLater(new Runnable(){
      public void run(){
        initComponents(main);
      }
    });
  }

And then modify initComponents to take a main object:

  public static void initComponents(main main){
    JFrame loginFrame = new JFrame("Encrypted Chat - Login");
    loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    main loginPanel = new main();
    loginPanel.setLayout(new FlowLayout());
    loginFrame.setSize(300, 125);
    loginFrame.setResizable(false);
    loginFrame.setVisible(true);
    loginFrame.add(main);  // <----- this line is added
  }
like image 34
sjr Avatar answered Nov 17 '22 03:11

sjr


for built_in FlowLayout (for JPanel) I don't suggest to use pack() for JFrame, sure correct way could be to use proper and better LayoutManager for this job, GridBagLayout or SpringLayout

output by using JFrame#setSize() and without pack()

enter image description here

for example

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class MainLogin implements ActionListener {

    private JFrame loginFrame = new JFrame("Encrypted Chat - Login");
    private JPanel pnl = new JPanel();
    private JLabel userLabel;
    private JLabel passLabel;
    private JTextField userField;
    private JTextField passField;
    private JButton login;
    private JButton closeLogin;
    private JButton help;

    public MainLogin() {
        userLabel = new JLabel("Username: ");
        passLabel = new JLabel("Password: ");
        userField = new JTextField(16);
        passField = new JTextField(16);
        login = new JButton("Login");
        login.setActionCommand("login");
        login.setMnemonic(KeyEvent.VK_L);
        closeLogin = new JButton("Close");
        closeLogin.setActionCommand("closeLogin");
        closeLogin.setMnemonic(KeyEvent.VK_E);
        help = new JButton("Help");
        help.setActionCommand("helpLogin");
        help.setMnemonic(KeyEvent.VK_H);
        login.addActionListener(this);
        closeLogin.addActionListener(this);
        help.addActionListener(this);
        pnl.add(userLabel);
        pnl.add(userField);
        pnl.add(passLabel);
        pnl.add(passField);
        pnl.add(login);
        pnl.add(help);
        pnl.add(closeLogin);
        loginFrame.add(pnl);
        loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        loginFrame.setSize(300, 125);
        loginFrame.setResizable(false);
        loginFrame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                MainLogin mainLogin = new MainLogin();
            }
        });
    }
}
like image 1
mKorbel Avatar answered Nov 17 '22 01:11

mKorbel