在JList中使用自定义JPanel组件

时间:2014-10-20 22:45:25

标签: java swing jlist

我需要使用名为Item的自定义JPanel组件显示JList。这些组件具有唯一标识name。它们可以动态添加到JList,或者只是更新(如果已经存在)。我尝试以下实现,但它只生成一个空的JList。请指教。

enter image description here

class Item extends JPanel {
    JLabel name = new JLabel(" ");
    JLabel col1 = new JLabel(" ");
    JLabel col2 = new JLabel(" ");    

    Item(){
        setMinimumSize(new Dimension(100, 20));
        setLayout(new BorderLayout());
        add(name, BorderLayout.WEST);
        add(col1, BorderLayout.CENTER);
        add(col2, BorderLayout.EAST);
    }
}

public class Test_List extends JFrame {
    private final JList list = new JList(new Item[0]);
    HashMap<String, Item> map = new HashMap<String, Item>();

    Test_List(){
        setTitle("Test JList");
        setLayout(new BorderLayout());
        add(new JScrollPane(list), BorderLayout.CENTER);
        pack();
    }

    public void update_item(String name, String s1, String s2){
        Item item = map.get(name);
        if (item == null){ // add new
            item = new Item();
            item.name.setText(name);
            map.put(name, item);
            list.add(item);
        }
        item.col1.setText(s1);
        item.col2.setText(s2);
    }

    public static void main(String s[]) {
        final Test_List frame = new Test_List();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                frame.setVisible(true);
            }
        });
        frame.update_item("A", "a", "aa"); // add new item
        frame.update_item("B", "b", "bb"); // add new item
        frame.update_item("A", "aa", "a"); // update existing item
    }        
}

1 个答案:

答案 0 :(得分:7)

模型负责建模数据,它不应该包含UI特定信息,因为模型不应该关心它是如何显示的,它负责转换数据,以便确认视图/模型合同,在这种情况下是ListModel合同。

首先看一下Writing a Custom Cell Renderer

A List

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;

public class TestListCellRenderer {

    public static void main(String[] args) {
        new TestListCellRenderer();
    }

    public TestListCellRenderer() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                DefaultListModel model = new DefaultListModel();
                model.addElement(new Item("A", "a", "aa"));
                model.addElement(new Item("B", "b", "bb"));
                model.addElement(new Item("C", "c", "cc"));
                model.addElement(new Item("D", "d", "dd"));

                JList list = new JList(model);
                list.setCellRenderer(new ItemCellRenderer());

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(list));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class Item {
        private String name;
        private String col1;
        private String col2;

        public Item(String name, String col1, String col2) {
            this.name = name;
            this.col1 = col1;
            this.col2 = col2;
        }

        public String getCol1() {
            return col1;
        }

        public String getCol2() {
            return col2;
        }

        public String getName() {
            return name;
        }

    }

    public static class ItemCellRenderer extends JPanel implements ListCellRenderer<Item>{

        private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
    private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
    protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;

        JLabel name = new JLabel(" ");
        JLabel col1 = new JLabel(" ");
        JLabel col2 = new JLabel(" ");

        public ItemCellRenderer() {
            setLayout(new BorderLayout());
            add(name, BorderLayout.WEST);
            add(col1, BorderLayout.CENTER);
            add(col2, BorderLayout.EAST);
        }

        @Override
        public Dimension getMinimumSize() {
            return new Dimension(100, 20);
        }

        @Override
        public Dimension getPreferredSize() {
            return getMinimumSize();
        }


    protected Border getNoFocusBorder() {
        Border border = UIManager.getBorder("List.cellNoFocusBorder");
        if (System.getSecurityManager() != null) {
            if (border != null) return border;
            return SAFE_NO_FOCUS_BORDER;
        } else {
            if (border != null &&
                    (noFocusBorder == null ||
                    noFocusBorder == DEFAULT_NO_FOCUS_BORDER)) {
                return border;
            }
            return noFocusBorder;
        }
    }

        @Override
        public Component getListCellRendererComponent(JList<? extends Item> list, Item value, int index, boolean isSelected, boolean cellHasFocus) {
            setComponentOrientation(list.getComponentOrientation());

            Color bg = null;
            Color fg = null;

            JList.DropLocation dropLocation = list.getDropLocation();
            if (dropLocation != null
                            && !dropLocation.isInsert()
                            && dropLocation.getIndex() == index) {

                bg = UIManager.getColor("List.dropCellBackground");
                fg = UIManager.getColor("List.dropCellForeground");

                isSelected = true;
            }

            if (isSelected) {
                setBackground(bg == null ? list.getSelectionBackground() : bg);
                setForeground(fg == null ? list.getSelectionForeground() : fg);
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }

            name.setText(value.getName());
            col1.setText(value.getCol1());
            col2.setText(value.getCol2());

            name.setForeground(getForeground());
            col1.setForeground(getForeground());
            col2.setForeground(getForeground());

            setEnabled(list.isEnabled());

            name.setFont(list.getFont());
            col1.setFont(list.getFont());
            col2.setFont(list.getFont());

            Border border = null;
            if (cellHasFocus) {
                if (isSelected) {
                    border = UIManager.getBorder("List.focusSelectedCellHighlightBorder");
                }
                if (border == null) {
                    border = UIManager.getBorder("List.focusCellHighlightBorder");
                }
            } else {
                border = getNoFocusBorder();
            }
            setBorder(border);

            return this;
        }
    }
}

说了这么多,我认为使用JTable会更好,请参阅How to Use Tables