Могу ли я ограничить длину текста в JTextField, который можно рисовать, сохраняя при этом полный текст? - PullRequest
5 голосов
/ 05 августа 2010

У меня есть текстовое поле в приложении.Несмотря на то, что это текстовое поле, пользователи иногда вставляют в него огромное количество текста.Кроме того, другие функции проблемы также устанавливают большие суммы.

Иногда бывает так много текста, что JVM получает нарушение прав доступа в fontmanager.dll.Похоже, Oracle не заинтересован в устранении самой проблемы, поэтому я хотел бы, по крайней мере, попытаться ее избежать.

Ограничение объема текста, вводимого пользователем, очевидно, неприемлемо (в противном случае это будетнаиболее очевидное решение), но допустимо разрешить его установку, а затем отключить текстовое поле.Когда текст связан с моделью, он должен снова содержать полный текст.

Поскольку это по сути ошибка в представлении, я решил, что исправление должно быть в представлении, а не работать вокругэто в модели и добавление туда дополнительных свойств.

Моя первая попытка прошла примерно так:

public class LimitedTextField extends JTextField {
    static final int LIMIT = 10000;
    private String fullString;

    @Override
    public void setText(String text) {
        if (text != null && text.length() > LIMIT) {
            fullString = text;
            setEnabled(false);
        } else {
            fullString = null;
            super.setText(text);
            setEnabled(true);
        }
    }

    @Override
    public String getText() {
        if (fullString != null) {
            return fullString;
        } else {
            return super.getText();
        }
    }
}

Это проходит наивные юнит-тесты, но как только я написал дополнительный тест для BeansBindingЯ обнаружил, что это не работает, потому что BeansBinding не привязывается к свойству text, а привязывается к Document, имитируя свойство text.Так что на самом деле getText () всегда возвращает пустую строку в этом тесте.

Сейчас я пытаюсь создать реализацию Document, которая будет делать то, что я хочу, но, конечно, нелегко сделать этот видтрюк на уровне документа.Я вижу все имеющиеся у него методы, но не могу найти хороший способ ограничить текст, не сделав его недоступным при вызове getText ().

Ответы [ 3 ]

1 голос
/ 05 августа 2010

Вместо использования JTextField, возможно, вы могли бы использовать строку sinTge JTextArea. Затем вы можете вставить символ новой строки в документ. Затем, когда текст будет нарисован, вы увидите только одну строку.

Возможно, вам также потребуется переопределить метод getText (), чтобы удалить символ новой строки. Не уверен, поможет ли это, но может заставить вас думать в другом направлении.

1 голос
/ 05 августа 2010

Документ ограниченной длины действительно легко сделать .Конечно, есть несколько подходов, вот самый простой (работает на производстве в нашей среде):

package com.twist.ui.text.document;

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class LimitedLengthDocument extends PlainDocument {
    private static final long serialVersionUID = 1L;

    private int limit;

    public LimitedLengthDocument(int limit) {
        super();
        this.limit = limit;
    }

    public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {
        if (str == null)
            return;

        // insert the string as usual.
        super.insertString(offset, str, attr);

        // If user tries to paste in a String that will not fit into the textfield, this approach will 
        // insert the text and remove the extra characters from the right.      

        // if resultant doc length is greater than the allowable size, truncate the document.
        if( getLength() > limit  )
            super.remove(limit, getLength() - limit);
    }
}
1 голос
/ 05 августа 2010

Это сложный вопрос, без сомнения.Вы хотите повлиять на рисование поля с минимальным воздействием, за исключением того, что не пытаетесь визуализировать слишком много текста.Единственное предложение, которое у меня есть, это посмотреть на создание собственной стратегии рисования (см. http://forums.sun.com/thread.jspa?threadID=481290) и там, где рисуется текст, просто нарисуйте подмножество символов. Вы можете посмотреть на попытку создания нового UIDelegate длярисование текстового компонента, но это может быть довольно сложно. Этот обзор рисования может помочь вам ориентироваться в отношении пользовательского рисования. Эта статья может помочь вам с тем, как применить пользовательский делегат пользовательского интерфейсаво всех текстовых полях или только в том, которое вы пытаетесь исправить.

...