1

I get an unexpected result using setVisibleRowCount and setLayoutOrientation on JList. I have following code on JList component:

public class JListDemo extends JPanel {

private DefaultListModel listModel;
private JList list;
private JButton jbAdd;
private JButton jbRemove;

public JListDemo() {
    super();        
    init();
}

private static void createAndShowGUI() {
    JFrame frame = new JFrame("JList Demo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setContentPane(new JListDemo());
    frame.setResizable(false);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

private void init() {
    listModel = new DefaultListModel();
    list = new JList(listModel);
    //list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    list.setVisibleRowCount(6);       
    list.setLayoutOrientation(JList.VERTICAL_WRAP);        
    JScrollPane scrollList = new JScrollPane(list);        
    jbAdd = new JButton("Add");
    jbRemove = new JButton("Remove");

    JPanel buttonPanel = new JPanel();
    buttonPanel.add(jbAdd);
    buttonPanel.add(jbRemove);

    Box displayBox = Box.createVerticalBox();
    displayBox.add(scrollList);
    displayBox.add(buttonPanel);

    add(displayBox);

    bindListeners();
}

private void bindListeners() {
    list.addListSelectionListener(new ListSelectionListener() {

        @Override
        public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting() == false) {
                if (list.getSelectedIndex() == -1) {
                    jbRemove.setEnabled(false);
                } else {
                    jbRemove.setEnabled(true);
                }
            }
        }
    });

    jbAdd.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            String name = JOptionPane.showInputDialog(JListDemo.this, "Enter name for list:", "", JOptionPane.PLAIN_MESSAGE); 
            listModel.addElement(name);                        
        }
    });

    jbRemove.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {

        }
    });
}



public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            createAndShowGUI();
        }
    });
}

When the GUI shows up, I only saw a straight line at JList component. If I comment out the method setLayoutOrientation(JList.VERTICAL_WRAP), then I can see JList component with 6 empty rows visible. Why did this happen? (note: JList is empty).

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
MinhHoang
  • 681
  • 3
  • 9
  • 22
  • 1
    Please provide a [SSCCE](http://pscode.org/). Otherwise we have almost no chance to guess what's going wrong. – Howard Aug 25 '12 at 17:46
  • 1
    Given the API for [`setVisibleRowCount()`](http://docs.oracle.com/javase/6/docs/api/javax/swing/JList.html#setVisibleRowCount%28int%29), how is this result unexpected? – trashgod Aug 26 '12 at 06:36
  • 1
    the problem is a rather weird implementation of getPreferredScrollableViewportSize of JList. To fix, override JList and override as you need it. Note to myself: consider to implement in SwingX. – kleopatra Aug 26 '12 at 13:19

2 Answers2

1

The issue is with the layout of the list itself. If the layout orientation is horizontal, the preferred scrollable viewport size corresponds to the preferred size. For vertical orientation it is actually calculated differently (assuming a fixed cell size times either the actual list size or a default value).

Thus you may either override getPreferredSize or getPreferredScrollableViewportSize to correspond to your choice of sizing.

Howard
  • 38,639
  • 9
  • 64
  • 83
0

You forgot to give the JList a preferred size, so when you call JFrame.pack, it ends up crushing the JList:

private void init() {
  listModel = new DefaultListModel();
  list = new JList(listModel);
  list.setVisibleRowCount(6);
  list.setLayoutOrientation(JList.VERTICAL_WRAP);
  list.setPreferredSize(new Dimension(300, 400)); <---- set preferred size
  //etc.
}
EthanB
  • 4,239
  • 1
  • 28
  • 46
  • ehh ... no: whatever the problem, setXXSize is always wrong - see http://stackoverflow.com/a/7229519/203657. – kleopatra Aug 26 '12 at 13:17