Swing/SelectableToolTip のバックアップ(No.4)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/SelectableToolTip へ行く。
- 1 (2020-02-03 (月) 17:38:55)
- 2 (2020-02-05 (水) 16:37:52)
- 3 (2020-05-31 (日) 21:06:50)
- 4 (2021-11-12 (金) 13:56:40)
- 5 (2023-03-16 (木) 16:37:23)
- category: swing
folder: SelectableToolTip
title: JToolTipの文字列を選択・コピー可能にする
tags: [JToolTip, JPopupMenu, JEditorPane]
author: aterai
pubdate: 2020-02-03T17:37:47+09:00
description: JToolTipの代わりにJPopupMenuを表示し、その内部に配置したコンポーネントのクリックや文字列の選択・コピーを可能にします。
image: https://drive.google.com/uc?id=1gSgkKvGUaTX9rESzzcCHyhNRREYr22cq
hreflang:
href: https://java-swing-tips.blogspot.com/2020/05/make-text-in-jtooltip-selectable-and.html lang: en
概要
JToolTip
の代わりにJPopupMenu
を表示し、その内部に配置したコンポーネントのクリックや文字列の選択・コピーを可能にします。
Screenshot
Advertisement
サンプルコード
JEditorPane hint = new JEditorPane();
hint.setEditorKit(new HTMLEditorKit());
hint.setEditable(false);
hint.setOpaque(false);
JCheckBox check = new JCheckBox();
check.setOpaque(false);
JPanel panel = new JPanel(new BorderLayout());
panel.add(hint);
panel.add(check, BorderLayout.EAST);
JPopupMenu popup = new JPopupMenu();
popup.add(new JScrollPane(panel));
popup.setBorder(BorderFactory.createEmptyBorder());
JEditorPane editor = new JEditorPane() {
@Override public JToolTip createToolTip() {
JToolTip tip = super.createToolTip();
tip.addHierarchyListener(e -> {
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0
&& e.getComponent().isShowing()) {
panel.setBackground(tip.getBackground());
popup.show(tip, 0, 0);
}
});
return tip;
}
};
editor.setEditorKit(new HTMLEditorKit());
editor.setText(HTML_TEXT);
editor.setEditable(false);
editor.addHyperlinkListener(e -> {
JEditorPane editorPane = (JEditorPane) e.getSource();
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
JOptionPane.showMessageDialog(editorPane, "You click the link with the URL " + e.getURL());
} else if (e.getEventType() == HyperlinkEvent.EventType.ENTERED) {
editorPane.setToolTipText("");
Optional.ofNullable(e.getSourceElement())
.map(elem -> (AttributeSet) elem.getAttributes().getAttribute(HTML.Tag.A))
.ifPresent(attr -> {
String title = Objects.toString(attr.getAttribute(HTML.Attribute.TITLE));
String url = Objects.toString(e.getURL());
// String url = Objects.toString(attr.getAttribute(HTML.Attribute.HREF));
hint.setText(String.format("<html>%s: <a href='%s'>%s</a>", title, url, url));
popup.pack();
});
} else if (e.getEventType() == HyperlinkEvent.EventType.EXITED) {
editorPane.setToolTipText(null);
}
});
View in GitHub: Java, Kotlin解説
JComponent#createToolTip()
メソッドをオーバーライドし、JToolTip
にHierarchyListener
を追加JToolTip
が表示状態になったらそのJToolTip
を親にしてJPopupMenu
を表示JToolTip
はJPopupMenu
の背後に隠れているJPopupMenu
にはJMenuItem
ではなくJEditorPane
とJCheckBox
を配置したJPanel
を追加している
- マウスカーソルを移動して親の
JToolTip
が非表示になってもJPopupMenu
は閉じないので、内部のJCheckBox
をクリックしたりJEditorPane
の文字列を選択しCtrl-Cなどでコピー可能- 通常の
JPopupMenu
なので親JFrame
などをクリックしてフォーカスが移動すると非表示になる
- 通常の