In this part: user interface components. The previous part is here .

IntelliJ IDEA includes a large number of custom Swing components. Using these components in your plugins ensures that they look and work consistent with the rest of the IDE user interface and often reduces the size of the code, compared to using standard Swing components.
Menus and toolbars
Menus and toolbars (toolbars) are built using the action system (as already described in the
second part).
Tool windows
Tool windows are panels that are displayed to the left, bottom, and right of the main IntelliJ IDEA window. On each side there are two groups of instrument windows - primary and secondary, and at the same time only one group can be active.
')
Each tool window can contain several tabs (called “contents” in the API). For example, the toolwindow “Run” displays a tab for each active launch configuration, and “Changes” displays a fixed set of tabs depending on the version control system used in the project.
There are two main scenarios for using toolboxes in plugins. In the first scenario (used, for example, in Ant and Commander plugins), the tool window button is always displayed, hence the user can activate and interact with the functionality of the plugin at any time. In the second scenario (used by the “Analyze Dependencies” action) a tool window is created in order to show the results of a specific operation and can be closed by the user immediately after the operation is completed.
In the first scenario, the window is registered in the plugin.xml file using the extension point
<<toolWindow>>
settings. The extension point attributes contain data that is used to display the toolwindow button:
- The “id” attribute (mandatory) - corresponds to the text displayed on the toolwindow button;
- Attribute “anchor” (mandatory) - sets the side of the screen to which the tool window is attached (“left”, “right” or “bottom”);
- The logical attribute “secondary” (optional) indicates whether the tool window will belong to the secondary group;
- “Icon” (optional) - the icon that will be displayed on the button (13 x 13 pixels).
In addition to this, you should specify a factory class (in the “factoryClass” attribute) that implements the
ToolWindowFactory interface. When the user clicks the tool window button, the createToolWindowContent () method is called and initializes the user interface. This procedure ensures that unused tool windows do not cause any overhead in memory usage or startup time: if the user does not interact with your plug-in's toolwindow, no code will be loaded or executed.
If the tool window is not required for all types of projects, you can specify an optional conditionClass attribute that contains the fully qualified class name that implements the Condition interface (it can be the same class that implements the factory). If the value () method returns “false”, the tool window will not be displayed. Please note that the condition is calculated only once when loading the project. If you want to show and hide tool windows dynamically, while working with a project, you need to use the second tool window registration script.
Configuration example <extensions defaultExtensionNs="com.intellij"> <toolWindow id="My Sample Tool Window" icon="/myPackage/icon.png" anchor="right" factoryClass="myPackage.MyToolWindowFactory" /> </extensions>
The second script is a normal call to the
ToolWindowManager .registerToolWindow () method from the plugin code. This method has several overloads that can be used depending on your tasks. If you use an overload that accepts a Swing component, then it becomes the first tab displayed in the tool window.
Displaying the contents of many toolwindows requires access to indexes. Because of this, the windows are turned off when building indexes, but it will remain active if you pass “true” as the value of the canWorkInDumbMode parameter to the registerToolWindow () function.
As mentioned earlier, tool windows can contain several tabs. To manage the contents of a window, you can call
ToolWindow .getContentManager (). To add a tab (“content”), you must first create it by calling
ContentManager .getFactory (). CreateContent (), and then add it to the toolbox using ContentManager.addContent ().
You can determine whether the user is allowed to close tabs, either globally or individually. The latter is done by defining the canCloseContents parameter of the registerToolWindow () function, or by specifying
<canCloseContents="true">
in the plugin.xml file. Even if tab closing is enabled globally, it can be disabled for a particular tab by calling
<Content.setCloseable(false)>
.
Dialogues
DialogWrapper is the base class for all modal (and some non-modal) dialog boxes used in the IntelliJ IDEA plugin. It provides the following features:
- The location of the buttons (the platform-specific order of the OK / Cancel buttons, Mac OS-specific Help button);
- Context help;
- Remembering the size of the dialog box;
- Data validation (and displaying an error message if the data entered in the dialog box is incorrect);
- Keyboard shortcuts: Esc to close the dialog box, left / right to switch between the buttons and Y / N for “Yes / No” answers if they are present in the dialog box;
- Optional checkbox “Do not ask again”.
When using the DialogWrapper class for a custom dialog box, you must perform the following steps:
- Call the designer of the base class and transfer the project within which the dialog box or parent component for the dialog box will be displayed;
- Call the init () method from the class constructor of the dialog box;
- Call the setTitle () method to set the title for the dialog box;
- Implement the createCenterPanel () method to return the component responsible for the main content of the dialog box;
- Optional: Override the getPreferredFocusedComponent () method, which returns the component that will be in focus when the dialog box appears;
- Optional: Override the getDimensionServiceKey () method to determine the identifier that will be used to preserve the size of the dialog box;
- Optional: Override the getHelpId () method to set the help context associated with the dialog box.
The DialogWrapper class is often used in conjunction with the UI Designer forms. To bind the form and your class that extends DialogWrapper, bind the root form panel to the field and return it from the createCenterPanel () method.
To display a dialog box, call the show () method and then use the getExitCode () method to check how the dialog box was closed.
You can override the createActions () or createLeftActions () methods to customize the buttons displayed in the dialog box (ie, replacing the standard set of OK / Cancel / Help buttons). Both of these methods return an array of Swing Action objects. If the button you add closes the dialog box, you can use DialogWrapperExitAction as the base class for the action.
To check the data entered in the dialog box, you can override the doValidate () method. The method will be called automatically by timer. If currently entered data is valid, you need to return null. Otherwise, return a ValidationInfo object that encapsulates the error message and, optionally, a component associated with incorrect data. If you specify a component, an error icon will be displayed next to it and it will receive focus when the user tries to click the OK button.
Popup windows
The IntelliJ IDEA user interface makes extensive use of pop-up windows — semi-modal windows that do not have an explicit close button and automatically disappear when the focus is lost. Using these controls in your plugin provides a single user interface between the plugin and the rest of the IDE.
Pop-up windows can have a title, can be moved if necessary and allow resizing (remembering is supported), they can be nested (it is allowed to show additional pop-up windows when an element is selected).
The
JBPopupFactory interface allows you to create pop-up windows that display different types of Swing components, depending on your specific needs. The most commonly used methods are:
- createComponentPopupBuilder () is the most universal way to show any Swing component inside a popup.
- createListPopupBuilder () - creates a popup window for selecting one or more items from a Swing JList.
- createConfirmation () - creates a pop-up window for choosing between two options and performing various actions depending on the selected one.
- createActionGroupPopup () - creates a popup that shows a group of actions and executes the one selected by the user.
Action group popups support various ways to select an action using the keyboard, in addition to the usual arrow keys. By transferring the value of one of the constants to the ActionSelectionAid enumeration, you can choose whether it will be possible to select an action by pressing the numeric key corresponding to its ordinal number, entering a part of its text (accelerated search) or pressing the mnemonic symbol. For pop-up windows with a fixed set of elements, it is recommended to choose the method of ordinal numbering; for pop-ups with variable and potentially large numbers of items, an accelerated search usually works best.
If you need to create a popup popup dialog, but the usual JList does not suit you - for example, it is undesirable to collect actions into a group, you can work directly with the
ListPopupStep interface and the JBPopupFactory.createListPopup () method. Usually it is not necessary to implement the entire interface; instead, you can inherit from the
BaseListPopupStep class. The basic methods for overriding this are: getTextFor () (the text that is displayed for the element is returned) and onChosen () (called when the element is selected). By returning a new PopupStep from the onChosen () method, you can implement hierarchical (nested) pop-up windows.
After you have created a window, you need to display it by calling one of the show () methods. You can let IntelliJ IDEA automatically select a context-based position by calling showInBestPositionFor (), or explicitly specify a position using methods such as showUnderneathOf () and showInCenterOf (). Note that the show () methods return control immediately, rather than waiting for the pop-up window to close. If you need to perform some actions when closing a window, you can bind a listener to it using the addListener () method; or override a method similar to PopupStep.onChosen (); or attach an event handler to the corresponding component inside the popup.
Notifications
One of the leading design principles in recent versions of IntelliJ IDEA is to prevent modal windows from being used to notify users of errors and other situations that may require their attention. As a replacement, IntelliJ IDEA provides a choice of several modeless notification types.
Dialogues
When working with a modal dialog box, instead of checking the entered data when you click on the OK button and notify the user about invalid data in another modal window, it is recommended to use the DialogBuilder.doValidate () method that was described earlier.
Editor Tips
For actions called from the editor (for example, refactoring, navigation, and the like), the best way to notify the user about the impossibility of taking actions is to use the
HintManager class. Its showErrorHint () method displays a window floating above the editor that disappears automatically when the user starts another action in the editor. The remaining methods of HintManager can be used to display other types of modeless notifications in the form of hints above the editor.
High Level Notifications
The most common way to display modeless notifications is to use the
Notifications class. It has two main advantages:
- the user can control each type of notification listed in the “Settings | Notifications ";
- all displayed notifications are collected in the Event Log tool window and can be viewed later.
The main method used to display the notification is Notifications.Bus.notify (). Notification text may contain HTML tags. You can allow the user to interact with the notification by including hyperlinks and passing the instance of NotificationListener into the constructor of the
Notification class.
The GroupDisplayId parameter of the Notication constructor indicates the type of notification; the user can select the type of display corresponding to the type of each notification in the Settings | Notifications To specify a preferred type, you must call Notifications.Bus.register () before displaying a notification.
Select classes and files
File selection
To allow the user to select a file, directory, or several files, use the
FileChooser method .chooseFiles (). This method has several overloads, one of which returns void and gets a callback function that takes a list of selected files as a parameter. This is the only overload that will display the native dialog box on Mac OS X.
The
FileChooserDescriptor class allows you to control which files can be selected. The constructor parameters determine whether files and / or directories can be selected, whether multiple elements can be selected. For more precise control, you can overload the isFileSelectable () method. You can also customize the display of files by overloading the getIcon (), getName () and getComment () methods of the FileChooserDescriptor class. Note that the native Mac OS X file selection dialog does not support most of the settings, so if you rely on them, you must use the chooseFiles () method overload, which displays the standard IntelliJ IDEA dialog box.
A very common way to select a file is to use a text field to enter a path with an ellipsis ("...") to display the file selection dialog. To create such a control, use the
TextFieldWithBrowseButton component and call its addBrowseFolderListener () method to configure the file picker. As an added bonus, this will allow the completion of the file name when you enter the path in the text box manually.
An alternate UI for selecting files, which is ideal when you need to search for a file by name, is available through the
TreeFileChooserFactory class. The dialog box used by this API has two tabs: one shows the structure of the project, the other - a list of files similar to that used in “Goto File”. To display a dialog box, call showDialog () on the object returned from createFileChooser () and then call getSelectedFile () to get a custom selection.
Choosing a class and package
If you want to offer the user the choice of a Java class, you can use the
TreeClassChooserFactory class. Its various methods allow you to specify a search scope in order to limit the selection to descendants of a particular class or interface implementations, as well as include or exclude internal classes from the list.
To select a Java package, you can use the
PackageChooserDialog class.
Editor components
Compared to Swing JTextArea, the IntelliJ IDEA editor component has a lot of advantages - syntax highlighting, code completion, code folding, and much more. The editors in IntelliJ IDEA are usually displayed as editor tabs, but they can be embedded in dialog boxes or tool windows. This allows the
EditorTextField component.
When creating an EditorTextField, you can specify the following attributes:
- The file type according to which the text is parsed in the field;
- Will the text field be read only;
- Whether the text field is single-line or multi-line.
One common use case for EditorTextField is to edit the name of a Java class or package. This can be achieved using the following steps:
- Use JavaCodeFragmentFactory .getInstance (). CreateReferenceCodeFragment () to create a code fragment representing the name of a class or package;
- Call PsiDocumentManager .getInstance (). GetDocument () to get the document corresponding to the code fragment;
- Pass the resulting document to the EditorTextField constructor or its setDocument () method.
Lists and trees
JBList and Tree
Whenever you plan to use the standard Swing component of the JList, consider using its alternative JBList, which supports the following additional features:
- Drawing a tooltip containing the full text of the element, if it does not fit in the field width;
- Drawing a gray text message in the middle of the list when it contains no elements (text can be customized by calling getEmptyText (). SetText ());
- Drawing the “Busy” icon in the upper right corner of the list when performing a background operation (activated by calling setPaintBusy ()).
Similar to JBList, there is a class com.intellij.ui.treeStructure.Tree providing a replacement for the standard JTree class. In addition to JBList features, it supports Mac-style rendering and auto-scrolling for drag & drop.
ColoredListCellRenderer and ColoredTreeCellRenderer
When you need to customize the presentation of items in a combo box or tree, it is recommended to use the classes
ColoredListCellRenderer or
ColoredTreeCellRenderer as a means of visualizing cells. These classes allow you to assemble views from several pieces of text with different attributes (by calling append ()) and use an additional icon for an element (by calling setIcon ()). The visualization system automatically assumes the setting of the correct text color for the selected elements and many other platform-specific rendering details.
ListSpeedSearch and TreeSpeedSearch
To facilitate the selection of items using the keyboard in the list or tree, you can apply a quick search handler to them. This can be done by a simple call.
<new ListSpeedSeach(list)>
or
<new TreeSpeedSearch(tree)>
. If you need to customize the text that is used to search for an item, you can override the getElementText () method. In addition, you can pass a function to convert elements to strings (as elementTextDelegate in the ListSpeedSearch constructor or as the toString () method in the TreeSpeedSearch constructor).
ToolbarDecorator
A very common task when developing a plugin is to display a list or tree where the user could add, delete, edit or reorder items. This task is greatly facilitated by the
ToolbarDecorator class. This class contains a toolbar with actions attached to elements and automatically allows drag & drop reordering of elements in lists if it supports the underlying list model. The position of the toolbar (above or below the list) depends on the platform on which IntelliJ IDEA is running.
To use the toolbar decorator:
- If you need support for deleting and reordering items in the list, make sure that your list model implements the EditableModel interface. CollectionListModel is a convenient class that implements this interface.
- Call ToolbarDecorator.createDecorator to create an instance of the decorator.
- If you need support for adding and / or removing items, call setAddAction () and / or setRemoveAction ().
- , addExtraAction() setActionGroup().
- createPanel() .
Swing-
Messages
Messages , ( ) ( ). . Mac OS X .
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, , .
...
: 1 , 2 , 3 , 4 , 5 , 6 , 7 .