Почему этот Swing List не отображает свои элементы? - PullRequest
2 голосов
/ 23 февраля 2010

Я почесал голову над этим. Ниже приведен пример работы. У меня есть 2 Swing Lists в макете потока каждый с простой моделью данных. В зависимости от того, как я создаю экземпляр FlowLayout, 2-й список не отображает его элементы. Weird.

import javax.swing.*;
import java.awt.*;

public class ListboxTest2 {

    public static void main(String[] args) {

        JFrame f = new JFrame();
        f.setSize(500, 500);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        // this works
        // panel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));

        // this doesn't
        panel.setLayout(new FlowLayout());

        final JList list1 = new JList();
        list1.setPreferredSize(new Dimension(120, 60));
        final JList list2 = new JList();
        list2.setPreferredSize(new Dimension(120, 60));  

        final String[] strings1 = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10", "Item 11", "Item 12"};
        final String[] strings2 = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10", "Item 11", "Item 12"};

        list1.setModel(new AbstractListModel() {

            public int getSize() {
                return strings1.length;
            }

            public Object getElementAt(int index) {
                return strings1[index];
            }
        });
        panel.add(list1);

        list2.setModel(new AbstractListModel() {

            public int getSize() {
                return strings2.length;
            }

            public Object getElementAt(int index) {
                return strings2[index];
            }
        });
        panel.add(list2);

        f.add(panel);

        f.setVisible(true);
        list1.grabFocus();
        list1.setSelectedIndex(0);
    }

}

Ответы [ 3 ]

2 голосов
/ 23 февраля 2010

Это всегда хорошая практика, чтобы обернуть списки в JScrollPane, так как это позволит вам прокручивать, когда элементы превышают видимую область. Добавьте списки на панель следующим образом.

panel.add(new JScrollPane(list1));
panel.add(new JScrollPane(list2));
2 голосов
/ 23 февраля 2010

Это не имеет ничего общего с менеджером макета. Вам нужно вызвать pack() на JFrame, прежде чем вы сделаете его видимым, в противном случае поведение будет несколько случайным, потому что у вас есть состояние гонки между вашим основным потоком и EDT.

Теоретически все манипуляции с пользовательским интерфейсом должны происходить в EDT, включая исходную настройку. На практике этого можно избежать, выполнив настройку полностью до запуска EDT (что, как я полагаю, обычно происходит, когда первый компонент становится видимым). Я подозреваю, что в вашем коде grabFocus() приводит к тому, что макет пользовательского интерфейса вычисляется в основном потоке, что приводит к состоянию гонки с EDT, запущенным setVisible().

2 голосов
/ 23 февраля 2010

в первой попытке, во втором списке отображается только один элемент. во всех последующих попытках он отображал его правильно. странно.

Я бы попытался переместить setVisible (true) после завершения инициализации.

...