Исправить ширину JComboBox


У меня есть JComboBox с некоторыми опциями. Когда я делаю выбор в другом компоненте, я изменяю содержимое JComboBox. Сначала я вызываю метод removeAllItems(), а затем добавляю одну за другой строки, которые мне нужны сейчас.

Проблема в том, что по умолчанию у меня было несколько вариантов, и один из них был большим текстом, поэтому JComboBox получил ширину, необходимую для правильного отображения этого варианта. Когда я изменяю содержимое JComboBox, эта опция текста исчезает, и теперь меньший текст дает ширину JComboBox, так что когда я меняю содержимое, оно становится меньше.

Мой первый подход был вызовом myComboBox.setPreferredSize(myComboBox.getSize()), а затем его размеры фиксируются, но не правильно: он становится немного меньше по высоте и ширине. Я думаю, что это потому, что я использую Nimbus Look&Feel, и размеры, которые я получаю из метода getSize(), являются теми, которые задаются Java default Look%Feel.

Я также пытался myCombo.setPreferredSize(new Dimension(myCombo.getHeight(), myCombo.getWidth())) с теми же результатами.

Как я могу подойти к этой проблеме?

Я добавляю пример кода того, как я использую Расположение:

    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]);
                }
            }

        }
    }

Это в основном GridBagLayout с 6 JPanel с новым GridBagLayout для каждого из них. Я просто написал jPanel1 здесь, чтобы упростить вещи. Я надеюсь, что это не очень грязно.

3 4

3 ответа:

Наконец я нашел простое решение:

jComboBox1.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXX");

И работает идеально для того, что я хотел

В точке, предшествующей добавлению JComboBox в jpanel1, попробуйте установить атрибут fill GridBagConstraints в NONE (вместо BOTH). Это должно (надеюсь) предотвратить изменение размера поля со списком.

c.fill = GridBagConstraints.NONE;
jPanel1.add(combo1, c);

NetBeans делает это за вас с помощью нескольких флажков в контекстном меню правой кнопки мыши компонента: Auto Resizing - > Horizontal и Vertical.

Я выключил их и сравнил код, сгенерированный NetBeans в моей истории контроля версий. Там было удивительное количество изменений, которые я не мог связать с размером компонента, но я видел изменения в том, как поле со списком было добавлено к содержащей его группе макетов. по существу,
....addComponent(destinationFolderComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

Был изменен на

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

JComboBox.setPreferredSize() никогда не вызывается явно, поэтому я предполагаю, что вы получите лучшие результаты, сообщив менеджеру макета предпочтительный размер и свойства повторного размера, а не сообщив JComboBox и надеясь, что менеджер макета прочитает эти свойства за кулисами.

(кстати, под ....addComponent() я имею в виду addComponent() называется длинная каскадная последовательность createParallelGroup() и createSequentialGroup(), начинающаяся с new javax.swing.GroupLayout(myPanel). Я представил короткую форму выше, потому что не хотел вдаваться в подробности. автоматически сгенерированный код NetBeans, который я не мог начать писать вручную или объяснить. Ты хочешь получить все целиком? Ты не можешь справиться со всем этим! вот оно:

    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())
    );

)