【问题标题】:How to get type of JTextfield from DocumentFilter如何从 DocumentFilter 获取 JTextfield 的类型
【发布时间】:2017-11-02 10:02:41
【问题描述】:

问题: 我想知道我们是否可以从 DocumentFilter 中获取 JTextfield 类型??
我已经阅读了 java 文档并进行了很多搜索,但没有找到任何信息。

需要: 我在 2 个 JTextfields 上设置了相同的 DocumentFilter。当事件发生时,在 DocumentFilter 的“替换”方法中,我想知道对哪个文本字段导致事件的操作。

用例: 我有大约 15 个 texfields(将来可能会增加),我想单独检查所有这些:
- 输入的最大文本长度
- 只能输入某些字符(所有文本字段都一样)
例如:textfield1 最多可占用 10 个字符,但 textfield2 最多可占用 5 个字符。

到目前为止我做了什么:
我为每个文本字段创建了单独的过滤器,这会导致大量冗余代码并增加处理的复杂性,以备将来使用。

期待任何帮助。 :-)

【问题讨论】:

  • 不,您无法访问它。 DocumentFilter 是模型的一部分(Document),JTextField 是控制器。
  • @SergiyMedvynskyy 很抱歉没有找到你。 :-(
  • @Aman 我认为他指的是DocumentFilter 类中没有可用于获取“替换事件”(不是事件)的来源的方法,类似于getSource ()getComponent ()。例如,您可以在文本字段中添加 CaretListener,但最好明确您想要实现的目标。
  • @Ansharja 我已经在问题中写下了需求。
  • @Aman 你说你想知道哪个文本字段导致了“事件”。我在问你:为什么?您是否需要文档过滤器在两个文本字段之间以不同的方式操作?然后,您可以有两个扩展文档过滤器的类,也许还有一个超类,您可以在其中保持它们之间的共同逻辑。输入字符时是否需要执行操作?再一次,您可以在您的字段上注册一个侦听器。其他原因?由于您无法获得想要的东西(从过滤器中检查来源),我们需要知道您真正想要实现的目标以找到不同的解决方案

标签: java swing jtextfield documentfilter


【解决方案1】:

好的,现在您的需求更清楚了,但是再一次,您不能(也不应该)检查您在 DocumentFilter 中输入的文本字段来决定在您的 replace () 方法中做什么.

可能的解决方案:创建您自己的DocumentFilter 类,传递您需要的所有参数(最大文本长度,可能还有一个禁止字符数组,或其他任何东西)。 您的所有文本字段都将有一个独特的 DocumentFilter 实例,并设置参数以满足您的需求。这样,您将获得一个没有冗余代码的干净解决方案。

例如:

import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;
public class FilterTextField
{
    public static void main (String [] a) {
        SwingUtilities.invokeLater (new Runnable () {
            @Override public void run () {
                createAndShowGUI ();
            }
        });
    }
    private static void createAndShowGUI () {
        JFrame frame = new JFrame ("Test");
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        frame.setContentPane (new MainPanel ());
        frame.pack ();
        frame.setLocationRelativeTo (null);
        frame.setVisible (true);
    }
}
class MainPanel extends JPanel
{
    public MainPanel () {
        super (new GridLayout (3, 1, 0, 20));

        JTextField t1 = new JTextField (20);
        JTextField t2 = new JTextField (20);
        JTextField t3 = new JTextField (20);

        ((AbstractDocument) t1.getDocument ()).setDocumentFilter (new MyDocumentFilter (5));
        ((AbstractDocument) t2.getDocument ()).setDocumentFilter (new MyDocumentFilter (10, '!', '?'));
        ((AbstractDocument) t3.getDocument ()).setDocumentFilter (new MyDocumentFilter (15, new char [] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}));

        add (t1);
        add (t2);
        add (t3);

        setBorder (new EmptyBorder (20, 20, 20, 20));
    }


}
class MyDocumentFilter extends DocumentFilter
{
    private char [] forbiddenCharacters;
    private int maximumLength;

    public MyDocumentFilter (int maximumLength, char ... forbiddenCharacters) {
        this.maximumLength = maximumLength;
        this.forbiddenCharacters = forbiddenCharacters;
    }
    @Override public void replace (FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
        // Get the full text you would have after replacement
        Document document = fb.getDocument ();
        String fullText = new StringBuilder (document.getText (0, document.getLength ())).replace (offset, offset + length, text).toString ();
        // Check your requirements ...
        if (fullText.length () <= maximumLength) {
            if (forbiddenCharacters != null) {
                for (char c : forbiddenCharacters) if (fullText.indexOf (c) > -1) return;
            }
            // Replace method is called only if your requirements are met.
            super.replace (fb, offset, length, text, attrs);
        }
    }
}

【讨论】:

  • 这是一个可行的解决方案。也许对代码 cmets 进行更多澄清也会对其他人有所帮助。谢谢:-)
  • @Aman 我很高兴它有帮助。你认为我应该把更多的cmets放在哪里澄清?
  • MyDocumentFilter 参数可能有一些解释。另一个是 String fullText 行,因为在那一行中发生了很多事情。 :-P
  • @Aman 我认为通过检查DocumentFilter replace 方法和varargs 用法的文档很清楚
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-07
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
相关资源
最近更新 更多