Как сделать интерфейс для программы

Добавил пользователь Дмитрий К.
Обновлено: 04.10.2024

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

Так как корневой элемент интерфейс — это рабочий стол, рисовать следует именно его, при этом команды должны уходить на драйвер устройства (VideoDevice). Допустим, устройство есть, рабочий стол тоже. Но как их связать вместе? Нужен посредник (Application), который будет готовить девайс и через графический контекст передавать на него команды рендера с рабочего стола. Когда он должен это делать

Постоянно, ведь интерфейс рисуется синхронно с частотой обновления монитора, для этого стоит выделить отдельный поток с бесконечным UI-циклом, где и будет непрерывно происходить рендер. После того как все элементы отрисуются в драйвер устройства, ему необходимо дать команду на отображение полученного изображения на матрице монитора. Это будет ещё одна операция для UI-цикла.

Как работает GUI-приложение

Что ещё может происходить в UI-цикле? Если нам надо переместить окно на рабочем столе или сменить текст в лейбле, добавить дочерний элемент, можем ли мы сделать это во время отрисовки? Очевидно, эти операции могут быть небезопасными. Например, можно добавить элемент в массив childs в тот момент, когда он находится в процессе перечисления, что вызовет ошибку. И это не единственное тонкое место — изменение размеров элементов, текста, цвета и других параметров во время отрисовки могут создать проблемы в коде рендера.

Правильным решением здесь будет синхронизация процесса рендера и модификации параметров элементов интерфейса. Поскольку подобные операции (назовём их invoke) в GUI происходят довольно часто, хорошим решением будет просто выполнять их в том же потоке, что и рендер, непосредственно перед ним. Для этого сделаем очередь операций и выберем метод добавления операции в очередь (invokeLater).

Программист, который хочет провести модификацию иерархии/параметров элементов, должен делать это только внутри таких операций. Кроме того, события ввода (например, с мыши и клавиатуры) также должны обрабатываться в этой очереди. Теперь мы имеем представление о том, как работает GUI-приложение.


Для управления буфером пикселей создан класс Texture. Ещё вы могли заметить, что GraphicsContext потерял свойство offset и теперь всегда рисует в текстуру, начиная с верхнего левого угла (это изменение будет объяснено ниже при рассмотрении алгоритмов полупрозрачности), у него появился метод fill () для монохромной заливки прямоугольной области, а также наследник SafeGraphicsContext. Дело в том, что дочерние элементы зачастую могут выходить за границы своих родителей, следовательно, их пиксели могут отрисоваться в несуществующие области текстуры. Чтобы не производить проверку попадания в границы родителя каждый раз, проще всего делать её на стороне графического контекста.

Барабанная дробь! Вот мы и создали все инструменты, чтобы всё вышесказанное обрело хоть какой-то практический смысл.

По промокоду DEV45 действует скидка 45% на все курсы до 31.10 включительно.

Онлайн-курсы, чтобы стать крутым дизайнером

Пишем собственные элементы интерфейса и рисуем их

Начнём с рабочего стола (Desktop). Это будет просто область, залитая одним цветом, с инструментом для управления окнами приложений. Фактически всё, что нужно для нашего примера, — это механизм выбора и контроля текущего активного окна, а также доставки событий мыши до элементов интерфейса, над которыми они произошли.

Окно приложения (Window) — тоже залитый прямоугольник с границей и заголовком, на котором лежит кнопка закрытия окна. Кнопка (Button) — это прямоугольная область, которая меняет цвет при нажатии на неё и посылает событие (callback) по окончанию нажатия.

И мышь! Возьмите её в руки, повертите, определите, что вы можете с ней сделать: мышь можно перемещать и нажимать на ней кнопки. Отлично, значит это и будет интерфейсом нашего драйвера. Поскольку мышь — устройство ввода, то для него мы не отправляем управляющие команды и лишь принимаем их через MouseDeviceCallback. Отметим, что для драйвера мыши могут существовать и команды управления: установка позиции курсора, чувствительности и т. д.

Осталось доставить входящие в приложение события мыши (MouseEvent) до их конечных получателей — элементов интерфейса. Первым делом надо решить, кто будет управлять этой доставкой — это должен быть класс, который имеет доступ ко всей иерархии элементов, а в нашем случае это как раз рабочий стол, приложение будет сообщать ему о новом событии мыши, вызывая метод onMouseEvent, остальное будет на его совести. Что же именно он должен делать?

Сначала надо придумать алгоритм поиска элемента, который находится в точке, в которой произошло событие мыши — nodeForMouseEvent (). Для этого надо посмотреть на рабочий стол, навести мышь на какую-нибудь кнопку и подумать, как найти именно её, зная только список элементов, лежащих на рабочем столе. И также держать в голове, что в случае, если поверх вашей кнопки лежит окно, оно перехватит событие, и кнопка его не получит. Значит событие получает тот элемент, который лежит выше всех в этой точке. Учитывая порядок отрисовки дочерних элементов в методе draw (), можно понять, что чем выше индекс элемента в массиве childs, тем позже он рисуется. В том числе если положить кнопку А на кнопку В, то кнопка А является получателем события мыши только в том случае, если нажатие не попадает в область кнопки В и попадает в область кнопки А. Так как нарисованный последним элемент лежит выше всех, искать получателя события надо рекурсивно, начиная с родительского элемента в порядке убывания индекса элемента.


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

Как можно реализовать drag-n-drop для окон?

Скажу больше: отдельные элементы в силу своей специфики могут реагировать на события мыши, даже если они не находятся прямо под курсором (курсор за границами элемента), или находятся, но перекрыты другими элементами. Например, если вы тянете файл с рабочего стола в корзину, на события мыши тут будут реагировать сразу два элемента интерфейса: перетаскиваемый файл и сама корзина, которая подсветится при поднесении к ней файла. Причём два элемента — это не предел, их может быть намного больше. Отсюда вывод: события мыши должны получать все элементы интерфейса, и уже какой-то конкретный механизм определяет, как они будут делить это событие между собой.

Можно придумать несколько таких механизмов, но для реализации нашей задачи (событие кнопки при отпускании мыши и перетаскивании окон) можно обойтись малой кровью — подходом с запоминанием активного элемента. Это элемент, который в данный момент эксклюзивно отвечает на события мыши. Пока он активен, рабочий стол будет направлять события исключительно ему, независимо от того, находится ли мышь над элементом или элемент в границах своего родителя. Пока активного элемента нет, рабочий стол будет предлагать событие элементу под курсором, вызывая метод doMouseEvent (). Метод должен возвращать boolean, который говорит, готов ли элемент стать активным. Как только один из элементов вернёт true, он станет активным и будет перехватывать все события мыши. Продолжаться это будет до тер пор, пока doMouseEvent () не вернёт false, что означает — элемент более не активен, и все другие опять могут получать события мыши. Этого простого и немного костыльного подхода хватит, чтобы удовлетворить наши потребности.



Создайте приложение сами!

Имея эти элементы, события мыши и класс Application, мы можем создать простое приложение. Предлагаю написать его с точки зрения разработчика, то есть используя написанный нами GUI как фреймворк. Код приложения вы можете найти в классе CustomApplication.


Усложняем задачу и добавляем полупрозрачность

Напоследок предлагаю усложнить задачу и добавить полупрозрачность. Это типовое задание, которое встречается при разработке интерфейса. Однако без аппаратного ускорения подобная задача становится сравнительно сложной. Давайте разбираться вместе.


Но нам нужен универсальный и простой способ смешивания. Проще всего понять его в мысленном эксперименте. Представляем себе чёрный квадрат и кладём поверх белый, только полностью прозрачный. Чёрный квадрат останется чёрным, потому что белый не сможет на него повлиять. Теперь представляем, что alpha белого квадрата максимальна, то есть теперь он полностью перепишет чёрный цвет своим. А сейчас мысленно погоняйте в голове прозрачность от минимуму к максимуму и наоборот. Промежуточные цвета будут серыми, то есть все каналы равномерно будут перетекать от 0 к 255, выдавая в результате градиент серого, и чем больше прозрачность белого, тем более тёмный серый мы получаем. Теперь надо увидеть правило, согласно которому всё это работает. Фактически мы имеем простое параметрическое уравнение:

color = source + (dest — source) * (alpha / alphaMax);

То есть для примера с белым и чёрным цветами по каждому каналу уравнение будет выглядеть так:

red = green = blue = 0 + (255 — 0) * (alpha / 255);

Всегда проверяйте свои формулы, подставляя значения из известных предельных случаев!

0 + (255 — 0) * (0 / 255) = 0 (при полной прозрачности чёрный остаётся нулём);
0 + (255 — 0) * (255 / 255) = 255 (при нулевой прозрачности цвет становится белым белый).

Сработает ли наш старый подход, при котором сначала отрисуется рабочий стол, а поверх — кнопка? В момент рисования пикселя кнопки она возьмёт текущее значение цвета этого пикселя и прибавит к нему собственный цвет с альфой по описанной сверху формуле и запишет результат поверх исходного цвета. Всё выглядит нормально.

C = Cdt*(1 — Aw) + Cw * Aw;

Cw = Cw * (1 — Ab) + Cb * Ab;

C = Cdt*(1 — Aw) + (Cw * (1 — Ab) + Cb * Ab)* Aw;

Если Ab = 1 и Aw = 0.5, то

C = 0.5 * Cdt + 0.5 * Cb;

C — цвет результата, Cdt, Cw, Cb, Aw, Ab — цвета и альфа элементов (dt — desktop, w — window, b — button).

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

А что если мы полностью где-то отрисуем элемент до того, как врисовывать его в родителя? Но для этого надо иметь отрисованные дочерние элементы, а они, в свою очередь, должны знать своих детей и т. д. В этом случае сначала отрисуются элементы, лежащие в вершинах дерева иерархии, потом — их родители, а в самом конце — на рабочем столе появятся готовые отрендеренные окна. Куда же надо их рендерить? А что, если каждому элементу иметь свою текстуру такого же размера, как и он сам? Тогда задачей рисования элемента будет только рендер самого себя и отрисовка дочерних элементов. Именно поэтому из графического контекста пропало свойство отступа — оно не требуется, все элементы теперь рисуют исключительно в свою текстуру в своей же системе координат. Давайте взглянем на код!


Осталось запустить приложение!

И убедиться, что всё работает корректно. Конечно, можно заметить, что всё работает очень медленно, но это не удивительно: мы рисуем пиксель за пикселем, не используя ни возможности быстрого копирования в памяти, ни аппаратное ускорение. Скорость алгоритмов не была целью. Главное — найти чистые алгоритмы путём анализа, и мы с этим справились.

Напоследок сделам минимальную оптимизацию: не надо перерисовывать элементы при каждом цикле рендера, особенно, если учитывать, что в данный момент все они — лишь залитые прямоугольники. Для этого у элемента вводим свойство needsRedraw, которое и будет индикатором того, что его текстуру следует перерисовать. Это свойство должно выставляться в true при каждом изменении свойств, влияющих на внешний вид элемента. Более того, это должно происходить не только с самим элементом, но и со всеми его родителями, так как их текстуры зависят от внешнего вида всех дочерних элементов.

Если вы начинающий программист, пожалуйста, напишите в комментариях, была ли вам полезна эта статья и интересна ли тема алгоритмизации и поиска решений.

Здравствуйте. Подскажите, Как создать графический интерфейс. К примеру написал прогу(исходник), тот же конвертер валют или калькулятор написан в консоле, как теперь "оформить" в графический интерфейс ? Исходники сделаны в С++

Как создать интерфейс шахматной программы без движка через С++
Всем привет! Хотел бы попытаться освоить язык С++, не будучи программистом, для того, чтобы.

Как проще всего сделать интерфейс для программы на С++?
Подскажите в какой как и с помощью какой программы проще всего сделать интерфейс для программы.


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

Как быстро сделать графический интерфейс для консольной программы под windows на С++ ?
В общем я студент прошу сориентировать по такому вопросу. У меня есть консольная программа которая.

Den4You, "специальная прога" называется IDE - интегрированная среда разработки. Такого типа программ несколько, самые известные - Microsoft Visual Studio (использует MFC), Borland Visual C++ (использует VCL), Qt Creator (использует Qt). Все три указанные в скобочках библиотеки (точнее, графическая их часть) - по сути своей надстройки над WinAPI.

Спасибо за ответы.. Вот у меня есть VS 2008 pro и xwDev-C++, правда VS подглючивает. Скажите или дайте ссылку, как "соеденять" эти формы с исходным кодом? Кстати да, в xwDev есть wxWidget (конструктор) этих форм, но как код и форму объеденить.

Решение

Prol s, хамите, уважаемый. Если каждый начнёт задавать вопрос, который ему не понятен, в форумах, то в книгах, библиотеках, поисковиках необходимость отпадёт, и все будут сидеть за монитором и отвечать на вопросы страждущих. Форум - последняя инстанция после того, как спрашивающий сбил пальцы в кровь, выискивая ответ в поисковиках, и высушил к чертям глаза, пытаясь найти его в книгах. По крайней мере, так должно быть.

Ага, вы еще поумничайте.


Во-первых - "дайте ссылку" - это не вопрос, во-вторых - в этом разделе обсуждаеться чистый С++, так что удосуждесть найти нужную Вам ветку форума и не парить людям мозги.


Как вы приступаете к созданию интерфейса? Насколько сильно вы ориентируетесь на web-интерфейсы? Помните о 5 самых важных аспектах проектирования UI для мобильных приложений.

1. Правила взаимодействия с пользователем не отменяются

Вспомним 4 ключевых правила интерактивного дизайна:

- Исследования
Отслеживайте поведения пользователей для корректировки работы приложения. Задайте пользователям цели и выявите препятствия на пути к их достижению.
- Учет пользовательских привычек и анатомических особенностей
Правильный интерфейс - не головоломка. В идеале пользователь не должен думать над тем, что нужно сделать, чтобы получить нужный результат, и не вынужден отгадывать, зачем нужен тот или иной элемент.
Помните, что у человека по пять пальцев на двух руках, и что со времен раннего html подчеркнутый текст синего цвета означает не что иное как ссылку.
- Возможность обучаться
Новое и непривычное в интерфейсе должно выглядеть и вести себя дружелюбно. Всегда оставляйте возможность отменить действие и вернуться назад. Тогда новые модели поведения можно будет легко изучить и принять.
- Обратная связь
Оповещайте пользователя о том, что его задача была выполнена: это может быть звуковой сигнал, небольшое модальное окно или всплывающее оповещение.

2. Понимание пользователей

Есть пара тактик, позволяющих понять поведение пользователей и проектировать интерфейс с его учетом:

- Внедрение персонажей
Результатом небольшого брейнсторма становятся один или несколько персонажей, являющихся классическими представителями вашей аудитории. Этот метод очень подробно описывал А. Купер, и даже рекомендовал давать имя этим персонажам и придавать им личные характеристики, чтобы приблизить их к реальным людям.
Соответственно, вы проектируете интерфейс только для них, а не для абстрактного "пользователя".

- Пользовательские сценарии
Написание сценариев поведения обеспечит понимание того, как человек будет действовать в приложении. Начните с цели, которую пользователь должен достичь и пропишите все его действия на пути к ней по пунктам. Опишите все существующие пути, начиная с наиболее очевидных. Так вы сможете отсечь лишнее или понять, как упростить этот путь.

- Карта действий
Продумайте все возможные условия для каждого действия и поведение элементов. Это избавит вас от лишних или непредусмотренных функций, а также поможет понять эмоциональную составляющую использования вашего продукта.


3. План потоков

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

Пример: банковское приложение. Сценарий: настройка пополнения депозитного счета.

Автоматическое пополнение депозита
[Установить]
Выберите частоту пополнения
[Раз в месяц] [Два раза в месяц] [Раз в несколько недель] [Каждую неделю]
Один раз в месяц
[Выберите дату]
Подтвердить
Введите сумму
[Введите сумму]
[Установить автоматическое пополнение счета]

Эскизы и прототипы помогают изучить одну из наиболее важных составляющих хорошего приложения - содержание. Вот несколько инструментов, которые помогут сделать это online:


4. Ориентация на поведенческие шаблоны, привычки и неписанные стандарты. Учет движений

Поведенческие шаблоны
Использование мобильных гаджетов вращается вокруг множества нюансов, которые нельзя не принимать во внимание - например, расположение большого пальца.

По этой причине навигационные кнопки, как правило, находятся в нижней части экрана:


В книге "Шаблоны мобильных интерфейсов", выпущенной UXPin, рассматриваются два вида взаимодействия: жесты и анимация.

Пользователи уже привыкли к возможности использовать разные жесты для различных ситуаций:


И распространенные типы анимации также вызывают ряд ожиданий, основанных на предыдущих опытах взаимодействия с приложениями.
Посмотреть, какими они бывают можно на Capptivate и UseYourInterface.

Учет движений
Анатомический фактор - очень важный элемент проектирования. Учитывайте строение тела человека и статистику использования мобильных устройств при проектировании. Левый верхний угол подходит для размещения важной информации, в то время как нижняя граница экрана - для навигации.


Именно так выглядят схемы наиболее удобных для человека жестов.


94% времени пользователи держат смартфон в вертикальном положении.


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


И большинство пользователей используют смартфоны с диагональю экрана в пределах 4-5,5 дюймов.

5. Использование итеративного подхода

Говоря просто, лучше всего начинать с малого функционала, анализируя его важность, необходимость и качество исполнения, постепенно дополняя нововведениями. Это не только ускорит запуск проекта, но и сократит риски. А главное - позволит избежать перегруженности интерфейса.

Бонус: web-помощники для проектировщика интерфейсов приложений

Тем, кто хочет разрабатывать под мобильные устройства, рекомендуем профессию «Разработчик мобильных приложений».


Как вы приступаете к созданию интерфейса? Насколько сильно вы ориентируетесь на web-интерфейсы? Помните о 5 самых важных аспектах проектирования UI для мобильных приложений.

1. Правила взаимодействия с пользователем не отменяются

Вспомним 4 ключевых правила интерактивного дизайна:

- Исследования
Отслеживайте поведения пользователей для корректировки работы приложения. Задайте пользователям цели и выявите препятствия на пути к их достижению.
- Учет пользовательских привычек и анатомических особенностей
Правильный интерфейс - не головоломка. В идеале пользователь не должен думать над тем, что нужно сделать, чтобы получить нужный результат, и не вынужден отгадывать, зачем нужен тот или иной элемент.
Помните, что у человека по пять пальцев на двух руках, и что со времен раннего html подчеркнутый текст синего цвета означает не что иное как ссылку.
- Возможность обучаться
Новое и непривычное в интерфейсе должно выглядеть и вести себя дружелюбно. Всегда оставляйте возможность отменить действие и вернуться назад. Тогда новые модели поведения можно будет легко изучить и принять.
- Обратная связь
Оповещайте пользователя о том, что его задача была выполнена: это может быть звуковой сигнал, небольшое модальное окно или всплывающее оповещение.

2. Понимание пользователей

Есть пара тактик, позволяющих понять поведение пользователей и проектировать интерфейс с его учетом:

- Внедрение персонажей
Результатом небольшого брейнсторма становятся один или несколько персонажей, являющихся классическими представителями вашей аудитории. Этот метод очень подробно описывал А. Купер, и даже рекомендовал давать имя этим персонажам и придавать им личные характеристики, чтобы приблизить их к реальным людям.
Соответственно, вы проектируете интерфейс только для них, а не для абстрактного "пользователя".

- Пользовательские сценарии
Написание сценариев поведения обеспечит понимание того, как человек будет действовать в приложении. Начните с цели, которую пользователь должен достичь и пропишите все его действия на пути к ней по пунктам. Опишите все существующие пути, начиная с наиболее очевидных. Так вы сможете отсечь лишнее или понять, как упростить этот путь.

- Карта действий
Продумайте все возможные условия для каждого действия и поведение элементов. Это избавит вас от лишних или непредусмотренных функций, а также поможет понять эмоциональную составляющую использования вашего продукта.


3. План потоков

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

Пример: банковское приложение. Сценарий: настройка пополнения депозитного счета.

Автоматическое пополнение депозита
[Установить]
Выберите частоту пополнения
[Раз в месяц] [Два раза в месяц] [Раз в несколько недель] [Каждую неделю]
Один раз в месяц
[Выберите дату]
Подтвердить
Введите сумму
[Введите сумму]
[Установить автоматическое пополнение счета]

Эскизы и прототипы помогают изучить одну из наиболее важных составляющих хорошего приложения - содержание. Вот несколько инструментов, которые помогут сделать это online:


4. Ориентация на поведенческие шаблоны, привычки и неписанные стандарты. Учет движений

Поведенческие шаблоны
Использование мобильных гаджетов вращается вокруг множества нюансов, которые нельзя не принимать во внимание - например, расположение большого пальца.

По этой причине навигационные кнопки, как правило, находятся в нижней части экрана:


В книге "Шаблоны мобильных интерфейсов", выпущенной UXPin, рассматриваются два вида взаимодействия: жесты и анимация.

Пользователи уже привыкли к возможности использовать разные жесты для различных ситуаций:


И распространенные типы анимации также вызывают ряд ожиданий, основанных на предыдущих опытах взаимодействия с приложениями.
Посмотреть, какими они бывают можно на Capptivate и UseYourInterface.

Учет движений
Анатомический фактор - очень важный элемент проектирования. Учитывайте строение тела человека и статистику использования мобильных устройств при проектировании. Левый верхний угол подходит для размещения важной информации, в то время как нижняя граница экрана - для навигации.


Именно так выглядят схемы наиболее удобных для человека жестов.


94% времени пользователи держат смартфон в вертикальном положении.


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


И большинство пользователей используют смартфоны с диагональю экрана в пределах 4-5,5 дюймов.

5. Использование итеративного подхода

Говоря просто, лучше всего начинать с малого функционала, анализируя его важность, необходимость и качество исполнения, постепенно дополняя нововведениями. Это не только ускорит запуск проекта, но и сократит риски. А главное - позволит избежать перегруженности интерфейса.

Бонус: web-помощники для проектировщика интерфейсов приложений

Создание нового проекта

Создание нового проекта

В появившемся окне:

В общем, как показано на рисунке ниже.

Опции создания проекта

Опции создания проекта

Только что созданный проект

Только что созданный проект

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

Свойство

Обратите внимание, в левом столбце указано имя (название свойства), а в правом — его значение.

Установка свойства формы

Установка свойства формы

Окно первого графического приложения

Окно первого графического приложения

В следующем уроке, мы рассмотрим простую работу с дизайнером форм, и настройку элементов графического интерфейса, а на этот урок подошел к концу, мы создали первое графическое приложение, собрали и запустили его.

В данном учебном курсе рассматривается создание простого графического интерфейса пользователя и добавление к нему несложной серверной функциональности. В частности, будет рассмотрен код, определяющий поведение кнопок и полей в форме Swing.

Мы разберем компоновку и структуру графического интерфейса, после чего добавим несколько кнопок и текстовых полей. Текстовые поля предназначены для получения вводимой пользователем информации и вывода результата работы программы. Кнопка будет инициировать работу функций, встроенных в клиентскую часть программы. Создаваемое приложение представляет собой простой, но полнофункциональный калькулятор.

Более детальное руководство по функциям разработки конструктора графического интерфейса пользователя, включая видеодемонстрации различных функций разработки см. в разделе Разработка графического пользовательского интерфейса Swing в IDE NetBeans.

Предполагаемая продолжительность: 20 минут

netbeans stamp 80 74 73

Для работы с этим учебным курсом требуются программное обеспечение и ресурсы, перечисленные ниже.

версия 6.9 или более поздняя

версия 6, 7 или 8

Упражнение 1: Создание проекта

Первым действием является создание проекта среды IDE для разрабатываемого приложения. Дадим проекту имя NumberAddition .

Выберите "Файл" > "Создать проект" . Также можно щелкнуть значок "New Project" на панели инструментов среды IDE.

Введите NumberAddition в поле Project Name ("Имя проекта") и укажите путь, например, в вашем основном каталоге, как местоположение проекта.

Установите флажок "Использовать отдельную папку для хранения библиотек" и укажите местоположение папки библиотек (необязательно). Дополнительная информация приведена в статье Предоставление доступа к библиотеке другим пользователям в документе Разработка приложений с помощью NetBeans IDE.

Удалите флажок "Create Main Class", если он установлен.

Упражнение 2: Создание внешнего интерфейса

Для продолжения процесса создания интерфейса необходимо создать контейнер Java, в который будут помещены другие требуемые элементы графического интерфейса. В этом действии контейнер будет создан с помощью элемента JFrame . Контейнер будет помещен в новый пакет, который будет отображаться в узле "Source Packages".

Создание контейнера JFrame

В окне 'Проекты' щелкните правой кнопкой мыши узел NumberAddition и выберите Создать > Другие .

Введите NumberAdditionUI в качестве имени класса.

Выберите пакет my.numberaddition .

Среда IDE создает форму NumberAdditionUI и класс NumberAdditionUI в приложении NumberAddition и открывает форму NumberAdditionUI в GUI Builder. Пакет my.NumberAddition заменяет собой пакет по умолчанию.

Добавление элементов: создание внешнего интерфейса

Далее с помощью окна "Palette" внешний интерфейс приложения заполняется панелью JPanel. После этого добавляются три элемента JLabel (текстовые подписи), три элемента JTextField (текстовые поля) и три элемента JButton (кнопки). Если до этого работа с конструктором графического интерфейса пользователя не выполнялась сведения о размещения компонентов см. в разделе Разработка графического пользовательского интерфейса Swing в IDE NetBeans.

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

Figure1

Если в правом верхнем углу среды IDE отсутствует окно Palette ("Палитра"), выберите Window ("Окно") > Palette ("Палитра").

Для начала выберите панель из категории Swing Containers ("Контейнеры Swing") в палитре и перетащите ее на JFrame.

Панель JPanel будет выделена. Перейдите к окну "Properties" и нажмите кнопку с многоточием (…​) рядом с полем "Border" для выбора стиля границы.

В диалоговом окне "Border" выберите "TitledBorder" из списка и введите Number Addition в поле "Title". Для сохранения изменений и закрытия диалогового окна нажмите кнопку "OK".

Теперь на экране должен отображаться пустой элемент "JFrame" с заголовком "Number Addition", как показано на рисунке. Согласно рисунку добавьте к нему три метки JLabel, три текстовых поля JTextField и три кнопки JButton.

Переименование элементов

На этом этапе будет выполнено переименование элементов, которые были добавлены к элементу JFrame.

Дважды щелкните jLabel1 и измените ntrcn (свойство "text") на First Number .

Дважды щелкните jLabel2 и измените текст на Second Number .

Дважды щелкните jLabel3 и измените текст на Result .

Удалите стандартный текст из jTextField1 . Отображаемый текст можно преобразовать в редактируемый. Для этого щелкните правой кнопкой мыши текстовое поле и выберите 'Редактировать текст' во всплывающем меню. При этом может потребоваться восстановить первоначальный размер поля jTextField1 . Повторите это действие для полей jTextField2 и jTextField3 .

Измените отображаемый текст jButton1 на Clear . (Для изменения текста кнопки щелкните кнопку правой кнопкой мыши и выберите "Edit Text". В качестве альтернативы можно щелкнуть кнопку, выдержать паузу и щелкнуть еще раз.)

Измените отображаемый текст jButton2 на Add .

Измените отображаемый текст jButton3 на Exit .

Теперь готовый графический интерфейс должен выглядеть так, как показано на рисунке ниже:

Figure2

Упражнение 3: Добавление функциональности

В этом упражнении будет добавлена необходимая функциональность к кнопкам "Add", "Clear" и "Exit". Поля jTextField1 и jTextField2 будут использоваться для ввода значений пользователем, а jTextField3 – для вывода результата работы программы. Создаваемая программа представляет собой простейший калькулятор. Итак, приступим!

Добавление функциональности к кнопке "Exit"

Для того чтобы кнопки стали функциональными, каждой из них необходимо присвоить обработчик событий, который будет отвечать за реагирование на события. В нашем случае требуется идентифицировать событие нажатия кнопки – путем щелчка мышью или с помощью клавиатуры. Поэтому будет использоваться интерфейс "ActionListener", предназначенный для обработки событий "ActionEvent".

Щелкните правой кнопкой мыши кнопку "Exit". Во всплывающем меню выберите Events ("События") > Action ("Действие") > actionPerformed. Учтите, что меню содержит множество других событий, на которые может реагировать программа! При выборе события actionPerformed среда IDE автоматически добавит прослушиватель ActionListener к кнопке Exit ("Выход") и создаст метод обработчика для обработки метода прослушивателя actionPerformed.

В среде IDE автоматически открывается окно "Source Code", где отображается место вставки действия, которое должно выполняться кнопкой при ее нажатии (с помощью мыши или клавиатуры). Окно "Source Code" должно содержать следующие строки:

Теперь добавим код действия, которое должна выполнять кнопка "Exit". Замените строку TODO на System.exit(0); . Готовый код кнопки "Exit" должен выглядеть следующим образом:

Добавление функциональности к кнопке "Clear"

Щелкните вкладку "Design" в верхней части рабочей области для возврата к экрану "Form Design".

Щелкните правой кнопкой мыши кнопку "Clear" ( jButton1 ). В появившемся меню выберите "Events > Action > actionPerformed".

Нажатие кнопки "Clear" должно приводить к удалению всего текста из всех текстовых полей "jTextField". Для этого следует добавить код, аналогичный приведенному выше. Готовый исходный код должен выглядеть следующим образом:

Этот код удаляет текст из всех трех полей JTextField, оставляя их пустыми.

Добавление функциональности к кнопке "Add"

Кнопка "Add" должна выполнять три действия.

Сначала она принимает данные, введенные пользователем в полях jTextField1 и jTextField2 , и преобразовывает их из типа "String" в тип "Float".

Затем она выполнит сложение двух чисел.

И, наконец, она преобразует сумму в тип String и поместит ее в jTextField3 . Начнем!

Щелкните вкладку "Design" в верхней части рабочей области для возврата к экрану "Form Design".

Щелкните правой кнопкой мыши кнопку "Add" ( jButton2 ). Во всплывающем меню выберите Events ("События") > Action ("Действие") > actionPerformed.

Добавьте код действий, которые должна выполнять кнопка "Add". Готовый исходный код должен выглядеть следующим образом:

Теперь программа полностью готова, и можно приступить к ее сборке и выполнению.

Упражнение 4: Выполнение программы

Для выполнения программы в среде IDE выполните следующие действия:

Выберите Run ("Запуск") > Run Main Project ("Запуск главного проекта") (как вариант, нажмите F6).

Примечание. При открытии окна с указанием того, что для Project NumberAddition не задан основной класс, следует выбрать my.NumberAddition.NumberAdditionUI в качестве основного класса в том же окне и нажать кнопку ОК.

Для запуска программы вне среды IDE выполните следующие действия:

Для сборки архива JAR приложения выберите "Run > Clean and Build Main Project" (Shift-F11).

При помощи проводника по файловой системе или диспетчера файлов перейдите в каталог ` NumberAddition/dist`.

Примечание. Местоположение каталога проекта NumberAddition зависит от пути, указанного при создании проекта в шаге 3 в разделе Упражнение 1. Создание проекта.

Дважды щелкните файл NumberAddition.jar .

Через несколько секунд приложение запустится.

Примечание. Если при двойном щелчке файла JAR не выполняется запуск приложения, дополнительные сведения о настройке связей файлов JAR в используемой операционной системе см эту статью.

Можно также запустить приложение из командной строки.

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

Вызовите командную строку или окно терминала.

В командной строке измените текущий каталог на каталог NumberAddition/dist .

В командной строке введите следующий оператор:

Примечание. Убедитесь, что my.NumberAddition.NumberAdditionUI задан как основной класс до запуска приложения. Для провери этого, щелкните правой кнопкой узел мыши узел проекта NumberAddition на панели 'Проекты', выберите 'Свойства' во всплывающем меню и выберите категорию 'Выполнить' в диалоговом окне 'Свойства проекта'. В поле 'Основной класс' должно отображаться my.numberaddition.NumberAdditionUI .

Механизм обработки событий

В этом руководстве было рассмотрено реагирование на простое событие нажатия кнопки. Существует множество событий, на которые может реагировать приложение. Просмотреть в среде IDE список доступных событий, которые могут обрабатываться элементами графического интерфейса, можно следующим образом:

Вернитесь к файлу NumberAdditionUI.java в редакторе. Щелкните вкладку "Design" для просмотра структуры графического интерфейса в GUI Builder.

Щелкните правой кнопкой мыши любой элемент графического интерфейса и выберите "Events" в появившемся меню. Теперь можно просто изучить содержимое меню, не выбирая каких-либо пунктов.

В качестве альтернативы можно выбрать "Properties" в меню "Window". В окне "Properties" щелкните вкладку "Events". Вкладка "Events" позволяет просмотреть и изменить обработчики событий, связанные с текущим активным элементом графического интерфейса.

Приложение также может реагировать на нажатие клавиш, одинарный, двойной или тройной щелчок мышью, перемещение указателя мыши, изменение размера окна и перемещение фокуса ввода. Меню "Events" позволяет автоматически создать обработчики событий для всех этих событий. Наиболее распространенным из них является событие "Action". (Для получения дополнительных сведений см. практические рекомендации по обработке событий в руководстве Sun Java Events Tutorial.)

Как выполняется обработка событий? При каждом выборе события из меню событий среда IDE автоматически создает так называемый прослушиватель событий и связывает его с компонентом разработчика. Для более подробного ознакомления с процессом обработки событий выполните следующие действия.

Вернитесь к файлу NumberAdditionUI.java в редакторе. Щелкните вкладку "Source" для просмотра исходного кода графического интерфейса.

Выполните прокрутку вниз и просмотрите реализованные методы jButton1ActionPerformed() , jButton2ActionPerformed() и jButton3ActionPerformed() . Эти методы называются обработчиками событий.

Теперь перейдите к методу initComponents() . Если этот метод отсутствует, найдите строку Generated Code и щелкните знак + рядом с этой строкой для отображения скрытого метода initComponents() .

Обратите внимание на синий блок, окружающий метод initComponents() . Этот код был автоматически создан средой IDE и не может быть изменен пользователем.

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

В методе initComponents() найдите следующий фрагмент:

В этом месте к элементу графического интерфейса, в данном случае к jButton3 , добавляется объект прослушивания событий "ActionListener". Интерфейс "ActionListener" имеет метод "actionPerformed" объекта "ActionEvent", который реализуется путем простого вызова обработчика событий jButton3ActionPerformed . Теперь эта кнопка реагирует на события действий. Каждый раз при нажатии кнопки создается событие "ActionEvent", которое передается в метод "actionPerformed" интерфейса прослушивания событий, исполняющий код, предусмотренный разработчиком для этого события в обработчике событий.

Читайте также: