В статье от 15 ноября 2005 года Sorting and Filtering Tables было показано как новые функции сортировки и фильтрации моделей компонента JTable в Java SE 6. В Java SE 6 не включены функции фильтрации и сортировки компонента JList. Однако в данной статье рассматриваются способы реализации данных функций в версии J2SE 5.0 для компонента JList.
В этой статье:
Добавлено : 26 Mar 2009, 16:24
Обычно способ фильтрации элементов в длинном списке реализуется при помощи компонента JTextField. Пока пользователь набирает текст в компоненте JTextField, набор элементов, отображаемых в списке, сокращается к набору элементов соответствующих вводимым данным.
Для реализации данной функции компонента JList необходимы два сопутствующих элемента: модель фильтрующая набор элементов на основании некоторого текста и текстовый компонент, вызывающий функцию фильтрации при вводе пользователем текста.
Реализация поля ввода является более легкой задачей, таким образом начнем обзор реализации с нее. Для набора компонентов Swing, моделью компонента JTextField является Document. Для отслеживания ввода в Document, вам необходимо реализовать в модели интерфейс DocumentListener. В нем определены три метода, позволяющие отслеживать события ввода, изменения и удалении текста:
public void insertUpdate(DocumentEvent event)
public void removeUpdate(DocumentEvent event)
public void changedUpdate(DocumentEvent event)
Метод changedUpdate() вызывается при изменении атрибутов модели. Он может не реализовываться. Так как действие фильтрации аналогично для двух оставшихся методов, то они просто вызывают общий метод, создаваемый в настраиваемой модели. Ниже приводится полное описание компонента JTextField, используемого для фильтрации в компоненте JList:
Для того чтобы не ограничиваться использованием компонента JTextField, создаваемого при помощи JList, применяется метод installJTextField(), связующий блок прослушивания событий с соответствующим компонентом. Также реализован метод, удаляющий данное соответствие. Применение данных методов позволяет пользователю компонента JList, поддерживающего фильтрацию, использовать собственный компонент JTextField, вместо создаваемого по умолчанию.
public void installJTextField(JTextField input) { input.getDocument().addDocumentListener(listener); }
public void unnstallJTextField(JTextField input) { input.getDocument().removeDocumentListener(listener); }
Далее рассматривается модель фильтрации. В ней реализуется метод filter() вызываемый методами, реализующими интерфейс DocumentListener. Для реализации данного метода вам необходимо поддерживать два списка элементов: исходный и фильтрованный списки. Применение наследования от класса AbstractListModel, требует от вас реализации нескольких следующих методов:
Конструктора
Реализация метода добавления элементов в модель
getSize() для получения размеров
getElementAt() для получения элемента
В конструкторе создаются два объекта типа List. Не важно, какие объекты хранятся в виде элементов List, поэтому объекты List создаются для хранения типа Object:
Listpublic FilteringModel() { list = new ArrayList(); filteredList = new ArrayList(); }
Добавление элементов в модель производится путем добавления их в исходную модель и затем фильтрацией данной модели. Данный механизм может быть оптимизирован реализацией метода для фильтрации одного элемента при его добавлении, однако в данной реализации при добавлении элемента вызывается метод filter(), который применяется и для фильтрации всего списка. (Заметьте, что метод filter() вызывается и событием реализованным в DocumentListener). Таким образом, даже при добавлении одного элемента происходит фильтрация всего списка, добавляющая каждый элемент, удовлетворяющий критерию поиска в фильтрованный список (который может быть пуст).
public void addElement(Object element) { list.add(element); filter(); }
Возвращаемый размер модели представляет собой размер фильтрованного списка, но не исходного:
public int getSize() { return filteredList.size(); }
Как и в случае с получением размера модели, метод получения элемента из списка возвращает элементы из фильтрованного списка, а не из исходного. Он реализован таким образом, что не нужно просматривать весь список:
И, наконец, в методе filter() реализуется основная работа. Так как вам не известно, будет ли новая строка поиска расширять или сужать набор элементов, то проще всего удалить весь фильтрованный список и добавить элементы, соответствующие критерию поиска, из исходного списка. Соответствие может быть найдено, как в начале строки, так и в любом ее месте. Ниже приводится пример поиска буквы "А". Данный метод позволяет найти элементы начинающиеся с заглавной буквы "А" или имеющие данный символ в любом месте строки.
Поиск в данном методе является чувствительным к регистру. В добавление к реализации начала поиска с начала строки, вы можете также изменить метод для реализации не чувствительного к регистру поиска.
Также вы можете сортировать результаты, после добавления элементов в фильтрованный список. Данное действие требует от вас знания содержания модели. В настоящий момент, поиск использует преобразование методом toString() и не подразумевается, что в нем могут содержаться содержаться элементы совместимого типа, которые также могут быть отсортированы.
Далее представлена полная реализация фильтрующего элемента JList с внутренним классом ListModel. В классе ListModel реализуется интерфейс DocumentListener для текстового компонента. На первый взгляд включение данного класса может показаться излишним, так как фильтрация выполняется для только для данной модели, но на самом деле определение поведения в данной реализации является наиболее верным.
public void changedUpdate(DocumentEvent event) { } } }
Теперь вам необходимо создать тестовую программу. Ключевыми в ней будут следующие шесть строк. В них создается компонент JList, который добавляется в компонент JScrollPane, а затем добавляется связанное текстовое поле:
FilteringJList list = new FilteringJList(); JScrollPane pane = new JScrollPane(list); frame.add(pane, BorderLayout.CENTER); JTextField text = new JTextField(); list.installJTextField(text); frame.add(text, BorderLayout.NORTH);
Основная часть программы добавляет элементы в модель. Ниже представлена модель, состоящая из списка подарков на рождество, имен оленей Санта-Клауса, линий лондонского метро и греческого алфавита.
public class Filters { public static void main(String args[]) { Runnable runner = new Runnable() { public void run() { JFrame frame = new JFrame("Filtering List"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FilteringJList list = new FilteringJList(); JScrollPane pane = new JScrollPane(list); frame.add(pane, BorderLayout.CENTER); JTextField text = new JTextField(); list.installJTextField(text); frame.add(text, BorderLayout.NORTH);
Скомпилируйте классы FilteringJList и Filters. Затем запустите Filters и вы должны получить фильтрующий компенет JList.
Если элементы в вашем списке имеют верное отображение при вызове метода toString(), то данный подход фильтрации в компоненте JList, использующий связанный компонент JTextField, работает верно. Для более сложных операций фильтрации, можно создать интерфейс Filter, который передается в модель при операции фильтрации.
Единственная вещь, которая не рассматривается в данном примере - это управление выбором. По умолчанию, компонент JList не изменяет выбор при изменении содержания списка модели. В зависимости от желаемого поведения, при фильтрации может сохранятся выбранный элемент или выделятся первый элемент из списка.
Хотя исходный компонент JList и не поддерживает фильтрацию напрямую, в нем существуют методы ее реализации. Если вам не подходит поведение по умолчанию, то вы можете переопределить метод getNextMatch() (добавлен в J2SE 1.4).
В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.
Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.
1 Введение 2 Правила визуализации и пример 3 Совмещение изображений в оперативной памяти 4 Постепенное исчезновение изображения 5 Ссылки и дополнительная информация
В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.
Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.
В статье от 16 марта 2004 года Best Practices in Exception Handling были описаны приемы обработки исключений. В данной статье вы изучите новый способ обработки исключений при помощи класса UncaughtExceptionHandler добавленного в J2SE 5.0.
С кодировками в java плохо. Т.е., наоборот, все идеально хорошо: внутреннее представление строк – Utf16-BE (и поддержка Unicode была с самых первых дней). Все возможные функции умеют преобразовывать строку из маленького регистра в большой, проверять является ли данный символ буквой или цифрой, выполнять поиск в строке (в том числе с регулярными выражениями) и прочее и прочее. Для этих операций не нужно использовать какие-то посторонние библиотеки вроде привычных для php mbstring или iconv. Как говорится, поддержка многоязычных тестов “есть в коробке”. Так откуда берутся проблемы? Проблемы возникают, как только строки текста пытаются “выбраться” из jvm (операции вывода текста различным потребителям) или наоборот пытаются в эту самую jvm “залезть” (операция чтения данных от некоторого поставщика).