为什么DocumentFilter没有给出预期的结果? [英] Why does the DocumentFilter not give the intended result?

查看:106
本文介绍了为什么DocumentFilter没有给出预期的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这一定是代码中的一个简单错误,或者是我的误解,但是我无法获得DocumentFilter来检测insertString事件.下面是一个用于大写字母的简单过滤器,但这并不像insertString(..)方法似乎从未被调用那样重要!

I figure this must be a simple mistake in the code or a misunderstanding on my part, but I cannot get a DocumentFilter to detect insertString events. Below is a simple filter for upper case letters, but that is not as important as the fact that the insertString(..) method never seems to be called!

为什么不调用DocumentFilterinsertString(..)方法?

过滤器应用于顶部的JTextField.每次调用insertString(..)时,都应将信息附加到CENTER中的JTextArea.目前,在文本字段中没有可导致将文本附加到文本区域的操作.

The filter is applied to the JTextField at the top. Every time insertString(..) is called, it should append information to the JTextArea in the CENTER. At the moment, there is no action in the text field that causes text to be appended to the text area.

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.text.*;

public class FilterUpperCaseLetters {

    private JComponent ui = null;
    private final JTextField textField = new JTextField(25);
    private final JTextArea textArea = new JTextArea(5, 20);

    FilterUpperCaseLetters() {
        initUI();
    }

    public void initUI() {
        // The document filter that seems to do nothing.
        DocumentFilter capsFilter = new DocumentFilter() {
            @Override
            public void insertString(
                    DocumentFilter.FilterBypass fb,
                    int offset,
                    String string,
                    AttributeSet attr) throws BadLocationException {
                textArea.append("insertString! " + string + "\n");
                if (!string.toUpperCase().equals(string)) {
                    textArea.append("Insert!\n");
                    super.insertString(fb, offset, string, attr);
                } else {
                    textArea.append("DON'T insert!\n");
                }
            }
        };
        AbstractDocument abstractDocument
                = (AbstractDocument) textField.getDocument();
        abstractDocument.setDocumentFilter(capsFilter);

        ui = new JPanel(new BorderLayout(4, 4));
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));

        ui.add(textField, BorderLayout.PAGE_START);
        ui.add(new JScrollPane(textArea), BorderLayout.CENTER);
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                FilterUpperCaseLetters o = new FilterUpperCaseLetters();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

推荐答案

文本组件使用replaceSelection(...)方法,该方法将依次调用AbstractDocumentreplace(...)方法,该方法将调用AbstractDocumentreplace(...)方法. DocumentFilter.

The text components use the replaceSelection(...) method which will in turn invoke the replace(...) method of the AbstractDocument which will invoke the replace(...) method of the DocumentFilter.

仅当使用Document.insertString(...)方法直接更新Document时才调用DocumentFilterinsertString(...)方法.

The insertString(...) method of the DocumentFilter is only called when you use the Document.insertString(...) method to directly update the Document.

因此实际上,您需要重写这两种方法以确保完成大写转换.

So in reality you need to override both methods to make sure the upper case conversion is done.

一个简单的示例,展示了如何轻松实现这两种方法:

A simple example showing how to easily implement both methods:

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class UpperCaseFilter extends DocumentFilter
{
    public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
        throws BadLocationException
    {
        replace(fb, offs, 0, str, a);
    }

    public void replace(FilterBypass fb, final int offs, final int length, final String str, final AttributeSet a)
        throws BadLocationException
    {
        if (str != null)
        {
            String converted = convertString(str);
            super.replace(fb, offs, length, converted, a);
        }
    }

    private String convertString(String str)
    {
        char[] upper = str.toCharArray();

        for (int i = 0; i < upper.length; i++)
        {
            upper[i] = Character.toUpperCase(upper[i]);
        }

        return new String( upper );
    }

    private static void createAndShowGUI()
    {
        JTextField textField = new JTextField(10);
        AbstractDocument doc = (AbstractDocument) textField.getDocument();
        doc.setDocumentFilter( new UpperCaseFilter() );

        JFrame frame = new JFrame("Upper Case Filter");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout( new java.awt.GridBagLayout() );
        frame.add( textField );
        frame.setSize(220, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args) throws Exception
    {
        EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }

}

这篇关于为什么DocumentFilter没有给出预期的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆