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.

Jef
  • 791
  • 1
  • 18
  • 36
wmdvanzyl
  • 352
  • 2
  • 5
  • 17
  • without posting a [SSCCE](http://sscce.org/) you can awaiting the same answers as is here below – mKorbel Apr 19 '12 at 19:00
  • sscce incoming - just give me a minute. – wmdvanzyl Apr 19 '12 at 19:19
  • [This answer of mine](http://stackoverflow.com/questions/9885855/how-to-dynamically-add-jbutton-to-jpanel/9885927#9885927) contains a scrollpane to which I dynamically add items – Robin Apr 19 '12 at 20:47
  • 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. – wmdvanzyl Apr 20 '12 at 07:15

2 Answers2

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();
            }
        });
    }
}
Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • sscce incoming - just give me a minute. – wmdvanzyl Apr 19 '12 at 19:18
  • 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. :-) – wmdvanzyl Apr 20 '12 at 07:13
0

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

See Revalidate vs. Repaint

Community
  • 1
  • 1
Charles
  • 245
  • 2
  • 11
  • 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." – wmdvanzyl Apr 19 '12 at 18:56
  • 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. – Charles Apr 19 '12 at 19:02
  • @Charles please [just try once](http://stackoverflow.com/a/6989230/714968), btw I'd to suggest to delete this answer because is soooooo down_vote sesitive – mKorbel Apr 19 '12 at 19:03
  • 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. – Charles Apr 19 '12 at 19:06
  • @mKorbel - 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()" – wmdvanzyl Apr 19 '12 at 19:17