Конструктор форм intellij idea

Обновлено: 25.04.2024

Давно не писал настольных приложений на Java вообще и с использовании Swing в частности. Однако, возникла необходимость немного по GUIть. В качестве инструмента выбрал IntelliJ IDEA Community edition, 2016.1 версии.

Взялся ваять и, естественно, первое, на что налетел — хотя со времён Borland Java Builder 2006 воды утекло немало, экранные интерфейсы создавать проще не стало, скорее наоборот. А одной из причин выбора IDEA было как раз наличие Swing дизайнера «из коробки», однако как им пользоваться с ходу решительно непонятно — форма генерится, класс создаётся, создаются переменные контролов из дизайнера… но и только: при создании нашего класса форма на экране не появляется

Пошарил интернет, информации приблизительно ноль. Народ говорит, мол, «создавай и — вперёд!». Хм…

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

Создание Swing GUI форм средствами JetBrains IntelliJ IDEA 2016.1

Во-первых, для понимания процесса лучше начать с того. что зайти в меню IDEA «File -> Settings» — там «Editor -> GUI Designer» и установить флажок Generate GUI Into: в Java source code. (это немного поможет пониманию процесса на первом этапе — потом можно будет убрать обратно).

image

Далее открываем дерево исходного кода своего проекта и кликаем правой кнопкой мыши на любую папку или файл исходного кода java и выбираем «New -> Dialog» — вводим имя класса для формы.

image

В итоге нам действительно сгенерили класс-наследник JDialog (который можно создать и использовать) и форма к нему.
Запускаем наш проект на выполнение и… о ужасчудо! при компиляции IDEA добавляет в конец нашего файла некоторый дополнительный код.


Несложно догадаться, что вся наша Swing-овая форма конфигурируется в автогенерируемом методе $$$setupUI$$$.

Вспомните настройку, которую мы установили в самом начале — «GUI Into: -> Java source code». Если её не ставить, то этот метод просто будет появляться напрямую в _class_ файле, минуя java-файл (декомпилируйте его, если сомневаетесь — я это сделал). Соответственно, можете вернуть настройку «GUI Into:» к первоначальному виду, чтобы этот код (который всё равно редактировать настоятельно не рекомендуют) не мозолил глаза.

Теперь, когда мы поняли, как оно работает, перейдём к созданию прочих форм — необязательно диалогов.

Опять правой кнопкой мыши кликаем на папку или файл исходного кода, выбираем «New -> GUI Form» — вводим имя класса для формы.

Генерится класс и форма к нему. Накидываем на форму несколько контролов. В GUI дизайнере смотрим имя корневого элемента (обычно panel1, если IDEA не задала имя, а такое бывает, задайте принудительно — я для наглядности назвал rootPanel).

image

Переходим к исходному коду нашего класса.

Итак:
1. Добавляем для нашего класса наследование «extends JFrame»;
2. Добавляем конструктор класса со строками:

Всё. Форма готова к употреблению. Остальное смотрите в многочисленных инструкциях по Swing.

P.S. Как вариант, можно не наследовать наш класс от JFrame, а создать конструктор вида:

When you finish building a GUI Designer form, at a minimum you should have a class that is bound to the form, and component type fields in the class bound to the various form components.

If the binary class files are specified as the output option, all runtime initialization code is generated in the class file. If your form has a bound class, you will not see the automatically generated initialization code there. In case you have selected Java source code as the output option, the bound class of your form will contain automatically generated $$$setupUI$$$() method.

Do not edit manually the GUI Initializer source code! At any compilation, IntelliJ IDEA automatically generates new code in this section, and all your changes will be lost.

Sometimes you might need to provide initialization code of your own. For example, you want a GUI component to be instantiated by a non-default constructor with certain parameters. In this case, IntelliJ IDEA will not generate instantiation of the component, and it is your responsibility to provide the call to constructor in the createUIComponents() method. Otherwise, a Null Pointer Exception will be reported. Follow the general technique described below.

To create custom GUI initializer source code for a certain component, follow this general procedure

Select the desired component.

In the Inspector, check the option Custom Create .

With the component selected, press F4 , or choose Jump to Source on the context menu.

In the text editor, locate the method createUIComponents() , and type the desired source code. The code in this method will not be removed on compilation.

Example

For example, you would like to provide non-default constructors for the radio buttons 1 and 2, and have GUI Designer create a default constructor for the radio button 3:

//For the radio buttons 1 and 2, option Custom Create is set to true. //You write custom constructors for these components //in the method createUIComponents() private JRadioButton radioButton1; private JRadioButton radioButton2; //For the radio button 3 the default constructor is generated automatically //in the method $$$setupUI$$$(). The component properties //specified in the GUI Designer //are generated as calls to the set* methods in $$$setupUI$$$(). private JRadioButton radioButton3; . private void createUIComponents() < radioButton1 = new JRadioButton("Custom text 1"); radioButton2 = new JRadioButton("Custom text 2"); >. private void $$$setupUI$$$() < createUIComponents(); . radioButton3 = new JRadioButton(); radioButton3.setText("RadioButton"); . >

GUI Designer equips the developers with the possibility to create GUI forms with the desired layout and bound class, and dialogs. A form can be created as only a form file, or together with a UI class. A dialog framework consists of a class defining basic components and methods, and a GUI form with components bound to the fields of the UI class.

As mentioned in the GUI Designer concepts, GUI forms in IntelliJ IDEA are not Java classes. They are special XML files stored in your project with a .form extension.

Prior to creating GUI forms and dialogs, select a package where the forms will be stored. You might need to create a package first. It is recommended to store the forms and dialogs in the same package as the classes that implement their functionality.

Creating a New GUI Form or Dialog

To create a new GUI form

On the main menu, choose File | New .

On the pop-up menu, choose GUI Form .

Specify the name of the new form, and select the layout manager.

Check the option Create bound class , and specify the bound class name.

To create a new dialog

On the main menu, choose File | New .

On the pop-up menu, choose Dialog .

Specify the name of the new dialog.

Specify the following options:

Generate main() method that creates and shows dialog.

Generate OK handler.

Generate Cancel handler.

Creating a form from a File Template

You can save any form as a File Template, and thus preserve commonly needed dialogs or panes of controls for later reuse. For detailed information about creating and using File Templates, refer to the sections:

To create a File Template from a GUI form

Create a GUI form or open it in the GUI Designer.

On the Main menu, choose File | Save File as Template . The File Templates dialog displays the source code of the form. The extension of the new template is .form

Specify the template name, and click OK .

To create a new GUI form from a File Template

In the Project tool window, right-click the package where you want to create the new form.

On the context menu choose New . The submenu contains items for all defined File Templates, including GUI forms.

Select the desired GUI form template on the context menu, and give it a name when prompted.

Opening Existing GUI Forms

Open form files the same way you open source code or text files for editing. Locate the file in the appropriate navigation view, select it, and do one of the following:

Choose Jump to Source on the context menu.

Each form opens in a separate tab in the same space occupied by the Editor for source code files. You can have source code/text files and form files open simultaneously.

Как создать графический интерфейс с JavaFX, используя разметку FXML и SceneBuilder.

Все посты в серии о JavaFX:

Традиционный способ

Просто напоминание — код выглядел так:


Как видите весь пользовательский интерфейс создан в Java коде.

Это очень простой пример, но по мере усложнения вашего приложения, когда приходится вводить несколько уровней вложенных макетов и множество компонентов, результирующий код может стать очень сложным для понимания. Однако это еще не все — в одном и том же классе присутствует код, который отвечает за структуру, визуальные эффекты и поведение одновременно.

У класса явно нет единой ответственности. Сравните это, например, с веб-интерфейсом, где каждая страница имеет четко разделенные задачи:

  • HTML — это структура
  • CSS — это визуальные эффекты
  • JavaScript — это поведение

Представляем FXML

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

В действительности есть много шаблонов дизайна для этого. Как правило, в конечном итоге вы приходите к варианту «Model-View-Whatever» — это что-то вроде «Model View Controller», «Model View Presenter» или «Model View ViewModel».

Можно часами обсуждать плюсы и минусы разных вариантов — давайте не будем делать это здесь. Более важно то, что с JavaFx вы можете использовать любой из них.

Это возможно потому, что в дополнение к процедурной конструкции вашего пользовательского интерфейса вы можете использовать декларативную разметку XML.

Оказывается иерархическая структура XML — это отличный способ описать иерархию компонентов в пользовательском интерфейсе. HTML работает достаточно хорошо, верно?

Формат XML, специфичный для JavaFX, называется FXML. В нем вы можете определить все компоненты приложения и их свойства, а также связать их с контроллером, который отвечает за управление взаимодействиями.

Загрузка FXML файлов

Итак, как мы можем изменить наш метод запуска для работы с FXML?


Здесь root представляет корневой компонент вашего пользовательского интерфейса, остальные компоненты вложены в него.

Метод load имеет generic возвращаемое значение, поэтому вы можете указать конкретный тип, а не Parent. Далее, вы получаете доступ к компонентно-ориентированным методам. Однако, это делает ваш код более хрупким. Если вы измените тип корневого компонента в вашем FXML, приложение может перестать работать во время выполнения, но при этом во время компиляции не будет ошибок. Это происходит потому, что теперь есть несоответствие типа, объявленного в вашем FXML и в загрузчике Java FXML.

Создание FXML файла

Теперь мы знаем, как загрузить файл FXML, но нам все еще нужно его создать. Файл должен иметь расширение .fxml. В Maven проекте, вы можете поместить этот файл в папку ресурсов или FXMLLoader может загрузить его с внешнего URL-адреса.

После создадания файла в его первой строке необходимо ввести декларацию XML:

Импорт

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

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

Добавление компонентов

Теперь пришло время добавить некоторые компоненты. В предыдущей статье мы узнали, что каждая сцена может иметь только один дочерний компонент. Для начала давайте добавим простую метку (label):


Конечно, метка в качестве корневого компонента — это не очень реалистичный пример. Обычно предпочтительнее использовать какой-то макет (layout), который является контейнером для нескольких компонентов и организует их расположение. Мы рассмотрим макеты позже в этой серии, а сейчас давайте просто воспользуемся простым VBox, который размещает свои дочерние элементы вертикально друг над другом.

FX Namespace

Существует пара элементов и атрибутов FXML, которые по умолчанию недоступны. Вам нужно добавить пространство имен (Namespace) FXML, чтобы сделать их доступными. Его необходимо добавить к корневому компоненту:


Теперь можно использовать новые элементы из пространства имен fx. Давайте попробуем добавить уникальные идентификаторы в наши компоненты:


Атрибут fx:id является уникальным идентификатором компонента, который можно использовать для ссылки на компонент из других частей нашего FXML и даже из нашего контроллера.

Скрипты

Наше приложение пока статично. Есть несколько меток и кнопка, но приложение не делает ничего динамического.

Давайте отреагируем на нажатие нашей кнопки и изменим заголовок с «Click me!» на «Click me again!».

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


Обратите внимание на fx:id, это идентификатор, который будет использоваться позже для ссылки на кнопку.

Теперь нужно предоставить функцию, которая будет вызвана для обработки события. Ее можно определить внутри тега fx:script. Важно то, что вы можете использовать различные языки для написания скрипта, JavaScript, Groovy или Clojure. Давайте посмотрим пример на JavaScript:


Заметьте, что мы ссылаемся на наш компонент Button с помощью идентификатора mainButton, который был объявлен так:


Также необходимо указать, какой язык сценариев вы используете в файле FXML:


Давайте рассмотрим полный текст примера:


Должен ли я использовать это?

В приведенном выше примере показано, как ссылаться на компоненты с помощью fx:id и как добавить простое поведение с помощью скрипта на JavaScript. Неужели это то, что вы должны на самом деле делать?

Ответ — в большинстве случаев нет. Есть несколько проблем с таким подходом. Причина, по которой введен FXML, была разделение интересов — чтобы отделить структуру и поведение пользовательского интерфейса. В этом скрипте снова вернулось поведение слитное со структурой пользовательского интерфейса. Более того, поскольку мы больше не работаем с кодом Java, а с XML, были утрачены все проверки кода во время компиляции и безопасность типов. Теперь все проблемы в приложении будут обнаружены во время выполнения, а не во время компиляции. Приложение стало очень хрупким и подверженым ошибкам.

Добавление контроллера

Итак, что можно сделать, чтобы получить четкое разделение интересов? Можно связать контроллер с нашим файлом FXML. Контроллер — это Java класс, который отвечает в приложении за обработку поведения и взаимодействия с пользователем. Таким образом можно вернуть безопасность типов и проверки времени компиляции.

Контроллер является POJO, он не должен расширять или реализовывать что-либо, а также не должен иметь никаких специальных аннотаций.

Как можно связать класс контроллера с нашим FXML? По существу, есть два варианта.

На Java

Вы можете создать экземпляр контроллера самостоятельно или использовать любые другие способы создания экземпляра, такие как инъекция зависимости. Затем просто загрузите вашим FXMLLoader.

В FXML

Вы можете указать класс вашего контроллера как атрибут fx:controller, который должен находиться в корневом компоненте.


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

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

Вызов методов контроллера

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


При нажатии на кнопку, она вызывает метод MainSceneController.buttonClicked(). Имейте в виду, что это работает, только если метод объявлен public. Если модификатор доступа более строгий, необходимо аннотировать метод аннотацией @FXML.

Внедрение компонентов в контроллер

Пока что мы просто печатаем на консоль. Что если мы снова захотим изменить текст нашей кнопки на «Click me again»? Как мы можем получить ссылки на компоненты в нашем контроллере?

К счастью, это легко. Помните эти атрибуты fx:id?


JavaFX пытается автоматически сопоставить компоненты с fx:id с полями определенным в вашем контроллере с тем же именем.

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


JavaFX пытается внедрить объект кнопки в ваш контроллер в поле с именем mainButton:


Как и в предыдущих методах, ваши поля должны быть public или аннотированными @FXML.

Теперь, когда у нас есть ссылка на нашу кнопку, можно легко изменить ее текст:

Scene Builder

Написание вашей структуры GUI в XML может быть более естественным, чем в Java (особенно если вы знакомы с HTML). Тем не менее, до сих пор это не очень удобно. Хорошей новостью является то, что существует официальный инструмент под названием Scene Builder, который поможет вам в создании пользовательского интерфейса. В двух словах, это графический редактор для вашего графического интерфейса.


В редакторе имеется три основных области:

  1. В левой части отображаются доступные компоненты, которые можно перетащить в среднюю часть. Она также содержит иерархию всех компонентов в вашем пользовательском интерфейсе, поэтому вы можете легко перемещаться по ней.
  2. Средняя часть — это ваше приложение, отображаемое на основе вашего файла FXML.
  3. Справа находится инспектор текущих компонентов. Здесь вы можете редактировать различные свойства выбранного текущего компонента. Любой компонент, выбранный в средней части иерархии, отображается в инспекторе.

Standalone

Scene Builder можно загрузить как отдельное приложение, которое можно использовать для редактирования FXML файлов.

Интеграция с IntelliJ IDEA

В качестве альтернативы, Scene Builder предлагает интеграцию с IDE.

В IntelliJ IDEA вы можете нажать правой кнопкой мыши на любом FXML файле и затем выбрать опцию меню «Открыть» в SceneBuilder.

В качестве альтернативы, IntelliJ IDEA интегрирует SceneBuilder непосредственно в IDE. Если вы откроете файл FXML в IDEA, в нижней части экрана появятся две вкладки


В IntelliJ IDEA можто настроить расположение исполняемого файла SceneBuilder:

Settings → Languages & Frameworks → JavaFX → Path to SceneBuilder

Что дальше


В следующем посте из нашей серии будут рассмотрены некоторые основные макеты (layout), которые можно использовать для организации компонентов GUI приложения на JavaFX.

IntelliJ IDEA включает в себя большое количество пользовательских Swing-компонентов. Использование этих компонентов в ваших плагинах гарантирует, что они будут выглядеть и работать согласовано с остальным пользовательским интерфейсом IDE и часто позволяет уменьшить размер кода, по сравнению с использованием стандартных Swing-компонентов.

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

Меню и панели инструментов (тулбары) строятся с использованием системы действий (как уже было описано во второй части).

Окна инструментов

Окна инструментов — это панели, которые отображаются слева, снизу и справа от главного окна IntelliJ IDEA. На каждой стороне содержится по две группы окон инструментов — первичное и вторичное, причем в один и тот же момент активной может быть только одна группа.

Каждое окно инструментов может содержать несколько вкладок (в API называются «contents»). Например, toolwindow «Run» показывает вкладку для каждой активной конфигурации запуска, а «Changes» отображает фиксированный набор вкладок в зависимости от системы управления версиями, используемой в проекте.

Существует два основных сценария для использования окон инструментов в плагинах. В первом сценарии (используется, например, в плагинах Ant и Commander) кнопка окна инструментов отображается всегда, следовательно пользователь может активировать и взаимодействовать с функциональностью плагина в любое время. Во втором сценарии (используется действием «Analyze Dependencies») окно инструментов создается для того, чтобы показать результаты конкретной операции и может быть закрыто пользователем сразу после завершения операции.

  • Атрибут «id» (обязательный) — соответствует тексту, отображаемому на кнопке toolwindow;
  • Атрибут «anchor» (обязательный) — задает сторону экрана, к которой привязывается окно инструментов («left», «right» или «bottom»);
  • Логический атрибут «secondary» (необязательный) — указывает, будет ли окно инструментов принадлежать вторичной группе;
  • «icon» (необязательный) — иконка, которая будет отображаться на кнопке (13 x 13 пикселей).

Если окно инструментов не требуется для всех типов проектов, можно указать необязательный атрибут conditionClass, содержащий полное имя класса, реализующего интерфейс Condition (это может быть тот же класс, что реализует фабрику). Если метод value() возвращает «false», окно инструментов не будет отображаться. Обратите внимание, что условие вычисляется только один раз при загрузке проекта. Если вы хотите показывать и скрывать окна инструментов динамически, во время работы с проектом, вам нужно использовать второй сценарий регистрации окна инструментов.

Второй сценарий заключается в обычном вызове метода ToolWindowManager.registerToolWindow() из кода плагина. Этот метод имеет несколько перегрузок, которые могут использоваться в зависимости от ваших задач. Если вы используете перегрузку, которая принимает Swing-компонент, то он становится первой вкладкой, отображаемой в окне инструмента.

Отображение содержимого многих toolwindows требует получение доступа к индексам. В силу этого окна выключаются при построении индексов, но оно останется активным, если вы передадите «true» в качестве значения параметра canWorkInDumbMode функции registerToolWindow().

Как упоминалось ранее, окна инструментов могут содержать несколько вкладок. Для управлением содержимым окна, вы можете вызвать ToolWindow.getContentManager(). Чтобы добавить вкладку («content»), необходимо сначала создать ее путем вызова ContentManager.getFactory().createContent(), а затем добавить в окно инструментов, с помощью ContentManager.addContent().

Вы можете определить, разрешено ли пользователю закрывать вкладки, или глобально, или для каждой в отдельности. Последнее осуществляется путем определения параметра canCloseContents функции registerToolWindow(), или указав в файле plugin.xml. Даже если закрытие вкладок разрешено глобально, его можно отключить для конкретной вкладки путем вызова .

Диалоги

Для отображения диалогового окна, вызовите метод show() и затем используйте метод getExitCode() для проверки, как было закрыто диалоговое окно.

Для настройки кнопок, отображаемых в диалоговом окне (т.е. замены стандартного набора кнопок ОК/Отмена/Помощь), можно переопределить методы createActions() или createLeftActions(). Оба этих метода возвращают массив объектов Swing Action. Если кнопка, которую вы добавляете закрывает диалоговое окно, можно использовать DialogWrapperExitAction в качестве базового класса для действия.

Всплывающие окна

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

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

  • createComponentPopupBuilder() — наиболее универсальный способ показать любой Swing-компонента внутри popup.
  • createListPopupBuilder() — создает всплывающее окно для выбора одного или нескольких элементов из Swing JList.
  • createConfirmation() — создает всплывающее окно для выбора между двумя вариантами и выполнения различных действий в зависимости от выбранного.
  • createActionGroupPopup() — создает popup, который показывает группу действий и выполняет то, которое выбрано пользователем.

Если вам нужно создать списочный всплывающий диалог, но обычный JList не устраивает — например, нежелательно собирать действия в группу, вы можете работать непосредственно с интерфейсом ListPopupStep и методом JBPopupFactory.createListPopup(). Обычно не требуется реализовывать весь интерфейс, вместо этого можно унаследоваться от класса BaseListPopupStep. Основные методы для переопределения это: getTextFor() (возвращается текст, отображаемый для элемента) и onChosen() (вызывается при выборе элемента). Возвращая новый PopupStep из метода onChosen(), можно реализовать иерархические (вложенные) всплывающие окна.

После того как вы создали окно, нужно отобразить его путем вызова одного из методов show(). Вы можете позволить IntelliJ IDEA автоматически выбрать позицию на основе контекста, путем вызова showInBestPositionFor(), или явно указать позицию через такие методы как showUnderneathOf() и showInCenterOf(). Обратите внимание, что методы show() немедленно возвращают управление, а не ждут, когда всплывающее окно закроется. Если вам нужно выполнить некоторые действия при закрытии окна, то можно привязать к нему слушателя с помощью метода addListener(); или переопределить метод, подобный PopupStep.onChosen(); или присоединить обработчик событий к соответствующему компоненту внутри всплывающего окна.

Уведомления

Один из ведущих принципов дизайна в последних версиях IntelliJ IDEA является предотвращение использования модальных окон для уведомления пользователя об ошибках и других ситуациях, которые могут потребовать его внимания. В качестве замены IntelliJ IDEA предоставляет на выбор несколько немодальных типов уведомлений.

Диалоги

При работе с модальным диалоговым окном, вместо проверки введенных данных при нажатии на кнопку ОК и уведомления пользователя о недопустимых данных в еще одном модальном окне, рекомендуется использовать метод DialogBuilder.doValidate(), который был описан ранее.

Подсказки редактора

Для действий, вызываемых из редактора (например, рефакторинг, навигации и тому подобное) лучший способ уведомления пользователя о невозможности выполнения действий — это использование класса HintManager. Его метод showErrorHint() отображает плавающее над редактором окно, которое скрывается автоматически, когда пользователь начинает выполнение другого действия в редакторе. Остальные методы HintManager можно использоваться для отображения прочих видов немодальных уведомлений в виде подсказок над редактором.

Высокоуровневые уведомления
  • пользователь может управлять каждый типом уведомлений, перечисленных в разделе «Settings | Notifications»;
  • все отображенные уведомления, собираются в окне инструментов «Event Log» и могут быть просмотрены позднее.

Параметр GroupDisplayId конструктора Notication указывает тип уведомления; пользователь может выбрать тип отображения, соответствующий типу каждого уведомления в разделе Settings | Notifications. Чтобы указать предпочтительный тип, необходимо вызвать Notifications.Bus.register() перед показом уведомления.

Выбор классов и файлов

Выбор файла

Класс FileChooserDescriptor позволяет вам проконтролировать, какие файлы могут быть выбраны. Параметры конструктора определяют можно ли выбрать файлы и/или каталоги, допускается ли выбор нескольких элементов. Для более точного контроля можно перегрузить метод isFileSelectable(). Вы также можете настроить отображение файлов путем перегрузки методов getIcon(), getName() и getComment() класса FileChooserDescriptor. Обратите внимание, что родной диалог выбора файлов Mac OS X не поддерживает большую часть настроек, так что если вы полагаетесь на них, необходимо использовать перегрузку метода chooseFiles(), которая отображает стандартное диалоговое окно IntelliJ IDEA.

Очень распространенный способ выбора файла — использовать текстовое поле для ввода пути с многоточием (". ") для отображения диалога выбора файлов. Для создания такого элемента управления, используйте компонент TextFieldWithBrowseButton и вызовите его метод addBrowseFolderListener(), чтобы настроить средство выбора файлов. В качестве дополнительного бонуса это даст возможность автозавершения имени файла при вводе пути в текстовом поле вручную.

Альтернативный UI для выбора файлов, который идеально подходит, когда необходим поиск файла по названию, доступен через класс TreeFileChooserFactory. Диалоговое окно, используемое этим API имеет две вкладки: одна показывает структуру проекта, другая — список файлов, аналогичный используемому в «Goto File». Для отображения диалогового окна, вызовите showDialog() на объекте, возвращенном из createFileChooser() и затем вызовите getSelectedFile() для получения пользовательского выбора.

Выбор класса и пакета

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

Для выбора пакета Java, можно использовать класс PackageChooserDialog.

Компоненты редактора

По сравнению со Swing JTextArea, компонент редактора IntelliJ IDEA имеет массу преимуществ — подсветка синтаксиса, автозавершение кода, сворачивание кода и многое другое. Редакторы в IntelliJ IDEA обычно отображаются в виде вкладок редактора, но они могут быть внедрены в диалоговые окна или окна инструментов. Это позволяет компонент EditorTextField.

  • Тип файла, согласно которому выполняется синтаксический анализ текста в поле;
  • Будет ли текстовое поле только для чтения;
  • Является ли текстовое поле однострочным или многострочным.
  • Используйте JavaCodeFragmentFactory.getInstance().createReferenceCodeFragment() для создания фрагмента кода, представляющего имя класса или пакета;
  • Вызовите PsiDocumentManager.getInstance().getDocument() чтобы получить документ, соответствующий фрагменту кода;
  • Передайте полученный документ в конструктор EditorTextField или его метод setDocument().

Списки и деревья

JBList и Tree
ColoredListCellRenderer и ColoredTreeCellRenderer

Когда вам нужно настроить представление элементов в поле со списком или дереве, рекомендуется использовать классы ColoredListCellRenderer или ColoredTreeCellRenderer в качестве средства визуализации ячеек. Эти классы позволяют собирать представления из нескольких фрагментов текста с разными атрибутами (посредством вызова append()) и применять дополнительный значок для элемента (путем вызова setIcon()). Система визуализации автоматически берет на себя настройку правильного цвета текста для выбранных элементов и многие другие платформозависимые детали рендеринга.

ListSpeedSearch и TreeSpeedSearch

Для облегчения выбора элементов с помощью клавиатуры в списке или дереве, к ним можно применить обработчик быстрого поиска. Это можно сделать простым вызовом или . Если вам нужно настроить текст, который используется для поиска элемента, можно переопределить метод getElementText(). Кроме того, можно передать функцию для преобразования элементов в строки (как elementTextDelegate в конструктор ListSpeedSearch или как метод toString() в конструктор TreeSpeedSearch).

ToolbarDecorator

Весьма распространенная задача при разработке плагина — отображение списка или дерева, где пользователь мог бы бы добавлять, удалять, редактировать или переупорядочить элементы. Осуществление этой задачи значительно облегчаются классом ToolbarDecorator. Этот класс содержит панель инструментов с действиями, привязанными к элементам и автоматически позволяет drag & drop изменение порядка элементов в списках, если это поддерживает нижележащая модель списка. Положение панели инструментов (выше или ниже списка) зависит от платформы, на которой выполняется IntelliJ IDEA.

  • Если вам нужна поддержка удаления и изменения порядка элементов в списке, убедитесь, что модель вашего списка реализует интерфейс EditableModel. CollectionListModel — это удобный класс, реализующий этот интерфейс.
  • Вызовите ToolbarDecorator.createDecorator для создания экземпляра декоратора.
  • Если вам нужна поддержка добавления и/или удаления элементов, вызовите setAddAction() и/или setRemoveAction().
  • Если вам нужны другие кнопки в дополнение к стандартным, вызовите addExtraAction() или setActionGroup().
  • Вызовите createPanel() и добавьте возвращенный компонент к вашей панели.

Прочие Swing-компоненты

Функция showCheckboxMessageDialog() обеспечивает простой способ реализации флажка «Do not show this again».

JBSplitter

Класс JBSplitter является заменой для стандартного класса JSplitPane. В отличие от некоторых других, улучшенных JetBrains Swing-компонентов это не равноценная замена, т.к. он имеет другой API. Однако, чтобы добиться единообразия в пользовательском интерфейсе, рекомендуется использовать JBSplitter вместо стандартного JSplitPane.
Чтобы добавить компоненты в разделитель, вызовите методы setFirstComponent() и setSecondComponent().

JBSplitter поддерживает автоматическое запоминание пропорции. Для того, чтобы включить его, вызовите метод setSplitterProportionKey() и передайте идентификатор, под которым будет храниться пропорция.

JBTabs

Класс JBTabs является реализацией вкладок от JetBrains, используемой в редакторе и некоторых других компонентах. Она имеет значительно другой look & feel, по сравнению со стандартными вкладками Swing и выглядит более инородно на платформе Mac OS X, так что оставляем за вами выбор, какая реализация вкладок будет более подходящей для вашего плагина.

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