0

自定义单元格渲染器可以定义像表单这样的对象的属性吗?

我一直在寻找一种方法来定义 a 的元素JList以反映对象的当前状态,而不是简单地使用一串信息。即使用单选按钮、文本框和标签代替文本。以像模板一样的预格式化方式。

我需要在列表中显示的项目是轮班时间段,每个时间段代表开始和结束时间以及各种布尔属性。如果我可以使用组件来显示每个对象的状态,以便有人可以选择它,那就更好了。当它被选中时,编辑将在列表下完成,而不是在列表中。只是为了展示。

像这样的东西:

http://i.stack.imgur.com/3MoeQ.png

4

1 回答 1

2

如果您只想在 JTable 单元格内渲染摆动组件,那么没问题:只需JPanel从单元格渲染器返回相关实例即可。但是,如果您希望内容完全成熟,则可能会遇到问题 interactable JPanel

本质上,问题是这样的:(JList并且,作为参考)JTable使用从单元格渲染器返回的面板来渲染项目。渲染完成后,该实例将被丢弃。这意味着您不能从外部更改从单元格渲染器返回的组件之一的状态并期望它在表中更新。

但是,您可以在某些情况下摆脱它,因为一旦用户单击单元格,列表就会进入编辑模式,此时用户正在编辑的单元格实际上包含摆动组件的真实实例,而不仅仅是渲染他们。

我发现使用自定义布局管理器来完成这样的任务通常会更好——甚至更简单。一个例子:

static class ListLayout implements LayoutManager {
    private final int myItemHeight;

    public ListLayout(int itemHeight) {
        myItemHeight = itemHeight;
    }

    @Override
    public void addLayoutComponent(String name, Component comp) {
    }

    @Override
    public void removeLayoutComponent(Component comp) {
    }

    public Dimension preferredLayoutSize(Container parent) {
        int h = 0;
        int w = 0;
        for (Component c : parent.getComponents()) {
            h += c.getPreferredSize().height;
            w = Math.max(w, c.getPreferredSize().width);
        }
        return new Dimension(w, h);
    } 

    public Dimension minimumLayoutSize(Container parent) {
        int w = 0;
        for (Component c : parent.getComponents()) {
            w = Math.max(w, c.getMinimumSize().width);
        }
        return new Dimension(w, 0);
    }

    public void layoutContainer(Container parent) {
        int y = 0;
        // Note: should really deal with parent's border insets here as well
        // Additionally, can add fields like padding, margin, etc. to make this
        // class more generally useful
        for (Component c : parent.getComponents()) {
             c.setBounds(0, y, parent.getWidth(), myItemHeight);
             y += myItemHeight;
        }
    }
}

和调用代码:

    JFrame frame = new JFrame();
    JPanel content = new JPanel();
    content.setLayout(new ListLayout(25));
    JScrollPane scroll = new JScrollPane(content);

    for (int i = 0; i < 20; ++i) {
        content.add(new JButton(Integer.toString(i)));
    }

    frame.setContentPane(scroll);
    frame.pack();
    frame.setVisible(true);

当然,这样做你会失去JList选择高亮等附加功能,所以这完全取决于你想要做什么。但是,上面的内容将在类似列表的布局中为您提供完全可交互的组件。

于 2016-07-17T00:11:27.987 回答