在JList上使用setVisibleRowCount和setLayoutOrientation的意外结果

时间:2012-08-25 17:33:24

标签: java swing jlist

我在setVisibleRowCount上使用setLayoutOrientationJList获得了意外结果。我在JList组件上有以下代码:

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

当GUI出现时,我只看到JList组件的直线。如果我注释掉方法setLayoutOrientation(JList.VERTICAL_WRAP),那么我可以看到JList组件,其中有6个空行可见。为什么会这样? (注意:JList为空)。

2 个答案:

答案 0 :(得分:1)

问题在于列表本身的布局。如果布局方向是水平的,则首选的可滚动视口大小对应于首选大小。对于垂直方向,实际上计算方式不同(假设固定单元格大小乘以实际列表大小或默认值)。

因此,您可以覆盖getPreferredSizegetPreferredScrollableViewportSize以符合您选择的尺码。

答案 1 :(得分:0)

你忘了给JList一个首选大小,所以当你调用JFrame.pack时,它最终会破坏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.
}