Java 按类别列出

Java 按类别列出,java,swing,jlist,Java,Swing,Jlist,我一直在谷歌上努力寻找一个包含类别的JList实现。我想我可以自己实现一个,但是单元渲染器、模型和所有东西都有点麻烦。所以我转向你 我的问题是:如果我有一个项目列表,分配给类别,我可以在JTree中显示它们。但因为我知道深度永远不会超过2,所以我觉得JTree太过分了。您知道在Swing中(或在某些外部库中)是否有一种简单的方法可以制作如下JList: 其中蓝色字段是标签(不可选择),白色字段是普通列表单元格 提前感谢您提供的任何提示和帮助 也许你可以像这样使用JComboBox。如果没有,它

我一直在谷歌上努力寻找一个包含类别的JList实现。我想我可以自己实现一个,但是单元渲染器、模型和所有东西都有点麻烦。所以我转向你

我的问题是:如果我有一个项目列表,分配给类别,我可以在JTree中显示它们。但因为我知道深度永远不会超过2,所以我觉得JTree太过分了。您知道在Swing中(或在某些外部库中)是否有一种简单的方法可以制作如下JList:

其中蓝色字段是标签(不可选择),白色字段是普通列表单元格


提前感谢您提供的任何提示和帮助

也许你可以像这样使用
JComboBox
。如果没有,它可能会让您了解如何使用
JList

来执行此操作,请改用。它很容易将组作为分支来支持,而项目是叶子。有关更多详细信息和屏幕截图,请参见

渲染器可以根据需要调整外观


正如@Robin所指出的:


我认为单个
JTree
以及带有自定义渲染器的单个
JList
都有相同的缺点:所有节点都是可选的


分支节点是可选择的,以便打开和关闭它们,因此我认为它们是可选择的没有问题。这与带有“标题”的列表略有不同。使用树有缺点(例如,必须对过去的分支组进行制表),也有优点(例如,默认情况下关闭分支,以便通过较少的击键/单击来访问组).

您可以根据自己的需要自行实现。只需让它检查所呈现的项目是父节点还是子节点

不在列表中选择父类别有点棘手。如果选择了父类别,可以修改渲染器使其不显示,也可以覆盖jlist的默认行为

就我个人而言,我会选择JTree,你可以让它看起来和你的列表完全一样,但它增加了很多其他能力,比如3级深度,看起来更灵活

不使用jtree有两个原因

可用性:您可以修改jtree,使其以您想要的方式运行,就像您可以使用列表一样

设计:我不认为在平面列表中存储树(类别和子类别都是树)是更好的设计。

是可能的

  • 反之亦然

  • JPanel的扩展/合并

import java.awt.*;
导入java.awt.event.*;
导入java.awt.font.*;
导入java.awt.image.buffereImage;
导入javax.swing.*;
公共类ExpandingPanels扩展MouseApter{
私人行动小组[]AP;
私人JPanel[]小组;
公共扩展面板(){
assembleActionPanels();
assemblePanels();
}
@凌驾
公共无效鼠标按下(MouseEvent e){
ActionPanel ap=(ActionPanel)e.getSource();
if(ap.target.contains(e.getPoint())){
ap.toggleSelection();
切换面板可见性(ap);
}
}
专用无效切换面板可见性(ActionPanel ap){
int index=getPanelIndex(ap);
如果(面板[索引].isShowing()){
面板[索引].setVisible(假);
}否则{
面板[index].setVisible(true);
}
ap.getParent().validate();
}
私有int getPanelIndex(ActionPanel ap){
对于(int j=0;jimport java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class ExpandingPanels extends MouseAdapter {

    private ActionPanel[] aps;
    private JPanel[] panels;

    public ExpandingPanels() {
        assembleActionPanels();
        assemblePanels();
    }

    @Override
    public void mousePressed(MouseEvent e) {
        ActionPanel ap = (ActionPanel) e.getSource();
        if (ap.target.contains(e.getPoint())) {
            ap.toggleSelection();
            togglePanelVisibility(ap);
        }
    }

    private void togglePanelVisibility(ActionPanel ap) {
        int index = getPanelIndex(ap);
        if (panels[index].isShowing()) {
            panels[index].setVisible(false);
        } else {
            panels[index].setVisible(true);
        }
        ap.getParent().validate();
    }

    private int getPanelIndex(ActionPanel ap) {
        for (int j = 0; j < aps.length; j++) {
            if (ap == aps[j]) {
                return j;
            }
        }
        return -1;
    }

    private void assembleActionPanels() {
        String[] ids = {"level 1", "level 2", "level 3", "level 4"};
        aps = new ActionPanel[ids.length];
        for (int j = 0; j < aps.length; j++) {
            aps[j] = new ActionPanel(ids[j], this);
        }
    }

    private void assemblePanels() {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(2, 1, 2, 1);
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        JPanel p1 = new JPanel(new GridBagLayout());
        gbc.gridwidth = GridBagConstraints.RELATIVE;
        p1.add(new JButton("button 1"), gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        p1.add(new JButton("button 2"), gbc);
        gbc.gridwidth = GridBagConstraints.RELATIVE;
        p1.add(new JButton("button 3"), gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        p1.add(new JButton("button 4"), gbc);
        JPanel p2 = new JPanel(new GridBagLayout());
        gbc.gridwidth = 1;
        gbc.anchor = GridBagConstraints.EAST;
        p2.add(new JLabel("enter"), gbc);
        gbc.anchor = GridBagConstraints.WEST;
        p2.add(new JTextField(8), gbc);
        gbc.anchor = GridBagConstraints.CENTER;
        p2.add(new JButton("button 1"), gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        p2.add(new JButton("button 2"), gbc);
        JPanel p3 = new JPanel(new BorderLayout());
        JTextArea textArea = new JTextArea(8, 12);
        textArea.setLineWrap(true);
        p3.add(new JScrollPane(textArea));
        JPanel p4 = new JPanel(new GridBagLayout());
        addComponents(new JLabel("label 1"), new JTextField(12), p4, gbc);
        addComponents(new JLabel("label 2"), new JTextField(16), p4, gbc);
        gbc.gridwidth = 2;
        gbc.gridy = 2;
        p4.add(new JSlider(), gbc);
        gbc.gridy++;
        JPanel p5 = new JPanel(new GridBagLayout());
        p5.add(new JButton("button 1"), gbc);
        p5.add(new JButton("button 2"), gbc);
        p5.add(new JButton("button 3"), gbc);
        p5.add(new JButton("button 4"), gbc);
        gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        p4.add(p5, gbc);
        panels = new JPanel[]{p1, p2, p3, p4};
    }

    private void addComponents(Component c1, Component c2, Container c, GridBagConstraints gbc) {
        gbc.anchor = GridBagConstraints.EAST;
        gbc.gridwidth = GridBagConstraints.RELATIVE;
        c.add(c1, gbc);
        gbc.anchor = GridBagConstraints.WEST;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        c.add(c2, gbc);
        gbc.anchor = GridBagConstraints.CENTER;
    }

    private JPanel getComponent() {
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(1, 3, 0, 3);
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        for (int j = 0; j < aps.length; j++) {
            panel.add(aps[j], gbc);
            panel.add(panels[j], gbc);
            panels[j].setVisible(false);
        }
        JLabel padding = new JLabel();
        gbc.weighty = 1.0;
        panel.add(padding, gbc);
        return panel;
    }

    public static void main(String[] args) {
        ExpandingPanels test = new ExpandingPanels();
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new JScrollPane(test.getComponent()));
        f.setSize(360, 500);
        f.setLocation(200, 100);
        f.setVisible(true);
    }
}

class ActionPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private String text;
    private Font font;
    private boolean selected;
    private BufferedImage open, closed;
    public Rectangle target;
    private final int OFFSET = 30, PAD = 5;

    public ActionPanel(String text, MouseListener ml) {
        this.text = text;
        addMouseListener(ml);
        font = new Font("sans-serif", Font.PLAIN, 12);
        selected = false;
        setBackground(new Color(200, 200, 220));
        setPreferredSize(new Dimension(200, 20));
        setBorder(BorderFactory.createRaisedBevelBorder());
        setPreferredSize(new Dimension(200, 20));
        createImages();
        setRequestFocusEnabled(true);
    }

    public void toggleSelection() {
        selected = !selected;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        int w = getWidth();
        int h = getHeight();
        if (selected) {
            g2.drawImage(open, PAD, 0, this);
        } else {
            g2.drawImage(closed, PAD, 0, this);
        }
        g2.setFont(font);
        FontRenderContext frc = g2.getFontRenderContext();
        LineMetrics lm = font.getLineMetrics(text, frc);
        float height = lm.getAscent() + lm.getDescent();
        float x = OFFSET;
        float y = (h + height) / 2 - lm.getDescent();
        g2.drawString(text, x, y);
    }

    private void createImages() {
        int w = 20;
        int h = getPreferredSize().height;
        target = new Rectangle(2, 0, 20, 18);
        open = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = open.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(getBackground());
        g2.fillRect(0, 0, w, h);
        int[] x = {2, w / 2, 18};
        int[] y = {4, 15, 4};
        Polygon p = new Polygon(x, y, 3);
        g2.setPaint(Color.green.brighter());
        g2.fill(p);
        g2.setPaint(Color.blue.brighter());
        g2.draw(p);
        g2.dispose();
        closed = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        g2 = closed.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(getBackground());
        g2.fillRect(0, 0, w, h);
        x = new int[]{3, 13, 3};
        y = new int[]{4, h / 2, 16};
        p = new Polygon(x, y, 3);
        g2.setPaint(Color.red);
        g2.fill(p);
        g2.setPaint(Color.blue.brighter());
        g2.draw(p);
        g2.dispose();
    }
}