【问题标题】:Sectioned List in Java/Swing?Java/Swing 中的分段列表?
【发布时间】:2010-10-26 20:26:11
【问题描述】:

我在JList 中有一个项目列表供用户选择。由于项目很多(例如,各州的城市),我想将列表分成几个部分。但是,章节标题不应该是可选的。因此,对于我的城市/州示例,这可能如下所示:

  • 状态 1
    • 城市 1
    • 城市 2
    • 城市 3
  • 状态 2
    • 城市 4
    • 城市5
    • 城市6

通过将JLists 嵌入到自定义ListCellRenderer 中,我自己编写这个并不难,但我想知道那里是否已经有这样的类。

【问题讨论】:

  • banjollity 建议的 JIDE 类很棒,但是如果有人可以建议一个纯开源组件,我也会对此感兴趣(我忘了说这是用于开放源项目)。另外,感谢 Tom 将班级名称更正为 ListCellRenderer

标签: java swing jlist segments


【解决方案1】:

JIDE 提供了一个组件,可以让您完全做到这一点。它被称为 GroupList:

【讨论】:

  • 就是这样!谢谢!我曾希望有一些开源的东西(我忘了说这是用于开源项目的),但看起来他们对在开源项目中使用有一个很好的政策。如果有人可以建议一个开源版本,我仍然会很感激。
【解决方案2】:

也许通过使用 JTree ?你描述的是一棵有两个层次的树。

【讨论】:

  • 一棵树会使 UI 过于复杂。外面的树太多了。
  • Tom 是对的,一棵树可能会起作用,但这是错误的比喻。我在问题中的插图不是很好,但是banjolity的屏幕截图说明了我的意思。
【解决方案3】:

我看到这个问题已经得到解答,但我注意到罗伯特评论说他希望有一个开源解决方案。我建议使用 Glazed Lists 的分隔符列表,您可以在此处找到该 API:

http://publicobject.com/glazedlists/glazedlists-1.8.0/api/ca/odell/glazedlists/SeparatorList.html

下面是一些示例代码,它将生成按首字母分组的项目列表:

alt text http://img300.imageshack.us/img300/8977/separatorlist.png

public class SeparatorListTest {

private static Comparator<String> createComparator() {
    return new Comparator<String>() {
        public int compare(String stringOne, String stringTwo) {
            return stringOne.substring(0,1).compareTo(stringTwo.substring(0,1));
        }
    };
}

private static ListCellRenderer createListCellRenderer() {
    return new DefaultListCellRenderer() {
        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

            if (value instanceof SeparatorList.Separator) {
                SeparatorList.Separator separator = (SeparatorList.Separator) value;
                label.setText(separator.getGroup().get(0).toString().substring(0,1));
                label.setFont(label.getFont().deriveFont(Font.BOLD));
                label.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
            } else {
                label.setFont(label.getFont().deriveFont(Font.PLAIN));
                label.setBorder(BorderFactory.createEmptyBorder(0,15,0,0));
            }

            return label;
        }
    };
}

public static void main(String[] args) {
    EventList<String> rawList = GlazedLists.eventListOf(
            "apple", "appricot", "acorn", "blueberry", "coconut", "chesnut", "grape");
    SeparatorList<String> separatorList = 
            new SeparatorList<String>(rawList, createComparator(), 1, 1000);

    JList list = new JList(new EventListModel<String>(separatorList));
    list.setCellRenderer(createListCellRenderer());
    JScrollPane scrollPane = new JScrollPane(list);
    scrollPane.setBorder(null);

    JFrame frame = new JFrame();
    frame.add(scrollPane, BorderLayout.CENTER);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200,200);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

}

【讨论】:

  • 谢谢,这看起来很有趣。最后,我编写了自己的分段列表,因为我不想仅仅为了获得这个组件而包含一个大型库。它有效,但并不完美。 GlazedLists 看起来可能非常符合要求。
  • 你好,publicobject.com/glazedlists/glazedlists-1.8.0/api/ca/odell/… 已经死了,有搬迁吗?
【解决方案4】:

您可以使用 Apple 所称的 SourceList。您可以在 iTunes 和 Mac OS X 的 Finder 中看到它们的作用。这是您描述的问题的优雅解决方案。

用于执行此操作的跨平台、开源 Java Swing 组件如下: http://explodingpixels.wordpress.com/2008/09/08/mac-widgets-for-java/

【讨论】:

  • 这并不是我在这里寻找问题的真正目的 - 但我一直在 Java 中寻找这种东西。好东西,谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
  • 2013-05-22
  • 2011-01-06
  • 1970-01-01
  • 1970-01-01
  • 2016-08-28
  • 2013-03-29
相关资源
最近更新 更多