Материал: Портянкин И. Swing

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

290

ГЛАВА 10

В примере мы создаем целых три панели инструментов, которые в итоге должны выглядеть как единое целое. Сами панели инструментов несложны и не требуют особых комментариев: они состоят из настроенных команд Action, кнопок JButton, а также дополнительных компонентов. Здесь мы снова использовали раскрывающийся список JComboBox, но в панели инструментов найдется место для любого компонента, лишь бы он не был чересчур требовательным к пространству контейнера, в противном случае на его фоне потеряются остальные элементы панели. Обратите внимание, что после добавления во вторую панель инструментов раскрывающегося списка мы добавили заполнитель (glue): как оказывается, в качестве менеджера расположения компонента JToolBar используется прекрасно знакомый нам менеджер BoxLayout. Вы можете пользоваться этим фактом для того, чтобы особым образом выстраивать компоненты панели инструментов, если вам это понадобится.

Самое главное — правильно расположить панели инструментов, так чтобы их было удобно добавлять, удалять или перемещать. Первые две панели инструментов мы расположили в панели с горизонтальным блочным расположением, разделив распоркой размером 5 пикселов (для создания панели применялся класс BoxLayoutUtils, описанный в главе 7). Полученную панель и третью панель инструментов мы поместили в панель с вертикальным блочным расположением. Как вы помните, в главе 7 при обсуждении блочного расположения мы отмечали, что у компонентов в контейнерах с таким расположением должно быть согласованное выравнивание, и панели инструментов — не исключение. В нашем примере выравнивание компонентов производится по левому краю. Полученную конструкцию из трех панелей инструментов мы добавляем на север нашего окна, после чего остается запустить программу с примером и посмотреть на результат.

После запуска программы вы увидите картину, довольно часто встречающуюся в современных сложных приложениях: несколько панелей инструментов, отвечающих за решение разных задач, работают как одно целое. Их также можно перетаскивать, хотя перетаскивание (из-за блочного расположения BoxLayout, а не полярного расположения BorderLayout) реализуется не полностью: вам не удастся причалить панели инструментов к другим границам окна или поменять их местами. Впрочем, если вам понадобится подобное поведение, его достаточно просто реализовать самому: следить за перемещениями мыши в слушателе и назначать панелям инструментов подходящие места в контейнере. Также было бы очень удобно добавить к комбинированным панелям инструментов контекстное меню, позволяющее «на лету» выводить новую панель инструментов или прятать одну из присутствующих экране панелей. Вы можете также обратить внимание

Меню и панели инструментов

291

на дополнительные библиотеки от энтузиастов Swing, к примеру, на библиотеку Flamingo, которая предоставляет некоторые довольно впечатляющие расширения для панелей инструментов.

Резюме

Меню — это «визитная карточка» приложения, по нему пользователи судят о его масштабе и возможностях. Каким бы сложным набором функций ваше приложение не обладало, меню Swing позволят обеспечить доступ к ним, причем именно в том виде, который лучше подходит вашему приложению. Панель инструментов — еще одна часть вашего приложения, «бросающаяся в глаза» при знакомстве с ним. Компонент JToolBar библиотеки Swing делает все, чтобы панели инструментов вашего приложения поражали своим удобством и функциональностью.

Глава 11. Списки

В этой главе будут рассмотрены обычные списки JList и раскрывающиеся списки JComboBox библиотеки Swing. Списки JList предназначены для вывода нескольких (чаще всего равноценных) вариантов данных; пользователь сразу видит весь список (или большую его часть), может провести быстрое сравнение альтернатив и выбрать то, что ему необходимо. Возможен выбор и нескольких альтернатив сразу. В отличие от обычного списка JList раскрывающийся список JComboBox чаще всего используется для выбора одного варианта из многих, примерно так же, как это происходит в группе переключателей. Он показывает только выбранный в данный момент элемент, а также имеет небольшую кнопку раскрытия списка, выводящую на экран всплывающее окно с набором альтернатив, которыми можно сменить текущий вариант выбора. Раскрывающийся список допускает и ввод пользователем собственных значений, не представленных во всплывающем окне с возможными альтернативами.

Мы постепенно продвигаемся по библиотеке Swing, и вот уже настает пора знакомиться с первыми компонентами, данные которых полностью хранятся в моделях. Именно в моделях хранятся данные списков и, как мы увидим, это на самом деле удобно

ипридает программе изящество и гибкость. Вы можете раздельно обрабатывать данные

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

Обычные списки JList

Списки JList позволяют выводить на экран перечень некоторых элементов, чаще всего строк, среди которых пользователь может выбрать то, что ему подходит. Список JList нуждается для правильной работы в двух поставщиках данных (моделях): первый поставщик сообщает, какие элементы и в каком порядке будет представлять список, второй — какие элементы являются выбранными. Первая модель, сообщающая списку, какие данные в нем хранятся, должна реализовывать интерфейс ListModel. Как и везде в Swing, вам не обязательно задействовать модель или реализовывать ее с нуля: у вас есть верные помощники в виде специальных конструкторов списка JList и уже имеющихся стандартных моделей. Вторая модель, следящая за состоянием выделенных элементов, реализует интерфейс ListSelectionModel. По умолчанию в списке JList используется стандартная реализация этой модели DefaultListSelectionModel, поддерживающая все самые важные режимы выделения, так что писать ее самому вряд ли понадобится.

Для начала давайте посмотрим, как проще всего создать список JList и как это будет выглядеть. Вот пример:

//SimpleLists.java

//Простейший способ создания списков import javax.swing.*;

import java.util.*; import java.awt.*;

public class SimpleLists extends JFrame {

Списки

293

// данные для списков

private String[] data1 = { "Один", "Два", "Три", "Четыре", "Пять"};

private String[] data2 = { "Просто", "Легко", "Элементарно", "Как дважды два"};

public SimpleLists() { super("SimpleLists"); setDefaultCloseOperation(EXIT_ON_CLOSE); // создаем списки

JList list1 = new JList(data1);

//для второго списка используем вектор

Vector<String> data = new Vector<String>(); data.addAll(Arrays.asList(data2));

JList list2 = new JList(data);

//динамически наполним вектор

Vector<String> big = new Vector<String>(); for (int i=0; i<50; i++) {

big.add("# " + i);

}

JList bigList = new JList(big); bigList.setPrototypeCellValue("12345");

//добавим списки в панель

setLayout(new FlowLayout()); add(list1);

add(list2);

add(new JScrollPane(bigList)); // выведем окно на экран setSize(300, 200); setVisible(true);

}

public static void main(String[] args) { SwingUtilities.invokeLater(

new Runnable() {

public void run() { new SimpleLists(); } });

}

}

В примере мы создаем небольшое окно и добавляем в него три списка JList. Первый список создается на основе массива строк String, второй использует в качестве данных вектор (динамический массив) Vector1 из пакета java.util. Заметьте, как мы задействовали

1 Класс Vector давно устарел, и все мы используем различные реализации списков List. Однако, по историческим причинам, Swing использует именно класс Vector, а поддержку современных списков добавлять в него не стали. Жаль, но ничего не поделаешь.

294

ГЛАВА 11

статический метод класса Arrays для создания вектора на основе еще одного массива строк. Ну и, наконец, третий список демонстрирует динамическое наполнение вектора данными прямо во время работы программы. С его помощью можно видеть, как список JList выводит большое количество элементов. Заметьте, что первые два списка сразу же добавляются в панель содержимого, а третий (большой) список предварительно включается в панель прокрутки JScrollPane. Компоненты Swing по умолчанию не предоставляют возможностей прокрутки содержимого, их необходимо помещать в панель прокрутки, и списки не являются исключением. Обратите также внимание на весьма полезный метод setPrototypeCellValue(). Элементы списка могут иметь разные размеры, поэтому перед выводом их на экран список JList запрашивает их размеры и в качестве своего горизонтального размера выбирает ширину самого большого элемента в списке. Метод setPrototypeCellValue() позволяет этого избежать. Вместо обращения ко всем элементам список будет использовать длину указанного вами объекта (чаще всего строки) и, таким образом, экономить время (это особенно верно для больших списков), а у вас появится возможность легко управлять внешним видом списка. Альтернативой данному методу также могут быть свойства fixedCellWidth и fixedCellHeight. С их помощью вы можете задать фиксированные размеры для ширины и высоты ячеек в пикселах, если уверены, что точно их знаете. Впрочем, задание размеров в пикселах — не лучшая идея в Java, так что метод setPrototypeCellValue() как правило предпочтительнее.

Нетрудно видеть, что в нашем примере нет и намека на модели, а списки тем не менее создаются и выводятся на экран. В этом вся прелесть Swing — вы выбираете тот подход к программированию, который вам больше по вкусу, и не задумываетесь о мелочах. На самом деле использованные нами конструкторы JList создают простую модель с помощью класса AbstractListModel на основе переданных массивов данных, так что от моделей все равно никуда не деться. То же самое можно сказать о модели, хранящей интервалы выделенных элементов списка: по умолчанию применяется стандартная модель, вполне удовлетворяющая основным нуждам.

Запустив программу с примером, вы сможете увидеть, как выглядят и функционируют списки. Заметьте, что во внешнем виде Metal списки без панели прокрутки или какойлибо рамки смотрятся не слишком эффектно, так что даже если список не велик, стоит поместить его в панель прокрутки. Это и улучшит его внешний вид, и позволит лучше контролировать размеры и состояние интерфейса в том случае, если элементы списка добавляются и удаляются динамически, прямо во время работы программы (а сделать это с помощью моделей легко). Работая с примером, вы сможете убедиться, что в списках по умолчанию можно выбирать произвольное количество элементов в произвольном порядке. Чуть позже мы увидим, как настроить параметры выбора элементов списка по своему вкусу.

Источник: https://studfile.net/preview/15935977/