简体   繁体   English

在JList中使用自定义JPanel组件

[英]Using custom JPanel components in JList

I need to display JList with custom JPanel components called Item . 我需要使用名为Item自定义JPanel组件显示JList。 These components have unique identification name . 这些组件具有唯一的标识name They may be dynamically added to the JList, or just updated (if already exist). 它们可以动态添加到JList中,也可以更新(如果已经存在)。 I try the following implementation, but it produces just an empty JList. 我尝试以下实现,但它只生成一个空的JList。 Please advise. 请指教。

在此输入图像描述

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

A model is responsible for modeling data, it should NEVER contain UI specific information, as the model shouldn't care how it is to be displayed, it is responsible for transforming the data so it confirms to the view/model contract, in this case the ListModel contract. 模型负责建模数据,它不应该包含UI特定信息,因为模型不应该关心它是如何显示的,它负责转换数据以便它确认视图/模型合同,在这种情况下ListModel合约。

Start by taking a look at 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;
        }
    }
}

Having said all that, I think you would be better off with a using a JTable , see How to Use Tables 说了这么多,我认为使用JTable会更好,请参阅如何使用表

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM