有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在jlist中以java显示文件名的短长度版本

我有一个显示文件列表的JList。我将其设置为的样式看起来很好,文件过滤器设置为仅显示名称长度为15个字符的文件和目录,但是我仍然希望显示长度超过15个字符的文件,只显示前15个字符左右。基本上,我想让它显示:

如果我有一个文本文件,上面写着“1234567891234567.txt”-包含20个字符,包括“.txt”,它不会显示在列表中。但我想让它展示这样的东西:

“12345…567.txt”或类似的东西。有办法做到这一点吗

我是否需要创建一个单独的数组并复制所有内容,并将新数组的值编辑为不超过15个字符?我试图寻找一个函数,可以改变文件的名称,但我找不到任何。建议


共 (2) 个答案

  1. # 1 楼答案

    想出一个能容纳一定空间的缩写字符串并不像听起来那么简单。当然,您可以确保您的文本长度不超过15个字符,但所有Swing look and feels会为jList指定一个可变宽度的字体。系统外观将使用底层桌面用于列表的任何字体,在我所知道的所有桌面中,这也是一种可变宽度字体

    这意味着,20个字符的字符串IIIIIIIIIIIIIIII.txt和20个字符的字符串WWWWWWWWWWWWWWWW.txt的宽度不同。截断每一个字符以适应JList的空间并不像将它们设为15个字符那么简单

    幸运的是,您可以使用FontMetrics来计算字符串的可视大小

    最简单但并非最有效的算法是一次缩减一个字符串,直到它符合JList的宽度:

    static <T> JList<T> createList(Collection<T> items) {
        JList<T> list = new JList<T>(new Vector<T>(items)) {
            private static final long serialVersionUID = 1;
    
            @Override
            public boolean getScrollableTracksViewportWidth() {
                return true;
            }
        };
    
        list.setCellRenderer(new DefaultListCellRenderer() {
            private static final long serialVersionUID = 1;
    
            private Insets insets = new Insets(0, 0, 0, 0);
    
            @Override
            public Component getListCellRendererComponent(JList<?> list,
                                                          Object value,
                                                          int index,
                                                          boolean selected,
                                                          boolean focused) {
                insets = list.getInsets(insets);
                int listWidth =
                    list.getWidth() - insets.left - insets.right - 4;
    
                if (listWidth > 0 &&
                    value != null &&
                    !(value instanceof Icon)) {
    
                    FontMetrics metrics = list.getFontMetrics(list.getFont());
                    Graphics g = list.getGraphics();
    
                    String text = value.toString();
                    while (text.length() > 1 &&
                      metrics.getStringBounds(text, g).getWidth() > listWidth) {
    
                        int midpoint = text.length() / 2;
                        if (text.charAt(midpoint) != '\u2026') {
                            // Replace center character with ellipsis.
                            text = text.substring(0, midpoint) + '\u2026'
                                + text.substring(midpoint + 1);
                        } else {
                            // Remove character before or after ellipsis.
                            if (text.length() % 2 == 0) {
                                midpoint ;
                            } else {
                                midpoint++;
                            }
                            text = text.substring(0, midpoint)
                                + text.substring(midpoint + 1);
                        }
                    }
    
                    value = text;
                    g.dispose();
                }
    
                return super.getListCellRendererComponent(list, value, index,
                    selected, focused);
            }
    
        });
    
        return list;
    }
    

    (请注意,“…”不是三个句号,而是ellipsis character。有什么区别?省略号的排列方式不同,对齐方式不同,屏幕阅读器的阅读方式不同,不能用换行符来拆分,它只是正确的标点符号。你不会用两个撇号来表示双引号。)

    我天真地从替换每个字符串中的中心字符开始,不管该字符两侧的字符宽度如何,但更智能、可能更令人愉悦的方法是使用位于中心的字符视觉,使用TextLayout.hitTestChar

  2. # 2 楼答案

    您可以检查文件名的长度,如果文件名包含超过20个字符,则可以将其缩写,如下所示:

    private static String getShortName(String fileName){
        if(fileName.length() <= 20){
            return fileName;
        }
        String extension = fileName.substring(fileName.lastIndexOf("."));
        String name = fileName.substring(0, fileName.lastIndexOf("."));
        return name.substring(0, 5) + "..." + name.substring(name.length() - 4) + extension;
    }
    
    public static void main(String[] args) throws Exception {
        System.out.println(getShortName("123.txt"));
        System.out.println(getShortName("123rewe.txt"));
        System.out.println(getShortName("123fdsfdsfdasfadsfdsgafgaf.txt"));
    }
    

    请注意,如果扩展名本身超过20个字符,或者文件名没有任何扩展名,则此功能将不起作用。但是,您可以根据需要对其进行修改