简体   繁体   English

如何在jlist内的Java中显示文件名的短版本

[英]How can I display a short length version of a file name in java inside of a jlist

I have a JList that displays a filelist. 我有一个显示文件列表的JList。 The style I have it set to looks good with a FileFilter set to only show files and directories with names that are 15 characters long, however I still want to show the files that are longer than that, just show the first 15 characters or so. 我将其设置为FileFilter的样式看起来不错,它只显示名称和名称长度为15个字符的文件和目录,但是我仍然想显示比该名称更长的文件,仅显示前15个字符左右。 Basically, I want it to show this: 基本上,我希望它显示以下内容:

If I have a text file that says "1234567891234567.txt" - that has 20 characters including the ".txt" and it won't show up in the list. 如果我有一个文本文件“ 1234567891234567.txt”-包含20个字符(包括“ .txt”),它将不会显示在列表中。 But I want it to show something like this: 但我希望它显示如下内容:

"12345...567.txt" or something similar. “ 12345 ... 567.txt”或类似的内容。 Is there a way to do this? 有没有办法做到这一点?

Would I have to create a seperate array and copy everything over, and edit the value of the new array to be no longer than 15 characters? 我是否需要创建一个单独的数组并复制所有内容,然后将新数组的值编辑为不超过15个字符? I tried looking for a function that would change the name of the file but I couldn't find any. 我试图寻找一个可以更改文件名的函数,但找不到任何函数。 Suggestions? 有什么建议吗?

You can check the length of file name and abbreviate it if it contains more than 20 characters, like the method below: 您可以检查文件名的长度,如果文件名超过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"));
}

Please note that it won't work if the extension itself is more than 20 characters or file name does not have any extension. 请注意,如果扩展名本身超过20个字符或文件名没有任何扩展名,它将无法使用。 However, you can modify it as per your requirement. 但是,您可以根据需要对其进行修改。

Coming up with an abbreviated string that will fit in a certain amount of space isn't as trivial as it may sound. 提出一个可以容纳一定空间的缩写字符串并不是听起来那么简单。 Sure, you could just make sure your text is no longer than 15 characters, but all Swing look-and-feels assign a variable-width font to JLists. 当然,您可以确保您的文本不超过15个字符,但是所有Swing外观都为JLists分配了宽度可变的字体。 The system look-and-feel will use whatever font the underlying desktop uses for lists, which also is a variable-width font in all desktops I'm aware of. 系统外观将使用底层桌面用于列表的任何字体,这也是我所知道的所有桌面中的可变宽度字体。

Which means, the 20-character string IIIIIIIIIIIIIIII.txt and the 20-character string WWWWWWWWWWWWWWWW.txt are not the same width. 这意味着,20个字符的字符串IIIIIIIIIIIIIIII.txt和20个字符的字符串WWWWWWWWWWWWWWWW.txt是不一样的宽度。 Truncating each of them to fit in the JList's space will not be as simple as making them 15 characters long. 截断它们以适合JList的空间不会像使它们长15个字符那样简单。

Fortunately, you can use a FontMetrics to calculate a string's visual size. 幸运的是,您可以使用FontMetrics来计算字符串的可视大小。

The simplest, though hardly most efficient, algorithm is to whittle down a string one character at a time until it fits in the JList's width: 最简单(尽管效率最高)的算法是一次将字符串缩减为一个字符,直到适合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;
}

(Notice that “…” is not three period characters, but rather the ellipsis character . What's the difference? The ellipsis is kerned differently, justified differently, read by screen readers differently, can't be broken up by word-wrap, and is simply the correct punctuation. You wouldn't use two apostrophes to represent a double-quote.) (请注意,“ ...”不是三个句点字符,而是省略号字符 。有什么区别?省略号有不同的字距,对齐的原因,屏幕阅读器的读取方式也不同,不能通过自动换行拆分,只是正确的标点符号。您不会使用两个撇号来表示双引号。)

I naïvely start by replacing the center character in each string, regardless of the width of the characters on either side of that character, but a more intelligent and possibly more visually pleasing approach would be to use the character visually located at the center, using TextLayout.hitTestChar . 我天真地从替换每个字符串中的中心字符开始,而不管该字符两边的字符的宽度如何,但是更明智且可能更令人愉悦的方法是通过TextLayout使用视觉上位于中心的字符.hitTestChar

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

相关问题 如何在 JList 中显示数组列表? - How can I display an arraylist in a JList? 如何将文件内容放入JList - How can I put the file contents in to a JList 如何在JList中显示File []数组 - How to display a File[] array in a JList 有没有一种方法可以用Java生成文件名的8.3或“短”(Windows)版本? - Is there a way to generate the 8.3 or 'short' (Windows) version of a file name in Java? 在 JList 中显示文件对象的简单名称 - Display Simple Name of File Object in JList 我想将动作侦听器从一个JList添加到另一个JList,并且JList如何在没有任何文本的情况下出现? - I want to add an action listener from one JList to another JList and how can a JList appear with out any text inside? 如何在Java Swing中将数据从文本文件加载到Jlist? - How can i load data from text file to Jlist in java swing? 如何在JTable单元内呈现JList? - How can I render a JList inside a JTable cell? java我如何检查文件名并使用FileResource auxFr = new FileResource(“ / testing / yob” + auxYear +“ short.csv”)打开; - java how can i check a file name and open with FileResource auxFr = new FileResource(“/testing/yob” + auxYear + “short.csv”); 如何将元素从Jlist_1添加/删除到Jlist_2(Java netbeans) - How can I add/remove Elements from Jlist_1 to Jlist_2 (Java netbeans)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM