3

I am having trouble refreshing the data inside the JComboBox.

There is a button "Create" which has ActionListener, which adds the item to JComboBox.

But the changes are not reflected in the GUI: I still don't see the new added item.

repaint() doesn't help.

Update: Here is a (almost) full GUI code:

public class Main extends JFrame implements ActionListener
{
    static Connection conn;
    static PreparedStatement ps = null;
    static ResultSet res;

    static Statement sta;

private final static int ITERATION_NUMBER = 1000;

public void GUI () throws SQLException {
    setBounds(0, 0, 320, 240);
    addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent we){
        close(ps);
        close(res);
        close(conn);
        System.exit(0);
        }
    });
    setMinimumSize(new Dimension(320, 240));
    setResizable(false);

    this.setTitle("Accounts");

    JPanel panel = new JPanel();
    GridLayout2 GL = new GridLayout2(4,3);
    GL.setHgap(10);
    panel.setLayout(GL);

    Font font = new Font("Serif", Font.BOLD, 20);
    Font font2 = new Font("Courier New", Font.BOLD, 16);

    JLabel label1 = new JLabel("Username");
    JLabel label2 = new JLabel("Password");
    JLabel label3 = new JLabel("Controls");

    label1.setFont(font2);
    label2.setFont(font2);
    label3.setFont(font2);

    final JTextField username = new JTextField();
    final JTextField password1 = new JPasswordField();
    final JTextField password2 = new JPasswordField();

    final JComboBox userBox1 = new JComboBox();
    final JComboBox userBox2 = new JComboBox();

    JButton create = new JButton("CREATE");

    create.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {
            try {
                createUser(conn, username.getText(), password1.getText());
userBox1.addItem(username.getText());
                userBox2.addItem(username.getText());
            } catch (NoSuchAlgorithmException
                    | UnsupportedEncodingException | SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    });



    userBox1.removeAllItems();
    userBox2.removeAllItems();

    res = (ResultSet) sta.executeQuery("SELECT LOGIN FROM ACCOUNTS");

    String temp;

    for (int i=0; res.next(); i++) {
        temp = (String)res.getString("LOGIN");
        userBox1.addItem(temp);
        userBox2.addItem(temp);
    }

    panel.add(label1);
    panel.add(label2);
    panel.add(label3);

    panel.add(username);
    panel.add(password1);
    panel.add(create);

    panel.add(userBox1);
    panel.add(password2);
    panel.add(modify);

    panel.add(userBox2);
    panel.add(new JLabel(""));
    panel.add(delete);

    add(panel);

    setVisible(true);
}

SOLUTION: Adding password1.setText(""); just after "createUser" solved the problem! That's strange, maybe it somehow refreshed the GUI...

Jake Badlands
  • 1,016
  • 3
  • 23
  • 46
  • 1
    did you `refesh` the `panel` or frame to which the `JComboBox` is a container. – Subs Jun 05 '12 at 20:49
  • 1
    repaint is almost never needed. The components know when they have to repaint themselves. – JB Nizet Jun 05 '12 at 20:49
  • @Jack Added a relevant part of code (could add more if needed) – Jake Badlands Jun 05 '12 at 20:50
  • 1
    Add the code declaring, initializing, and adding the combo to the frame. My guess is that you add an item to a different combo than the one displayed. – JB Nizet Jun 05 '12 at 20:52
  • 1
    1) Generally you can just add it to the [model](http://docs.oracle.com/javase/7/docs/api/javax/swing/DefaultComboBoxModel.html). 2) For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Jun 05 '12 at 20:53
  • 2
    If this is your actual code, then it has two problems: 1. it uses components out of the event dispatch thread. 2. Since userBox is local to the GUI method, I don't know how the listener could have a reference to it. So I'm still guessing you're modifying a different combo than the one displayed. Post real code, or even better: an SSCCE. – JB Nizet Jun 05 '12 at 21:01
  • @JBNizet Thanks to "final" modifier, I could access the userBox object. – Jake Badlands Jun 05 '12 at 21:03
  • 1
    So the create button is created in the same method? Why don't you post real code, or an SSCCE. We can only guess, because we don't see the real code. – JB Nizet Jun 05 '12 at 21:04
  • 1
    Another possibility is that userName.getText() returns null or an empty string, and that this makes the new item invisible in the combo. – JB Nizet Jun 05 '12 at 21:10
  • Actually, there are two comboBoxes, but each of them has this "refresh" problem. – Jake Badlands Jun 05 '12 at 21:13
  • @JBNizet Sorry, forgot to undo the last debug. Please recheck the listener. – Jake Badlands Jun 05 '12 at 21:15
  • 1
    And are you sure the createUser method doesn't throw an exception? What happens when you execute this code in a debugger? – JB Nizet Jun 05 '12 at 21:18
  • @JBNizet It doesn't throw any exceptions. However, adding password1.setText(""); just after "createUser" solved the problem! That's strange, maybe it somehow refreshed the GUI... – Jake Badlands Jun 05 '12 at 21:24

4 Answers4

7
  • you have to add ComboBoxModel to the JComboBox,

  • there you can to add / remove / modify the value,

  • events implemented in the API refreshing your view (JComboBox) without moreover code lines

  • all updates must be done on Event Dispatch Thread

EDIT

maybe I missread your question, if you want to add JComboBox to the already visible GUI, then you have to call (as last code lines and with success only once for one Container)

myContainer.revalidate() // for JFrame up to Java7 is there only validate()
myContainer.repaint()

(sorry @timaschew)

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 2
    @timaschew: there's no need to call `revalidate()` in this situation. – Hovercraft Full Of Eels Jun 05 '12 at 20:54
  • 2
    No need to revalidate anything. Components repaint themselves when they need to. – JB Nizet Jun 05 '12 at 20:55
  • 1
    @timaschew revalidate???, not never to call that for compound JComponent [better would be to test for why reasons is there validate & revalidate](http://stackoverflow.com/a/6989230/714968), this is about LayoutManager and add / remove / modify JComponent in already visible Container – mKorbel Jun 05 '12 at 20:58
3
static class TestFrame extends JFrame implements ActionListener
{
    private JComboBox testBox = new JComboBox();
    private JButton testButton = new JButton();
    int c = 0;

    public TestFrame()
    {
        testBox = new JComboBox();
        testButton = new JButton("Click Me!");
        testButton.addActionListener(this);

        JPanel panel = new JPanel(new GridLayout(2,1));
        panel.add(testBox);
        panel.add(testButton);
        this.add(panel);
        pack();
        setVisible(true);
    }

    public void actionPerformed(ActionEvent e)
    {
        testBox.addItem("test" + c++);
    }
}

This test case works, are you sure you added the listener to the component that is clicked?

Jack
  • 131,802
  • 30
  • 241
  • 343
0

To my knowledge, ComboBox cannot not be refreshed with ".removeAllItems()", ".removeAll()", or ".repaint()".

If you want to refresh it, you have to create a new ComboBox every time, and then add items to it. With the above-given code as an example:

    userBox1 = new JComboBox(); // to replace userBox1.removeAllItems();
    userBox2 = new JComboBox(); // to replace userBox2.removeAllItems();

    res = (ResultSet) sta.executeQuery("SELECT LOGIN FROM ACCOUNTS");

    String temp;

    for (int i=0; res.next(); i++) {
        temp = (String)res.getString("LOGIN");
        userBox1.addItem(temp);
        userBox2.addItem(temp);
    }

I had similar issues, but I solved them this way.

William Hou
  • 1,251
  • 14
  • 17
-3

This code is the button click event to refresh jframeform in the button click event.

new room().show();  //room() is a jframeform
new room().setVisible(false);
Szymon
  • 42,577
  • 16
  • 96
  • 114