0

I'm looking for a way to dynamically add a Component inside a JFrame after it has been set visible. Specifically, I'm making a request to a database and based on the length of the result, I want to show a JRadioButton on the screen. I'm using this code:

try {
        Class.forName(Mavenproject1.SQL_DRIVER);
        Connection c = (Connection) DriverManager.getConnection(Mavenproject1.DB, Mavenproject1.ROOT, Mavenproject1.PASSWORD);
        PreparedStatement ps = c.prepareStatement("Select * from calendriers where user = ?");
        ps.setString(1, Login.USER);
        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            int cal_id = rs.getInt(1);
            ps = c.prepareStatement("Select * from creneaux where calendrier = ?");
            ps.setInt(1, cal_id);
            rs = ps.executeQuery();
            while (rs.next()) {
                JRadioButton radio = new JRadioButton("Hello world");
                radio.setVisible(true);
                Date debut = Date.getDateFromString(rs.getString(2), true);
                Date fin = Date.getDateFromString(rs.getString(3), true);
                Creneau cr = new Creneau(debut, fin);
                creneaux.add(cr);
                System.out.println(cr.toString());
                getContentPane().add(radio);
                getContentPane().revalidate();
                getContentPane().repaint();
            }
            Component[] components = getContentPane().getComponents();
            for (Component component : components) {
                System.out.println(component.getClass().getName());
            }
        }
    } catch (Exception ex) {
        JOptionPane.showMessageDialog(null, "Error", "error", 1);
    }

As an output, I'm having the corresponding JRadioButtons are components of the content pane but I'm unable to see it on the screen ,I checked the location using getLocation() it said 0,0 , I changed it to 100,100 but still nothing..

4
  • 1) What is the layout manager of the content pane? By default it is a BorderLayout and only a single component can be added to the BorderLayout.CENTER, which is the default if you don't specify a constraint when adding the component. 2) components are visible by default so no need for the setVisible(...) statement. 3) the revalidate() and repaint() should be invoked outside the loop AFTER all components have been added.
    – camickr
    Commented Mar 24, 2023 at 14:57
  • @camickr I'm using a GroupLayout
    – Yahia
    Commented Mar 24, 2023 at 15:18
  • 1
    And GroupLayout is one of the most complex layout managers. You need to specify multiple constraints to get the components to display properly. Read the Swing tutorial on Layout Managers. I suggest you use one of the other layout manager to achieve your desired layout. You can also nest panels with different layout managers.
    – camickr
    Commented Mar 24, 2023 at 15:22
  • minimal reproducible example please .. no need for database access to demonstrate a problem with layout :)
    – kleopatra
    Commented Mar 24, 2023 at 15:51

1 Answer 1

-1

You have to make the UI changes on the event dispatch thread. Assuming the database access is done on a dedicated thread, wrap the UI changes in SwingUtilities.invokeLater(), for example:

SwingUtilities.invokeLater(() -> {
    JRadioButton radio = new JRadioButton("Hello world");
    radio.setVisible(true);
    getContentPane().add(radio);
    getContentPane().revalidate();
    getContentPane().repaint();
});

Using a SwingWorker might be a good idea too.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.