Swing/TranslucentToolTips の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/TranslucentToolTips へ行く。
- Swing/TranslucentToolTips の差分を削除
--- category: swing folder: TranslucentToolTips title: JToolTipを半透明にする tags: [JToolTip, JList, Calendar] author: aterai pubdate: 2019-06-03T15:15:47+09:00 description: JToolTipを半透明に設定し、その形状や表示位置も変更します。 image: https://drive.google.com/uc?id=1yfrneVdDempFHGb54FMzcxO4DIlyzJd-Ew hreflang: href: https://java-swing-tips.blogspot.com/2019/06/make-jtooltip-translucent-and-change.html lang: en --- * 概要 [#summary] `JToolTip`を半透明に設定し、その形状や表示位置も変更します。 #download(https://drive.google.com/uc?id=1yfrneVdDempFHGb54FMzcxO4DIlyzJd-Ew) * サンプルコード [#sourcecode] #code(link){{ class BalloonToolTip extends JToolTip { private static final int TRI_HEIGHT = 4; 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()) { Optional.ofNullable(SwingUtilities.getRoot(c)) .filter(JWindow.class::isInstance).map(JWindow.class::cast) .ifPresent(w -> w.setBackground(new Color(0x0, true))); } }; addHierarchyListener(listener); setOpaque(false); setForeground(Color.WHITE); setBackground(new Color(0xC8_00_00_00, true)); setBorder(BorderFactory.createEmptyBorder(5, 5, 5 + TRI_HEIGHT, 5)); } @Override public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); d.height = 32; return d; } @Override protected 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.dispose(); super.paintComponent(g); } private Shape makeBalloonShape() { int w = getWidth() - 1; int h = getHeight() - TRI_HEIGHT - 1; int r = 10; int cx = getWidth() / 2; Polygon triangle = new Polygon(); triangle.addPoint(cx - TRI_HEIGHT, h); triangle.addPoint(cx, h + TRI_HEIGHT); triangle.addPoint(cx + TRI_HEIGHT, h); Area area = new Area(new RoundRectangle2D.Float(0, 0, w, h, r, r)); area.add(new Area(triangle)); return area; } } }} * 解説 [#explanation] - 半透明化と形状の変更 -- `JToolTip`自体は`setOpaque(false)`で透明化し、別途`JToolTip#paintComponent(...)`をオーバーライドして吹き出し図形を半透明色で描画 -- `JToolTip`が対象コンポーネントの親`JFrame`外に表示される場合は`JToolTip`の親`JWindow`を`setBackground(new Color(0x0, true)))`で完全透明化 - 表示位置の変更 -- `JList#getToolTipLocation(...)`をオーバーライドして、マウスカーソルの下側ではなく対象セルの真上に`JToolTip`が表示されるよう位置を調整 #code{{ @Override public String getToolTipText(MouseEvent e) { Point p = e.getPoint(); int idx = locationToIndex(p); Rectangle rect = getCellBounds(idx, idx); if (idx < 0 || !rect.contains(p.x, p.y)) { return null; } Contribution value = getModel().getElementAt(idx); String act = value.activity == 0 ? "No" : Objects.toString(value.activity); return "<html>" + act + " contribution <span style='color:#C8C8C8'> on " return "<html>" + act + " contribution <span style='color:#C8C8C8'> on " + value.date.toString(); } @Override public Point getToolTipLocation(MouseEvent e) { Point p = e.getPoint(); int i = locationToIndex(p); Rectangle rect = getCellBounds(i, i); String toolTipText = getToolTipText(e); if (Objects.nonNull(toolTipText)) { JToolTip tip = createToolTip(); tip.setTipText(toolTipText); Dimension d = tip.getPreferredSize(); int gap = 2; return new Point((int) (rect.getCenterX() - d.getWidth() / 2d), rect.y - d.height - gap); } return null; } @Override public JToolTip createToolTip() { if (tip == null) { tip = new BalloonToolTip(); tip.setComponent(this); } return tip; } }} * 参考リンク [#reference] - [[JListでウィークカレンダーを作成してヒートマップを表示する>Swing/CalendarHeatmapList]] - [[JListのセル上にToolTipを表示する>Swing/ToolTipOnCellBounds]] - [[JToolTipの形状を吹き出し風に変更する>Swing/BalloonToolTip]] * コメント [#comment] #comment #comment