Java DocumentFilter 问题

问题描述 投票:0回答:1

我遇到了 DocumentFilter 的问题(或者至少看起来是导致问题的原因)。

代码本身从文件夹中获取文件,然后允许我重命名它们,我正在努力解决的部分是它还应该检查每个文件以查看它是否遵循特定的命名结构,如果遵循,则应该添加到文本字段。

我有一些 JTextFields 的 Int 和 Size 过滤器,它们看起来工作正常,即它们不会接受任何字母,也不会超过最大长度。我在不同的文本字段上有两个过滤器:serialFilter 和 sciFilter。当我获取字符串并使用 setText 函数时,serialFilter 工作得非常好 - 请记住文本始终等于过滤器的最大大小。但是 sciFilter 不会更新文本。我进行了测试以确保尺寸不超过最大长度。

相关代码如下,如果有人需要更多,请告诉我。

public class NewTest {
    JPanel panel;
    JLabel oldFileName, sciLabel, serialLabel;
    JTextField sciField, serialField;
    JButton accept;
    String sci, serial;

    public NewTest() {
        JFrame frame = new JFrame("Set Drawing Number");
        
        //SEARCH FOLDER
        File f = getFolder();
        //===== ONLY INCLUDE IF 'f' IS A FILE
        FileFilter fileFilter = new FileFilter() {
            public boolean accept(File f) {   
                return f.isFile();
            }
        };
        
        File[] listOfFiles = f.listFiles(fileFilter);
        panel = new JPanel();
        panel.setLayout(null);
        panel.setBounds(700, 300, 0, 0);
        
        //===== SET UP DOCUMENT FILTERS =====
        DocumentFilter sciFilter = new SizeAndIntFilter(5);
        DocumentFilter serialFilter = new SizeAndIntFilter(4);
        
        //==== SETUP JPANEL =====
        sciField = new JTextField(5);
        ((AbstractDocument)sciField.getDocument()).setDocumentFilter(sciFilter);
        sciField.setBounds(110, 55, 45, 25);
        
        serialField = new JTextField(4);
        ((AbstractDocument)serialField.getDocument()).setDocumentFilter(serialFilter);
        serialField.setBounds(175, 55, 41, 25);
        
        oldFileName = new JLabel(listOfFiles[0].getName());
        oldFileName.setBounds(83, 5, 300, 25);
        
        String testThis = listOfFiles[0].getName();
        
        //SPLIT oldFileName BY DELIMITER "-" TO SEE IF IT IS FOLLOWING THE CURRENT NAMING STANDARD
        String[] testThisArray = testThis.split("-");
        
        sciField.setText(testThisArray[1]);
        serialField.setText(testThisArray[2]);
        
        accept = new JButton("Accept");
        accept.setBounds(375, 173, 100, 30);
        accept.addActionListener(new ActionListener(){
            int n = 0;
            public void actionPerformed(ActionEvent e){
                String[] checkNum = {"", ""};
                while(n < listOfFiles.length){
                    n++;
                    if(n < listOfFiles.length){
                        oldFileName.setText(listOfFiles[n].getName());
                        checkNum = listOfFiles[n].getName().split("-");
                        
                    }
                    else{
                        oldFileName.setText("NO MORE FILES");
                    }
                    break;
                }
                
                if(checkNum[1].length() == 5){
                    System.out.println(checkNum[1]);
                    sciField.setText(checkNum[1]);
                }
                
                if(checkNum[2].length() == 4){
                    serialField.setText(checkNum[2]);
                }
            }
        }); 
        
        panel.add(oldFileName);
        panel.add(sciField);
        panel.add(serialField);
        panel.add(accept);
        
        frame.add(panel);
        frame.setSize(500, 250);
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
    

    //===== MAIN =====
    public static void main(String[] args){
        //STARTS SetNumNoCheck()
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new NewTest(); //PUT FILE VARIABLE IN BRACKETS
            }
        }); 
    }
    
    //===== GET FOLDER =====
    public File getFolder(){
        int test = 0;
        //SELECT FOLDER WITH DRAWINGS YOU WISH TO RENAME
        JFileChooser folder = new JFileChooser();
        
        folder.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        folder.setDialogTitle("Select Folder");
        folder.showDialog(null, "SELECT");
        
        File f = folder.getSelectedFile();
        //IF JFileChooser IS CLOSED - PATH WILL BE NULL : CLOSE PROGRAM
        if(f == null){
            System.exit(0);
        }

        return f;
    }
}

//SETS CHARACTER LIMIT & ALLOWS NUMERIC VALUES ONLY
class SizeAndIntFilter extends DocumentFilter {
    private int limit;    
    
    public SizeAndIntFilter(int limit) {
        this.limit = limit;
    }

    @Override
    public void insertString(FilterBypass fb, int offs, String str, AttributeSet a) throws BadLocationException {

        Document doc = fb.getDocument();
        StringBuilder sb = new StringBuilder();
        sb.append(doc.getText(0, doc.getLength()));
        sb.insert(offs, str);

        if (test(sb.toString())) {
            if ((fb.getDocument().getLength() + str.length()) <= limit)
                super.insertString(fb, offs, str, a);
            else
                Toolkit.getDefaultToolkit().beep();
        }
        else {
            //WARN - only numeric values allowed
        }
   }
   
   private boolean test(String text) {
        try {
            Integer.parseInt(text);
            return true;
        } 
        catch (NumberFormatException e) {
            return false;
        }
    }

    @Override
    public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a) throws BadLocationException {
        Document doc = fb.getDocument();
        StringBuilder sb = new StringBuilder();
        sb.append(doc.getText(0, doc.getLength()));
        sb.insert(offs, str);

        if (test(sb.toString())) {
            if ((fb.getDocument().getLength() + str.length()) - length > limit)
                super.replace(fb, offs, length, str.substring(0, limit-fb.getDocument().getLength()), a);
            else if ((fb.getDocument().getLength() + str.length()) - length <= limit)
                super.replace(fb, offs, length, str, a);
            else
                Toolkit.getDefaultToolkit().beep();
        }
        else {
            //WARN - only numeric values allowed
        }   
    }
}

我当然知道这段代码不是最好的编写代码,我知道我确信我正在做一些我不应该做的事情,但如果你能够通过我的代码并且不想谋杀我将不胜感激。

经过一些测试,似乎任何以 1 或 2 开头的数字都可以为 Filter sciField 设置。而过滤器serialField可以以任何数字开头并且似乎工作正常。出现这种情况时:

当我“手动”更改文本 sciField.setText("12345") 当我在serialField上使用sci的过滤器时,它工作正常。 当我在 sciField 上使用任一过滤器时,除非数字以 1 或 2 开头,否则它不起作用。

This is an example of the code running through 3 files

java file swing jfilechooser documentfilter
1个回答
0
投票

向所有提供帮助的人致歉。我刚刚开始编码,所以我对 MRE 的解释是错误的。

当我注意到以 1 和 2 开头的数字有效时,我发现了我应该早点看到的问题。我没有意识到我在下面传递的文本包括设置的值和附加的前一个值 - 使其对于整数来说太大。我把它换成双人间,我们很好。

`

private boolean test(String text) {
    try {
        //Integer.parseInt(text);
        Double.parseDouble(text);
        return true;
    } 
    catch (NumberFormatException e) {
        return false;
    }
}`

再次感谢,我将尽力在将来以正确的格式呈现代码。

© www.soinside.com 2019 - 2024. All rights reserved.