как отобразить все String elementName в JTree с одинаковой длиной?

Я создал JTree, который показывает список файлов. эти файлы имеют разную длину. Я хочу показать их все одинаковой длины в JTree, например, 20 символов. Если имя больше 20 символов, оно должно появиться во всплывающей подсказке.

Как я могу это реализовать? ниже мой рендерер.

 private static class FileTreeCellRenderer extends DefaultTreeCellRenderer {
    private Map<String, Icon> iconCache = new HashMap<String, Icon>();
    private Map<File, String> rootNameCache = new HashMap<File, String>();

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value,
                                                  boolean sel, boolean expanded, boolean leaf, int row,
                                                  boolean hasFocus) {

        FileTreeNode ftn = (FileTreeNode) value;
        File file = ftn.file;
        String filename = "";
        if (file != null) {
            if (ftn.isFileSystemRoot) {
                filename = this.rootNameCache.get(file);
                if (filename == null) {
                    filename = fsv.getSystemDisplayName(file);
                    this.rootNameCache.put(file, filename);
                }
            } else {
                filename = file.getName();
            }
        }
        JLabel result = (JLabel) super.getTreeCellRendererComponent(tree,
                filename, sel, expanded, leaf, row, hasFocus);
        if (sel)
            this.setFont(getFont().deriveFont(Font.BOLD));
        else
            this.setFont(getFont().deriveFont(Font.PLAIN));
        if (file != null) {
            Icon icon = this.iconCache.get(filename);
            if (icon == null) {
                icon = fsv.getSystemIcon(file);
                this.iconCache.put(filename, icon);
            }
            result.setIcon(icon);
        }
        return result;
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension dim = super.getPreferredSize();
        FontMetrics fm = getFontMetrics(getFont());
        char[] chars = getText().toCharArray();

        int w = getIconTextGap() + 40;
        for (char ch : chars)  {
            w += fm.charWidth(ch);
        }
        w += getText().length();
        dim.width = w;
        return dim;
    }
}

person itro    schedule 03.05.2012    source источник


Ответы (1)


Вы можете настроить текст на этикетке, чтобы ограничить размер, например.

JLabel result = (JLabel) super.getTreeCellRendererComponent(tree,
                filename, sel, expanded, leaf, row, hasFocus);
result.setText( fileName.subString( 0, Math.min( 20, fileName.length() ) );
result.setTooltip( fileName );

Примечание:

Вы переопределяете getPreferredSize без всякой причины, так как тот факт, что рендерер является компонентом, не используется в вашем коде. Вы возвращаете метку в методе getTreeCellRendererComponent

person Robin    schedule 03.05.2012
comment
Я переопределяю getPreferredSize, чтобы получить фиксированную ширину для JTree, в противном случае он случайным образом становится большим или маленьким (я добавил JTree в BorderLayout.WEST). может быть, есть лучший способ сделать это, но я сделал так. Любое предложение будет оценено. - person itro; 03.05.2012
comment
Я получаю следующую ошибку: «Исключение в потоке AWT-EventQueue-1 java.lang.StringIndexOutOfBoundsException: индекс строки вне диапазона: 20 в java.lang.String.substring(String.java:1765) в be.azvub.j2eeoe.util .configtoolscanners.view.FileTreePanel$FileTreeCellRenderer.getTreeCellRendererComponent(FileTreePanel.java:157) ´ - person itro; 03.05.2012
comment
@itro Предпочтительный размер имеет значение только потому, что DefaultTreeCellRenderer возвращает себя при запросе компонента. Я упустил из виду этот факт. И я внесу изменения в свой ответ для этого исключения - person Robin; 03.05.2012