3

我有一个JTextField textField,我有一个任意的String string

我希望文本字段显示字符串的结尾,但切断它不适合的内容并使用“...”代替它。例如,如果字符串是,"Hello How Are You Doing"那么文本字段可能看起来像

...re You Doing

给定textfieldstring,我该怎么做?

更新:我想这样做的原因是因为它是一个文件选择器,所以我想优先显示文件的结尾。例如,如果用户选择保存在 /Users/Name/Documents/Folder1/Folder2/Folder3/file.txt 那么我想显示结尾,其余不适合的应该替换为“...”

这是完成的地方:

JFileChooser chooser = new JFileChooser();
int response = chooser.showSaveDialog(this);
if(response == JFileChooser.APPROVE_OPTION) {
    File file = chooser.getSelectedFile();
    String string = file.getAbsolutePath();

    fileTextField.setText(/* here's where the code would go */);
}
4

3 回答 3

5

..它是一个文件选择器,所以我想优先显示文件的结尾。

我建议将其作为替代方案,或者将工具提示(路径)放在文件名之后。

文件列表名称

import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import java.io.File;

class FileListName {

    final class FileListCellRenderer extends DefaultListCellRenderer {

        private FileSystemView fsv = FileSystemView.getFileSystemView();

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            JLabel l = (JLabel) c;
            File f = (File) value;
            l.setText(f.getName());
            l.setIcon(fsv.getSystemIcon(f));
            l.setToolTipText(f.getAbsolutePath());

            return l;
        }
    }

    public FileListName() {
        JFileChooser jfc = new JFileChooser();
        jfc.showOpenDialog(null);
        if (jfc.getSelectedFile() != null) {
            File[] f = {jfc.getSelectedFile()};
            JList list = new JList(f);
            list.setVisibleRowCount(1);
            list.setCellRenderer(new FileListCellRenderer());
            JOptionPane.showMessageDialog(null, list);
        }
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                try {
                    // Provides better icons from the FSV.
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                new FileListName();
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}
于 2013-01-07T03:55:58.530 回答
3

String#length您将面临的问题是与像素宽度不匹配的事实。您需要考虑当前字体、组件宽度、图标、图标间距、插图、屏幕 DPI ...... :P

在此处输入图像描述

public class TrimPath {

    public static void main(String[] args) {
        new TrimPath();
    }

    public TrimPath() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());

                File path = new File("C:\\Users\\Default\\AppData\\Local\\Microsoft\\Windows\\GameExplorer");
                TrimmedLabel label = new TrimmedLabel(path.getPath());
                label.setIcon(FileSystemView.getFileSystemView().getSystemIcon(path));

                frame.add(label);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TrimmedLabel extends JLabel {

        private String masterText;

        public TrimmedLabel(String text) {
            super(text);
        }

        @Override
        public void setText(String text) {
            if (masterText == null ? text != null : !masterText.equals(text)) {
                masterText = text;
                super.setText(text);
            }
        }

        @Override
        public String getText() {

            String text = getMasterText();

            if (text != null && text.length() > 0) {
                int width = getWidth();
                Icon icon = getIcon();
                if (icon != null) {
                    width -= (icon.getIconWidth() + getIconTextGap());
                }
                FontMetrics fm = getFontMetrics(getFont());
                if (width > 0 && fm != null) {
                    int strWidth = fm.stringWidth(text);
                    if (strWidth > width) {
                        StringBuilder sb = new StringBuilder(text);
                        String prefix = "...";
                        while (fm.stringWidth(prefix + sb.toString()) > width) {
                            sb.delete(0, 1);
                        }
                        text = prefix + sb.toString();
                    }
                }
            }
            return text;
        }

        public String getMasterText() {
            return masterText;
        }
    }
}
于 2013-01-07T05:29:19.443 回答
0

可以通过设置自己的文档来完成

(这是快速的'n'dirty所以测试很多次)

final int CHAR_DISPLAY_MAX = 10;
final int REPLACE_NUMBER = 3;
final JTextField tf = new JTextField(7);
Document doc = new PlainDocument(){
  public void insertString(int offs, String str, AttributeSet a) throws BadLocationException{
    if (this.getLength() + str.length() > CHAR_DISPLAY_MAX)
    {
      String oldText = tf.getText();
      String newText = oldText+str;
      tf.setText("..."+newText.substring(newText.length() - (CHAR_DISPLAY_MAX-REPLACE_NUMBER)));
      return;
    }
    super.insertString(offs, str, a);
  }
};
tf.setDocument(doc);
于 2013-01-07T04:54:42.827 回答