Dynamically create jCheckBox and add to a jScrollPane
Asked Answered
T

2

6

EDIT: Using the solutions presented below, I have changed the code to have a JPanel inside a JScrollPane. Using a JButton i add JCheckBoxes to the JPanel inside the JScrollPane. This was one problem solved, as the a JScrollPanecan only take one JComponent. The rest of the issues were solved setting a gridlayout to the JPanel inside JScrollPane. I have kept my original question here for the sake of posterity:

ORIGINAL QUESTION: I'm trying to dynamically create JCheckBox and add them to a JScrollPane, but alas i am achieving little success. I have reduced this to a single proof-of-concept implementation.

I have a JScrollPaneon a JPanel inside a JFrame. Also on the JPanel, i have added a button that is supposed to add a JCheckBox to the JScrollPane when clicked. Should be simple enough. The code inside the button is as follows:

 private void addCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {

    JCheckBox cb = new JCheckBox("New CheckBox");        

    jScrollPaneCheckBoxes.add(cb);
    jScrollPaneCheckBoxes.revalidate();
 }

The code runs seemingly without error. I have no exceptions and using the debugger shows that the JCheckBox is in fact added to the JScrollPane . Unfortunately, nothing is displayed in the application. I need direction as to where to look for the problem.

Here is a quick piece of code that you can just run. Unfortunately i threw this together using Netbeans and it's GUI designer and as such it's a bit longer than it needs to be, especially the generated code. Focus on the method jButton1ActionPerformed, that's where the above code is taken from.

EDIT: This code now does what i need it to. :-)

package dynamiccheckboxsscce;

import javax.swing.JCheckBox;

public class Main extends javax.swing.JFrame {

    /**
     * Creates new form Main
     */
    public Main() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jPanel1 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane1.setPreferredSize(new java.awt.Dimension(250, 250));

        jPanel1.setPreferredSize(new java.awt.Dimension(300, 250));
        jPanel1.setLayout(new java.awt.GridLayout(0, 2, 10, 10));
        jScrollPane1.setViewportView(jPanel1);

        jButton1.setText("Add Checkbox");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE)
                .addContainerGap())
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(0, 0, Short.MAX_VALUE)
                .addComponent(jButton1)
                .addGap(112, 112, 112)))));
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE)
                .addComponent(jButton1)
                .addContainerGap()));

        pack();
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        JCheckBox cb = new JCheckBox("New CheckBox");

        jPanel1.add(cb);
        jPanel1.revalidate();
        jPanel1.repaint();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Main().setVisible(true);
            }
        });
    }
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
}

Thanks in advance.

Triad answered 19/4, 2012 at 18:43 Comment(4)
without posting a SSCCE you can awaiting the same answers as is here belowWilow
sscce incoming - just give me a minute.Triad
This answer of mine contains a scrollpane to which I dynamically add itemsInterstitial
I have updated the code above to a working example, which combines the points made by mKorbel and the code he provided. The code above just uses a slightly different approach and a different layout manager, but results in more or less the same output.Triad
W
8

EDIT

  • you have to set proper LayoutManager to the JPanel

  • you ahve to add JPanel to the JScrollPane

  • for example (without using built_in designer, even safe time for ..., required best knowledge about used SwingFramework and Swing too, I'm satisfied with plain Swing)

code

import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class AddJCheckBoxToJScrollPane {

    private static final long serialVersionUID = 1L;
    private JFrame frame = new JFrame();
    private JButton jButton1;
    private JPanel jPanel1;
    private JScrollPane jScrollPane1;

    public AddJCheckBoxToJScrollPane() {
        jPanel1 = new JPanel();
        jPanel1.setLayout(new GridLayout(0, 2, 10, 10));
        jScrollPane1 = new JScrollPane(jPanel1);
        jButton1 = new JButton("Add Checkbox");
        jButton1.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                JCheckBox cb = new JCheckBox("New CheckBox");
                jPanel1.add(cb);
                jPanel1.revalidate();
                jPanel1.repaint();
            }
        });
        frame.add(jScrollPane1);
        frame.add(jButton1, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 200);
        //frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String args[]) {

        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
        } catch (InstantiationException ex) {
        } catch (IllegalAccessException ex) {
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        }
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new AddJCheckBoxToJScrollPane();
            }
        });
    }
}
Wilow answered 19/4, 2012 at 19:8 Comment(2)
sscce incoming - just give me a minute.Triad
Thanks for the solution. I have learned two things from this experience. 1. What is being displayed has a lot more to do with the layouts than with the component and 2. I don't know enough about layouts. :-)Triad
M
0

You should be calling repaint() instead of revalidate().

See Revalidate vs. Repaint

Mannes answered 19/4, 2012 at 18:46 Comment(5)
Replaced revalidate with repaint - no difference. Even added both. Thanks for the suggestion. Quote from that link you provided: "revalidate is called on a container once new components are added or old ones removed."Triad
Hmm. My thought would've been that the repaint on the children wouldn't have caught the added object but the repaint on the top-level panel would. You're going to need to give us more information if that's not the issue.Mannes
@Mannes please just try once, btw I'd to suggest to delete this answer because is soooooo down_vote sesitiveWilow
If anything it'll prevent more people from posting the same thing. I don't mind if it's downvoted, as it was the wrong answer.Mannes
@Wilow - tone of voice is very difficult on-line, so i'm going to give you the benefit of the doubt and kindly ask that if my question is annoying you that you just skip it - i don't want to anger you or waste your time; i just want to try and solve my problem without any hassles. THat link you gave includes this language, which i can not identify as English: "to avoiding any further discusion about required/non-required any of Methods ... notice: for adds/removes JComponents (simple structured just in one Row/Column and with same Size on Screen) is sufficient just action JFrame.pack()"Triad

© 2022 - 2024 — McMap. All rights reserved.