4

I have a JComboBox with some options. When I make a selection at another component, I'm changing JComboBox contents. First I call the removeAllItems() method, and then I add one by one the Strings I need now.

The problem is, by default I had some options, and one of them was the larger text, so JComboBox got the width it needed to show that option correctly. When I change the JComboBox contents, that text option is gone, and now a smaller text is giving the width to the JComboBox, so when I change contents it gets smaller.

My first approach was calling myComboBox.setPreferredSize(myComboBox.getSize()) and then its dimensions are fixed, but not correctly: it gets a bit smaller in height and width. I think it is because I'm using Nimbus Look&Feel, and the dimensions I'm getting from the getSize() method are the ones given by the Java default Look%Feel.

I also tried myCombo.setPreferredSize(new Dimension(myCombo.getHeight(), myCombo.getWidth())) with same results.

How can I approach this problem?

I add a code example of how I'm using the Layout:

    private String[] comboEventDOutputStrings = { "Run", "Stop", "Pause", "Conditioning time", "Deposition time", "Equilibration time", "Measurement time"};
    private String[] comboEventDInputStrings = { "Run", "Stop", "Pause"};
    // The first String array is the default set of values. It's obvious that the JComboBox will get smaller
    // when I change to the second array of contents

        //...   
            JPanel pane = new JPanel(new GridBagLayout());
            JPanel jPanelExterno = new JPanel(new GridBagLayout());
            GridBagConstraints cExterna = new GridBagConstraints();
            GridBagConstraints c = new GridBagConstraints();
            Border loweredetched = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
            jPanelExterno.setBorder(loweredetched);
            jPanelExterno.setName("");

            cExterna.fill = GridBagConstraints.BOTH;
            cExterna.anchor = GridBagConstraints.NORTH;
            cExterna.gridx = 0;
            cExterna.gridy = 0;
            cExterna.insets = new Insets(10,10,5,5);

                JPanel jPanel1 = new JPanel(new GridBagLayout());
                jPanel1.setBorder(loweredetched);
                jPanel1.setName("PIO 1");

                jCheckBox1 = new JCheckBox("Enable");
                jCheckBox1.setSelected(false);
                jCheckBox1.setName("1");
                jCheckBox1.addActionListener(new PIOCheckListener());

                c.fill = GridBagConstraints.BOTH;
                c.anchor = GridBagConstraints.NORTH;
                c.gridx = 0;
                c.gridy = 0;
                c.insets = new Insets(10,5,10,10);
                jPanel1.add(jCheckBox1, c);

                c.gridy++;
                c.insets = new Insets(5,10,5,5);
                JLabel label1 = new JLabel("IO Type");
                jPanel1.add(label1, c);
                c.gridx++;
                c.insets = new Insets(5,5,5,10);

                combo1 = new JComboBox(comboIOTypeStrings);
                combo1.setEnabled(false);
                combo1.setSelectedIndex(0);
                combo1.setName("1");
                combo1.addActionListener (new PIOComboListener());
                jPanel1.add(combo1, c);

                c.gridy++;
                c.insets = new Insets(5,10,5,5);
                c.gridx=0;
                JLabel label2 = new JLabel("Active level");
                jPanel1.add(label2, c);
                c.gridx++;
                c.insets = new Insets(5,5,5,10);

                combo2 = new JComboBox(comboActiveLevelStrings);
                combo2.setEnabled(false);
                combo2.setSelectedIndex(0);
                jPanel1.add(combo2, c);

                c.gridy++;
                c.insets = new Insets(5,10,5,5);
                c.gridx=0;
                JLabel label3 = new JLabel("Event");
                jPanel1.add(label3, c);
                c.gridx++;
                c.insets = new Insets(5,5,10,10);

                combo3 = new JComboBox(comboEventDOutputStrings);
                combo3.setEnabled(false);
                combo3.setSelectedIndex(0);
                jPanel1.add(combo3, c);

                c.gridy++;
                c.insets = new Insets(5,10,5,5);
                c.gridx=0;
                JLabel label4 = new JLabel("Node");
                jPanel1.add(label4, c);
                c.gridx++;
                c.insets = new Insets(5,5,10,10);

                combo4 = new JComboBox(comboNodeStrings);
                combo4.setEnabled(false);
                combo4.setSelectedIndex(0);
                jPanel1.add(combo4, c);

            jPanelExterno.add(jPanel1, cExterna);

        pioDialog.add(pane);
        pioDialog.pack();
        pioDialog.setLocationRelativeTo(null);
        pioDialog.setVisible(true);
    //...
}   


    class PIOComboListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent a) {
            JComboBox cb = (JComboBox)a.getSource();
            JComboBox target1 = null;
            JComboBox target2 = null;
            JComboBox target3 = null;
            switch(Integer.parseInt(cb.getName())){
                case 1:
                    target1 = combo2;
                    target2 = combo3;
                    target3 = combo4;
                    break;
                default:
                    Register.debug("PIODialog error: No target for comboBoxes");
                    break;
            }

            if(cb.getSelectedIndex()==2){ //Analog input
                target1.setEnabled(false);
                target2.setEnabled(false);
                target3.setEnabled(false);
            }
            else{
                target1.setEnabled(true);
                target2.setEnabled(true);
                target3.setEnabled(true);
                target2.removeAllItems();
                if(cb.getSelectedIndex()==0){
                    for(int i=0; i<comboEventDOutputStrings.length; i++)
                        target2.addItem(comboEventDOutputStrings[i]);
                } else {
                    for(int i=0; i<comboEventDInputStrings.length; i++)
                        target2.addItem(comboEventDInputStrings[i]);
                }
            }

        }
    }

It's basically a GridBagLayout with 6 JPanel with a new GridBagLayout for each one of them. I just wrote jPanel1 here to simplify things. I hope it is not very messy.

Roman Rdgz
  • 12,836
  • 41
  • 131
  • 207
  • This could be related to the layout manager you're using as they treat attributes like preferred size differently. Can you post some code showing how you're adding the component to its parent Container? – Adamski Oct 19 '11 at 07:55
  • @Roman Rdgz question, you want to resize JComboBox in the Container or its Popup or both – mKorbel Oct 19 '11 at 08:01
  • @Adamski I'm using GridBagLayout. Does that help, or still need a code example? – Roman Rdgz Oct 19 '11 at 08:08
  • @mKorbel I'll try to explain myself better: I want the JComboBox to stay with the width it gets automatically from its default contents (the ones showed up when you popup it). – Roman Rdgz Oct 19 '11 at 08:09
  • @Roman Rdgz: Can you post the code you're actually using to add the components to the container? – Adamski Oct 19 '11 at 08:14
  • 1
    that not sscce, I deleted my post – mKorbel Oct 19 '11 at 08:35
  • For better help sooner, post an [SSCCE](http://pscode.org/sscce.html). – Andrew Thompson Oct 19 '11 at 08:35
  • @Roman Rdgz for JComboBox is better to implements ItemListener(fired twice, SELECTED & DESELECTED), – mKorbel Oct 19 '11 at 08:59

3 Answers3

16

Finally I found an easy solution:

jComboBox1.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXX");

And works perfect for what I wanted

Roman Rdgz
  • 12,836
  • 41
  • 131
  • 207
1

NetBeans does this for you with a couple of checkboxes in the component's right-click context menu: Auto Resizing -> Horizontal and Vertical.

I turned them off and compared the NetBeans generated code in my revision control history. There were a surprising number of changes that I could not relate to the size of the component but I did see changes in how the combo box was added to it's containing layout group. essentially,

....addComponent(destinationFolderComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

was changed to

....addComponent(myComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 514, javax.swing.GroupLayout.PREFERRED_SIZE)

JComboBox.setPreferredSize() is never explicitly called, so I assume you get better results from telling the layout manager the preferred size and re-size properties, rather than telling the JComboBox and hoping the layout manager reads those properties behind the scenes.

(by the way, by ....addComponent(), I mean addComponent() is called in a long, cascaded sequence of createParallelGroup() and createSequentialGroup(), starting with a new javax.swing.GroupLayout(myPanel). I presented the short form above because I didn't want to get into the nitty gritty of auto-generated NetBeans code, which I could not begin to write manually or explain. You want the whole thing? You can't handle the whole thing! here it is:

    javax.swing.GroupLayout taskPanelLayout = new javax.swing.GroupLayout(taskPanel);
    taskPanel.setLayout(taskPanelLayout);
    taskPanelLayout.setHorizontalGroup(
        taskPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(taskPanelLayout.createSequentialGroup()
            .addContainerGap()
            .addGroup(taskPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, taskPanelLayout.createSequentialGroup()
                    .addGroup(taskPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jScrollPane1)
                        .addGroup(taskPanelLayout.createSequentialGroup()
                            .addGroup(taskPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addComponent(tagModifierLabel, javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING))
                            .addGap(18, 18, 18)
                            .addGroup(taskPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(destinationFolderComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 514, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(tagModifierTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 514, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addGap(18, 18, 18)
                    .addGroup(taskPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(importFilesButton)
                        .addComponent(selectFilesButton)
                        .addComponent(clearFilesListButton)
                        .addComponent(commitChangesButton)))
                .addGroup(taskPanelLayout.createSequentialGroup()
                    .addComponent(importFilesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(0, 0, Short.MAX_VALUE)))
            .addContainerGap())
    );

)

PMorganCA
  • 730
  • 6
  • 24
0

At the point prior to adding the JComboBox to jpanel1, try setting the fill attribute of the GridBagConstraints to NONE (rather than BOTH). This should (hopefully) prevent the combo-box from resizing.

c.fill = GridBagConstraints.NONE;
jPanel1.add(combo1, c);
Adamski
  • 54,009
  • 15
  • 113
  • 152