Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Combo box popup width adjusting no longer work in 1.0.6_26-b03

yccheokAug 8 2011 — edited Sep 24 2011
Previously, I was able to adjusting combo box popup's width, by referring to the technique described in [http://tips4java.wordpress.com/2010/11/28/combo-box-popup/|http://tips4java.wordpress.com/2010/11/28/combo-box-popup/]. During that time, I was using 1.0.6_24-b07.

However, after I update my Java runtime to 1.0.6_26-b03, things broke.

Here is the screen shoot.

[Workable screen shoot|http://i.imgur.com/0elo7.png]
[Not workable screen shoot|http://i.imgur.com/BeKMy.png]

Here is the code snippet to demonstrate this problem.
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * NewJFrame.java
 *
 * Created on Aug 9, 2011, 4:13:41 AM
 */

package experiment;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.BasicComboPopup;

/**
 *
 * @author yccheok
 */
public class NewJFrame extends javax.swing.JFrame {
    /**
     * Adjust popup for combo box, so that horizontal scrollbar will not display.
     * 8039483
     * http://www.camick.com/java/source/BoundsPopupMenuListener.java
     *
     * @param comboBox The combo box
     */
    public static void adjustPopupWidth(JComboBox comboBox) {
        if (comboBox.getItemCount() == 0) return;
        Object comp = comboBox.getAccessibleContext().getAccessibleChild(0);
        if (!(comp instanceof BasicComboPopup)) {
            return;
        }
        BasicComboPopup popup = (BasicComboPopup)comp;
        JList list = popup.getList();
        JScrollPane scrollPane = getScrollPane(popup);

        // Just to be paranoid enough.
        if (list == null || scrollPane == null) {
            return;
        }

        //  Determine the maximimum width to use:
        //  a) determine the popup preferred width
        //  b) ensure width is not less than the scroll pane width
        int popupWidth = list.getPreferredSize().width
                        + 5  // make sure horizontal scrollbar doesn't appear
                        + getScrollBarWidth(popup, scrollPane);
        Dimension scrollPaneSize = scrollPane.getPreferredSize();
        popupWidth = Math.max(popupWidth, scrollPaneSize.width);

        //  Adjust the width
        scrollPaneSize.width = popupWidth;
        scrollPane.setPreferredSize(scrollPaneSize);
        scrollPane.setMaximumSize(scrollPaneSize);
    }

    /*
     *  I can't find any property on the scrollBar to determine if it will be
     *  displayed or not so use brute force to determine this.
     */
    private static int getScrollBarWidth(BasicComboPopup popup, JScrollPane scrollPane) {
        int scrollBarWidth = 0;
        Component component = popup.getInvoker();
        if (component instanceof JComboBox) {
            JComboBox comboBox = (JComboBox)component;

            if (comboBox.getItemCount() > comboBox.getMaximumRowCount()) {
                JScrollBar vertical = scrollPane.getVerticalScrollBar();
                scrollBarWidth = vertical.getPreferredSize().width;
            }
        }
        return scrollBarWidth;
    }

    /*
     *  Get the scroll pane used by the popup so its bounds can be adjusted
     */
    private static JScrollPane getScrollPane(BasicComboPopup popup) {
        JList list = popup.getList();
        Container c = SwingUtilities.getAncestorOfClass(JScrollPane.class, list);
        return (JScrollPane)c;
    }

    /** Creates new form NewJFrame */
    public NewJFrame() {
        initComponents();
        this.jComboBox1.addPopupMenuListener(getPopupMenuListener());
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jComboBox1 = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4", "This is a very long text. This is a very long text" }));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(82, 82, 82)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(242, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(34, 34, 34)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(246, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }

    private PopupMenuListener getPopupMenuListener() {
        return new PopupMenuListener() {
            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                // We will have a much wider drop down list.
                adjustPopupWidth(jComboBox1);
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {
            }
        };
    }

    // Variables declaration - do not modify
    private javax.swing.JComboBox jComboBox1;
    // End of variables declaration

}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Oct 22 2011
Added on Aug 8 2011
6 comments
1,160 views