Первый вариант пользовательского интерфейса

Если бы Вы попробовали собрать наш первый поект и запустить его под ОС Windows и при этом закомментировать строки перенаправления вывода данных, то скорее всего Вас постигло большое разочарование — на экране были сплошные закорючки и ничего не было понятно. Вероятнее всего Вы уже догадались, что проблема кроется в том, что текст мы набирали в кодировке Windows, а из командной строки весь вывод шел в кодировке MS-DOS.
Для того, чтобы Вам было понятнее, да и интереснее, давайте сделаем простой пользовательский интерфейс, заодно рассмотрим некоторые моменты создания такого рода приложений.
В данный момент мы не ставим своей целью получить что-то очень законченное — скорее это будет черновик, который мы потом сделаем более привлекательным и более сложным. Но мы сделаем приложение, которое пользуется некоторыми нашими командами — надо же на чем-то проверять наши разработки.

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

  1. Список групп
  2. Список студентов для группы
  3. Элементы для редактирования — добавить, удалить, редактировать данные о студенте
  4. Элементы для работы с группой — удаление всех студентов и перевод студентов в другую группу

В этой части мы не будем реализовывать все команды, но кое-чем все-таки сможем воспользоваться. Давайте рассмотрим более подробно, какие же конкретно элементы управления нам потребуются. В первую очередь отметим, что использовать мы будем более новую библиотеку графических элементов SWING. Тем, кто захочет попробовать свои силы в более старом пакете AWT — придется это сделать самостоятельно. В некоторых случаях пакет AWT просто необходим — когда Вы пишете апплет для выполнения его в броузере, который поддерживает только старую версию JAVA 1.1.
Для показа групп и студентов нам потребуется список. Элементами для команд на редактирование пока будут кнопки. Для ввода информации — диалоговые окна. Ну и конечно же нам потребуется самое главное окно, в котором мы будем выполнять все наши действия.
Самое главное окно обычно наследуется от класса JFrame. Для того, чтобы создать очень простое оконное приложение надо очень мало строк.

 

Небольшой комментарий: В самом конструкторе нашего приложения (MainFrame) мы вызываем только один метод, который уже существует в JFrame — setBounds. Этот метод служит для установки размеров нашего окна.
Ну и конечно же метод main — первой строкой мы создаем объект, во второй строке мы устанавливаем поведение формы при закрытии (в данном случае мы говорим, чтобы при закрытии окна заканчивалось и приложение, а третья строка содержит метод, устанавливающий, что наша форма станет видимой. И все теперь готово. Приложение можно будет запускать.
ЗАМЕЧАНИЕ: Вы явно должны были обратить внимание на несколько необычный вызов в методе main. Такой вызов связан с тем, что все события внутри системы Swing происходят в отдельном треде — Event Dispatching Thread — EDT. Желательно (я бы сказал необходимо) ВСЕ операции с графикой делать в нем, т.к. некоторые операции не являются потоко-защищенными (т.е. если вы будете обращаться к форме из разных тредов, то результат может быть не очень красивый). Если вам пока сложно точно понять принцип такого запуска — просто пользуйтесь им. Позже разберетесь.

Для сборки и запуска нашего простого примера используются команды

javac MainFrame.java
java MainFrame

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

Контейнеры
Для удобства работы Вам полезно будет представлять себе, что каждый элемент пользовательского интерфейса — это реальный объект, который можно положить на экран, который может принимать сообщения, у которого есть определенные свойства и т.д.
Но куда же мы должны класть наши элементы — ведь у нас сейчас перед глазами пустое окно (которое уже можно перемещать по экрану, менять размеры). Как Вы сам догадались — конечно же на окно. Точнее в ту область окна, которая находится под заголовком — так называемая «клиентская область». Если немного подумать, то становится ясно, что элементы можно класть на какие-то другие элементы. И именно те элементы, которые могут содержать в себе другие элементы называются контейнерами. Понятие контейнера очень рапространено — это может быть не только визуальный элемент (Но мы об этом поговорим в другой раз). Контейнером называют практически все, что может содержать и управлять другими элементами.
Чем важно понятие контейнера для визуальных компонентов ? Тем, что с их помощью можно группировать элементы. Вы может положить на один большой контейнер два поменьше и в каждый поместить какие-то элементы. Каждый из маленьких контейнеров может управлять размещением собственных элементов. Когда Вам надо будет разместить много элементов управления на форме — помните о контейнерах, думайте в их терминах. Если вы хотите определенным образом скомпоновать какие-либо элементы — знайте, что Вам потребуется контейнер.
Мы будем использовать самый простой и наверно самый распространенный контейнер — обычную панель — класс JPanel. Именно объект этого класса содержит «клиентская область формы». Доступ к ней осуществляется через вызов getContentPane(). Немного позже Вы увидите пример вызова.

Слушатели — Listeners
Конечно же практически каждый визуальный компонент не просто показывает себя на экране — он должен как-то реагировать на действия пользователя. И в большинстве случаев он это делает — кнопка нажимается, список прокручивается и т.д. Но ведь часто нам нужно не просто нажать кнопку — нам нужно, чтобы за этим нажатием выполнялось то, что нам хочется. Так каким образом можно узнать, что кнопку нажали, что над панелью провели мышкой ?
Для этого существует механизм слушателей — listeners.
Идея очень простая — тот, кто реагирует на какие-либо события содержит список объектов-слушателей, которые хотели бы узнавать о конкретном событии. Та же кнопка при своем нажатии, имея такой список, пробегает по нему и сообщает каждому объекту, который зарегистрировался как слушатель нажатия кнопки (можно зарегистрировать слушатель определенного события, произошедшего с кнопкой — движение мышки, нажатие кнопки мышки вниз и т.д.), что кнопку нажали. Т.к. объекты, которые хотят узнать о событии имеют разных предков (кроме конечно тех, которые произошли непосредственно от Object), то чтобы можно было им сообщать о событии единообразно все эти объекты должны реализовывать какой-то определенный интерфейс. Например для того, чтобы добавить слушателя для кнопки существует интерфейсActionListener (обратите внимание, что сам интерфейс имеет слово Listener — это обычное соглашение по именованию). Там всего один метод — actionPerformed. Также в подавляющем большинстве случаев в метод интерфейса передается параметр, который описывает параметры события. Например при событии «движение» от мышки хорошо передавать координаты мыши. При нажатии кнопки на клавиатуре — код клавиши. И т.д.

Модели
Уже достаточно давно в программирование используется такое понятие как паттерн (шаблон). Паттерны — это набор стандартных решений для стандартных задач. Если Вы хотите подробнее познакомиться с ними — отсылаю Вас к книге Э. Гамма «Приемы объектно-ориентированного проектирования — паттерны проектирования». Знание паттернов проектирования — это большой плюс. Не пренебрегайте ими.
Мы же рассмотрим здесь один такой паттерн — Model-View-Controller. Основная идея этого шаблона состоит в том, что поведение какого-либо сложного компонента системы разбивается на три части — модель, представление и контроллер.
Модель содержит данные, представление показывает, а контроллер реагирует на события. Чаще всего контроллер обрабатывает события и меняет модель, а потом сама модель может используя представление показывать свое содержимое (или контроллер может передать модель представлению, чтобы то модель показало).
Таким образом легко соединять и использовать разные представления для одной модели, а также использовать разные модели для одного представления. По сути это выглядит как если показывать текст в редакторе Notepad или в броузере — содержимое файла остается прежним. Касательно замены модели — в редакторе Word вы можете смотреть разные файлы, но визуально Word со своими компонентами вряд ли изменится сильно.
Мы увидим практическое применение этого несколько позже. А пока надо просто запомнить — если Вы хотите изменить состояние визуального компонента (добавить строки в список или удалить, изменить дерево) ищите у компонента метод getModel и меняйте данные модели. Практически каждый визуальный элемент SWING имеет модель, которая может быть изменена. И уже сама модель путем вызова определенных внутренних методов меняет визуальное представление компонента. Именно через нее Вы можете менять данные, которые отображает визуальный компонент. Не пытайтесь воздействовать непосредственно на элементы, которые Вы передаете в качестве параметров или менять что-либо прямо в визуальном компоненте. Например, элемент списка JList получает в качестве списка Vector. Так вот не пытайтесь менять переданный элемент типа Vector — последствия могут быть самые непредсказуемые. Для корректной работы Вам необходимо получить модель у визуального компонента и работать непосредственно с ней. Несколько позже мы увидим как это происходит — нам же придется менять содержимое списка студентов.
В процессе создания нашего примера мы увидим примеры использования всех трех понятий, которые мы рассмотрели. Правда не в этой части — здесь мы рассмотрим только некоторые.

Давайте для начала создадим достаточно простое приложение, которое не умеет многое. Я здесь преследую две цели:

  1. Не загружать пример. Если сразу дать новичку полный код приложения, то скорее всего он не будет в нем разбираться.
  2. Показать процесс конструирования формы — какие элементы можно использовать, как их располагать на форме, как пользоваться менеджерами разметки. Мы затронем понятие контейнера — сможете посмотреть все на практике.

 

Прежде чем смотреть код — немного слов о менеджере разметки — layout manager. Во-первых, достаточно подробно он рассмотрен здесь:
Что такое LayoutManager
Если же описать это понятие в двух словах, то можно сказать следующее: любой контейнер должен управлять тем, что в нем находится. В одном случае удобно располагать компоненты один под другим, в другом — рядом, в третьем — в виде таблицы. Именно для этой задачи каждый контейнер имеет у себя layout manager — объект, который занимается распределением объектов по контейнеру. Наше приложение сейчас будет уметь мало — мы вернемся к нему в других частях. А пока опишем, что мы собираемся создавать.

Форма будет разделена на две части — верхнюю и нижнюю. На верхней части будет компонент для ввода года. Мы его сделаем в виде числового слайдера (спинера). В общем элемент со стрелками вверх-вниз. Нижняя часть будет несколько сложнее — она поделится на две части. На левой будет список групп, а на правой список студентов. Пока у нас будет полный список. Когда мы будем более подробно рассматривать SWING мы усложним наше приложение.
Ниже приведены наши классы. Student.java и Group.java пока остаются без изменений. А вот в классе ManagementSystem мы удалили метод main. Теперь приведем непосредственно код уже всех наших частей:

Student.java

Group.java

ManagementSystem.java

И наконец класс для нашей формы — StudentsFrame.java — здесь обязательно обратите внимание на комментарии в конструкторе. Именно здесь мы создаем все наши элементы в соответсвии с тем описанием, что приведен выше.

StudentsFrame.java

ВНИМАНИЕ!!!
Возможно, Вы обратили внимание, что класс StudentFrame.java находится в другом пакете — students.frame
Теперь структура нашего каталога выглядит так:

Для сборки нам потребуется команда

 

javac students/frame/*.java students/logic/*.java

Для сборки примера из архива

javac -encoding UTF-8 students/frame/*.java students/logic/*.java

Для запуска наберите следующую команду:

java -cp . students.frame.StudentsFrame

Как видите наше приложение уже что-то может. Если Вы попробуете уменьшить окно, то в какой-то момент увидите, что появяться линейки прокрутки. Конечно, наши данные еще далеки от совершенства и каждый раз будут исчезать из памяти. Для того, чтобы они не исчезали мы используем Часть 3 — Базы данных

Leave a reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.