プラグイン作って覚えたことを淡々と記録するよ(Balloon編)

イヤ,プラグインは作ってないけどね。:-P
Maven ProjectsやChangesツールウィンドウにバルーンが出ていたので,もしやと思いOpenAPIを調べてみたよ。そしたら,いかにもなAPIが見つかった。

  • com.intellij.openapi.ui.popup.Balloon
  • com.intellij.openapi.ui.popup.BalloonBuilder

同パッケージにある JBPopupFactoryのメソッドを調べてみたら,こんなのも見つけた。

createBalloonBuilder

public abstract BalloonBuilder createBalloonBuilder(@NotNull
javax.swing.JComponent content)
createBalloonBuilder
public abstract BalloonBuilder createHtmlTextBalloonBuilder(@NotNull
java.lang.String htmlContent,
@Nullable
javax.swing.Icon icon,
java.awt.Color fillColor,
@Nullable
javax.swing.event.HyperlinkListener listener)


こんな面白いAPI試さないワケないので,さっそく試してみた。

こんなツールウィンドウ作って,

こんなコードでバルーン出してみる。

  private JButton button;
  private int count = 0;

  private void initToolWindow() {
      :
    myContentPanel.add(button = new JButton("Click Me"));
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            showBalloon();
        }
    });
      :
  }

  private void showBalloon() {
    count++;
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        Balloon.Position pos = count % 4 == 0 ? Balloon.Position.above :
                               count % 4 == 1 ? Balloon.Position.atLeft :
                               count % 4 == 2 ? Balloon.Position.atRight : Balloon.Position.below;
        BalloonBuilder builder = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("<i>Hello World</i><br>IntelliJ IDEA<br>" + pos, null, Color.WHITE, null);
        Balloon balloon = builder.createBalloon();
        balloon.show(new RelativePoint(button, new Point(button.getWidth() / 2 , button.getHeight() / 2)), pos);
      }
    });

ポジション指定で上下左右の4方向にでる。

サイズは自動計算してくれてるけど,表示領域がIntelliJ内に限られるので,ちょっと無理すると(↓)こんな感じにくずれる。


BalloonBuilder,Balloonの組み合わせはいろいろ細かい設定できるんだけど,その細かさがウザいという話もある。たとえばツールウィンドウの位置や非表示のときなどの調整を自前でしないとイケないとか。
それに先のMaven ProjectsやChangesツールウィンドウのバルーンは,ツールウィンドウの名称部分(下図の強調部分。『アンカー』って言うらしい)に表示されていたはずだ。


「このアンカーにバルーン表示するのはどうしたらいいのだろう?」と調べるも手がかりが見つからなかったので,しょうがないからMaven Integrationプラグインの中身を拝見*1。結構鼻が利くようになってたようで,案外簡単に該当箇所を見つける事ができた。:-)
なんのことはない「ToolWindow.notifyByBalloon()」って,いかにもなAPIがちゃんとありましたよ,ってなことで,こんなアクション作って動作テスト。

public class BalloonAction extends AnAction {
  private int count = 0;

  public void actionPerformed(AnActionEvent e) {
    Project project = (Project) DataKeys.PROJECT.getData(e.getDataContext());
    ToolWindowManager.getInstance(project)
                     .notifyByBalloon("SimpleToolWindow",
                                 count % 3 == 0 ? MessageType.INFO :
                                 count % 3 == 1 ? MessageType.ERROR :
                                                  MessageType.WARNING, "<b>Hello World</b>");
    count++;
  }
}

さすが,こちらは空気読んでツールウィンドウの場所に応じてバルーンの表示位置を調整してくれる。ただちょっとアイコンがジャマくさいね(@Nullableだからnull指定すりゃいいか)。


まあでも,APIが特定できたんで,そこ覗けば*2ツールウィンドウのアンカー取得方法もわかるだろうから,気に入らなければ気に入るようなコードを書けばいいんだけどね。:-P


それに,こんな面白いAPI知っちゃったからには,なんかに使いたくなるのが人情ってなもんで,IdeaSabotterに使えないかなぁ〜とか妄想中。:-)

*1:良い子はマネしちゃいけないよ

*2:繰り返すけど,良い子はマネしちゃいけないよ