ui

DialogWrapper

The DialogWrapper is the base class which is supposed to be used for all modal dialogs (and some non-modal dialogs) shown in IntelliJ Platform plugins. It provides the following features:

  • Button layout (platform-specific order of OK/Cancel buttons, Mac OS-specific Help button)

  • Context help

  • Remembering the size of the dialog

  • Non-modal validation (displaying an error message text when the data entered into the dialog is not valid)

  • Keyboard shortcuts

    • Esc for closing the dialog

    • Left/Right for switching between buttons

    • Y/N for Yes/No actions if they exist in the dialog

  • Optional Do not ask again checkbox

When using the DialogWrapper class for your own dialog, you need to follow these steps:

  • Call the base class constructor and provide either a project in the frame of which the dialog will be displayed, or a parent component for the dialog.

  • Call the init() method from the constructor of your dialog class

  • Call the setTitle() method to set the title for the dialog box

  • Implement the createCenterPanel() method to return the component comprising the main contents of the dialog.

  • Optional: Override the getPreferredFocusedComponent() method and return the component that should be focused when the dialog is first displayed.

  • Optional: Override the getDimensionServiceKey() method to return the identifier which will be used for persisting the dialog dimensions.

  • Optional: Override the getHelpId() method to return the context help topic associated with the dialog.

The DialogWrapper class is often used together with UI Designer forms. In this case, you bind a UI Designer form to your class extending DialogWrapper, bind the top-level panel of the form to a field and return that field from thecreateCenterPanel() method.

To display the dialog, you call the show() method and then use the getExitCode() method to check how the dialog was closed.

To customize the buttons displayed in the dialog (replacing the standard OK/Cancel/Help set of buttons), you can override either the createActions() or createLeftActions() methods. Both of these methods return an array of Swing Action objects. If the button that you’re adding closes the dialog, you can use DialogWrapperExitAction, as the base class for your action.

To validate the data entered into the dialog, you can override the doValidate() method. The method will be called automatically by timer. If the currently entered data is valid, you need to return null from your implementation. Otherwise, you need to return a ValidationInfo class which encapsulates an error message and an optional component associated with the invalid data. If you specify a component, an error icon will be displayed next to it, and it will be focused when the user tries to invoke the OK action.

 

Popups

The IntelliJ Platform user interface makes extensive use of popups - semi-modal windows that have no chrome (explicit closing buttons) and disappear automatically on focus loss. Making use of these controls in your plugin ensures a consistent user experience between your plugin and the rest of the IDE.

Popups can optionally display a title, are optionally movable and resizable (and support remembering their size), and can be nested (show another popup when an item is selected).

The JBPopupFactory interface allows you to create popups that display different kinds of components, depending on your specific needs. The most commonly used methods are:

  • createComponentPopupBuilder() is the most generic one, allowing you to show any Swing component in the popup.

  • createListPopupBuilder() creates a popup for choosing one or more items from a Swing JList.

  • createConfirmation() creates a popup for choosing between two options, and performing different actions depending on which option is selected.

  • createActionGroupPopup() creates a popup which shows the actions from an action group and executes the action selected by the user.

Action group popups support different ways of choosing an action from the keyboard, in additional to the normal arrow keys. By passing one of the constants in the ActionSelectionAid enumeration, you can choose whether an action can be selected by pressing a key corresponding to its sequential number, typing part of its text (speed search) or pressing a mnemonic character. For popups with a fixed set of items, the recommended selection method is sequential numbering; for popups with a variable and potentially large number of items, speed search typically works best.

If you need to create a list-like popup which is more flexible than a simple JList but don’t want to represent the possible choices as actions in an action group, you can work directly with the ListPopupStep interface and theJBPopupFactory.createListPopup() method. Normally you don’t need to implement the entire interface; instead, you can derive from the BaseListPopupStep class. The key methods to override are getTextFor() (returning the text to display for an item) and onChosen() (called when an item is selected). By returning a new popup step from the onChosen()method, you can implement hierarchical (nested) popups.

Once you’ve created the popup, you need to display it by calling one of the show() methods. You can let the IntelliJ Platform automatically choose the position based on the context, by calling showInBestPositionFor(), or specify the position explicitly through methods like showUnderneathOf() and showInCenterOf().

Note:

The show() methods return immediately and do not wait for the popup to be closed.

If you need to perform some action when the popup is closed, you can either attach a listener to it using theaddListener() method, override a method of the popup contents such as PopupStep.onChosen(), or attach an event handler to your own component within the popup.

 

File Choosers

To let a user choose a file, directory or multiple files, use the FileChooser.chooseFiles() method. This method has multiple overloads. The best method to use is the one which returns void and takes a callback receiving the list of selected files as a parameter. This is the only overload which will display a native file open dialog on macOS.

The FileChooserDescriptor class allows you to control which files can be selected. The constructor parameters specify whether files and/or directories can be selected, and whether multiple selection is allowed. For more fine-grained control over the allowed selection, you can overload the isFileSelectable() method. You can also customize the presentation of files by overloading getIcon()getName() and getComment() methods on FileChooserDescriptor. Note that the native Mac OS X file chooser does not support most of the customizations, so if you rely on them, you need to use an overload of chooseFiles() which displays the standard IntelliJ Platform dialog.

A very common way of using file choosers is to use a text field for entering the path with an ellipsis button (“…”) for showing the file chooser. To create such a control, use the TextFieldWithBrowseButton component and call theaddBrowseFolderListener() method on it to set up the file chooser. As an added bonus, this will enable filename completion when entering paths in the text box.

An alternative UI for selecting files, which works best when the most common way of selecting a file is by typing its name, is available through the TreeFileChooserFactory class.

The dialog shown by this API has two tabs:

  • One shows the project structure

  • Another shows a list of files similar to the one used by the Goto File popup.

To show the dialog, call showDialog() on the chooser returned from createFileChooser(), and then callgetSelectedFile to retrieve the user’s selection.

Class and Package Choosers

If you want to offer the user a possibility to select a Java class, you can use the TreeClassChooserFactory class. Its different methods allow you to specify the scope from which the classes are taken, to restrict the choice to descendants of a specific class or implementations of an interface, and to include or exclude inner classes from the list.

For choosing a Java package, you can use the PackageChooserDialog class.

 

EditorTextField

Compared to Swing JTextArea, the IntelliJ Platform’s editor component has a ton of advantages: syntax highlighting support, code completion, code folding and much more. IntelliJ Platform editors are normally displayed in editor tabs, but they can be embedded in dialogs or toolwindows, too. This is enabled by the EditorTextField component.

When creating an EditorTextField, you can specify the following attributes:

  • The file type according to which the text in the text field is parsed;

  • Whether the text field is read-only or editable;

  • Whether the text field is single-line or multiline.

A common use case for EditorTextField is entering the name of a Java class or package. This can be accomplished with the following steps:

 

JBList and Tree

Whenever you would normally use a standard Swing JList component, it’s recommended to use the JBList class as drop-in replacement. JBList supports the following additional features on top of JList:

  • Drawing a tooltip with complete text of an item if the item doesn’t fit into the list box width.

  • Drawing a gray text message in the middle of the list box when it contains no items. The text can be customized by calling getEmptyText().setText().

  • Drawing a busy icon in the top right corner of the list box to indicate that a background operation is being performed. This can be enabled by calling setPaintBusy().

Similarly, the Tree class provides a replacement for the standard JTree class. In addition to the features of JBList, it supports wide selection painting (Mac style) and auto-scroll on drag & drop.

ColoredListCellRenderer and ColoredTreeCellRenderer

When you need to customize the presentation of items in a list box or a tree, it’s recommended to use theColoredListCellRenderer or ColoredTreeCellRenderer classes as the cell renderer. These classes allow you to compose the presentation out of multiple text fragments with different attributes by calling append() and to set an optional icon for the item by calling setIcon. The renderer automatically takes care of setting the correct text color for selected items and of many other platform-specific rendering details.

ListSpeedSearch and TreeSpeedSearch

To facilitate keyboard-based selection of items in a list box or a tree, you can install a speed search handler on it using the ListSpeedSearch and TreeSpeedSearch. This can be done simply by calling new ListSpeedSeach(list) or new TreeSpeedSearch(tree). If you need to customize the text which is used to locate the element, you can override thegetElementText() method. Alternatively, you can pass a function to convert items to strings. A function needs to be passed as elementTextDelegate to the ListSpeedSearch constructor or as toString to the TreeSpeedSearchconstructor.

ToolbarDecorator

A very common task in plugin development is showing a list or a tree where the user is allowed to add, remove, edit or reorder the items. The implementation of this task is greatly facilitated by the ToolbarDecorator class. This class provides a toolbar with actions on items and automatically enables drag & drop reordering of items in list boxes if supported by the underlying list model. The position of the toolbar above or below the list depends on the platform under which the IDE is running.

To use a toolbar decorator:

  • If you need to support removing and reordering of items in a list box, make sure the model of your list implements the EditableModel interface. CollectionListModel is a handy model class that implements this interface.

  • Call ToolbarDecorator.createDecorator to create a decorator instance.

  • If you need to support adding and/or removing items, call setAddAction() and/or setRemoveAction().

  • If you need other buttons in additional to the standard ones, call addExtraAction() or setActionGroup().

  • Call createPanel() and add the component it returns to your panel.

 

Messages

The Messages class provides a way to show simple message boxes, input dialogs (modal dialogs with a text field) and chooser dialogs (modal dialogs with a combo box). The function of different methods of the class should be clear from their names. When running on macOS, the message boxes shown by the Messages class use native UI.

The showCheckboxMessageDialog() function provides an easy way to implement a Do not show this again checkbox on messages.

Note that it is recommended to use non-modal notifications instead of modal message boxes whenever it’s appropriate. Please refer to the Notifications topic for more information.

JBSplitter

The JBSplitter class is JetBrains’ replacement for the standard JSplitPane class. Unlike some other JetBrains-enhanced Swing components, it’s not a drop-in replacement and has a different API. However, to achieve a consistent user experience, it’s recommended to use JBSplitter instead of the standard JSplitPane in your plugins.

To add your components to the splitter, call the setFirstComponent() and setSecondComponent() methods.

JBSplitter supports automatic remembering of the split proportion. In order to enable it, call thesetSplitterProportionKey() method and pass the ID under which the proportion will be stored.

JBTabs

The JBTabs class is JetBrains’ implementation of the tab control, used for editor tabs and a few other components. It has a significantly different look & feel compared to the standard Swing tabs, and looks less native on the macOS platform, so it’s up to you to choose which tab control would be more appropriate for your plugin.

posted @ 2017-05-03 23:18  liqiking  阅读(357)  评论(0编辑  收藏  举报