Swing/BalloonToolTip の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/BalloonToolTip へ行く。
- Swing/BalloonToolTip の差分を削除
---
category: swing
folder: BalloonToolTip
title: JToolTipの形状を吹き出し風に変更する
tags: [JToolTip, JWindow, HeavyWeightWindow, HierarchyListener, Shape, Area, JList]
author: aterai
pubdate: 2016-12-12T01:24:24+09:00
description: JToolTipの形状を吹き出し風に変更し、JListのセル上にこれを表示します。
image: https://drive.google.com/uc?id=1tL6BwEx2s_gjjZZX3nwBOUAtoslcPXQnrA
hreflang:
href: https://java-swing-tips.blogspot.com/2016/12/change-shape-of-jtooltip-to-balloon.html
lang: en
---
* 概要 [#summary]
`JToolTip`の形状を吹き出し風に変更し、`JList`のセル上にこれを表示します。
#download(https://drive.google.com/uc?id=1tL6BwEx2s_gjjZZX3nwBOUAtoslcPXQnrA)
* サンプルコード [#sourcecode]
#code(link){{
class BalloonToolTip extends JToolTip {
private HierarchyListener listener;
@Override public void updateUI() {
removeHierarchyListener(listener);
super.updateUI();
listener = e -> {
Component c = e.getComponent();
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0
&& c.isShowing()) {
Window w = SwingUtilities.getWindowAncestor(c);
if (w != null && w.getType() == Window.Type.POPUP) {
// Popup$HeavyWeightWindow
w.setBackground(new Color(0x0, true));
}
}
};
addHierarchyListener(listener);
setOpaque(false);
setBorder(BorderFactory.createEmptyBorder(8, 5, 0, 5));
}
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 28;
return d;
}
@Override public void paintComponent(Graphics g) {
Shape s = makeBalloonShape();
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(getBackground());
g2.fill(s);
g2.setColor(getForeground());
g2.draw(s);
g2.dispose();
super.paintComponent(g);
}
private Shape makeBalloonShape() {
Insets i = getInsets();
int w = getWidth() - 1;
int h = getHeight() - 1;
int v = i.top / 2;
Polygon triangle = new Polygon();
triangle.addPoint(i.left + v + v, 0);
triangle.addPoint(i.left + v, v);
triangle.addPoint(i.left + v + v + v, v);
Area area = new Area(new RoundRectangle2D.Float(
0, v, w, h - i.bottom - v, i.top, i.top));
area.add(new Area(triangle));
return area;
}
}
}}
* 解説 [#explanation]
- `setOpaque(false)`で背景色を描画しない`JToolTop`を作成し`JToolTop#paintComponent(...)`をオーバーライドして吹き出し風の背景を描画
- `JToolTop`に`HierarchyListener`を追加しその`JToolTop`が表示状態になった時親が`JWindow`で`Window#getType() == Window.Type.POPUP`かどうかを調べてこれを透明に設定
-- `JToolTop`が元`JFrame`外に表示される場合は`HeavyWeightWindow`に配置して表示されるためこの`JWindow`を透明にする必要がある
-- `JToolTop`が元`JFrame`内に表示される場合はその`JFrame`の`JLayeredPane`の`POPUP_LAYER`に`JToolTop`が描画されるので`setOpaque(false)`な`JToolTop`の背景は描画されない
-- `JWindow#setShape(...)`メソッドでも形状の変更が可能だが、この場合フチを滑らかにすることが難しい
- `JList#createToolTip()`をオーバーライドし通常の`JToolTip`の代わりに`BalloonToolTip`(上記の`JToolTip`)を作成して返すように設定
#code{{
JList<String> list = new JList<String>(model) {
@Override public JToolTip createToolTip() {
JToolTip tip = new BalloonToolTip();
tip.setComponent(this);
return tip;
}
};
}}
* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/java/awt/event/HierarchyListener.html HierarchyListener (Java Platform SE 8)]
- [[JTabbedPaneのツールヒントをタブ位置に対応したふきだしに変更する>Swing/SpeechBalloonToolTipTail]]
* コメント [#comment]
#comment
#comment