在JList中使用自定义JPanel组件 - java

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

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
    }        
}

参考方案

模型负责对数据建模,因为它永远不应该包含UI特定的信息,因为模型不关心显示方式,它负责转换数据,因此可以确认是否符合视图/模型协定ListModel合同。

首先看一下Writing a Custom Cell Renderer

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

当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java

我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…

Java-父类正在从子类中调用方法? - java

抱歉,我还是编码的新手,可能还没有掌握所有术语。希望您仍然能理解我的问题。我想得到的输出是:"Cost for Parent is: 77.77" "Cost for Child is: 33.33" 但是,我得到这个:"Cost for Parent is: 33.33" "Cost f…

java.net.URI.create异常 - java

java.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…

Java-固定大小的列表与指定初始容量的列表之间的差异 - java

我在理解这一点上遇到了问题。当我们做 List<Integer> list = Arrays.asList(array); 我们不能在该列表上使用添加,删除之类的方法。我知道Arrays.asList()返回固定大小的列表。我不明白的是,如果我们创建一个具有指定初始容量的列表,例如List<Integer> list2 = new A…

我正在尝试从用户那里获取输入并将其传输到文本文件 - java

我正在尝试编写一个聊天机器人,以便从用户那里学到答案,为此,我需要将答案保存到一个文本文件中,稍后再阅读。在代码中,它允许我编写问题,然后不创建文本文件并给出错误。有人可以告诉我我在做什么错。谢谢所有帮助。public static void main(String[] args) { // TODO Auto-generated method stub S…