JToolTipの表示位置をマウスドラッグで変更可能にする
Total: 30
, Today: 30
, Yesterday: 0
Posted by aterai at
Last-modified:
Summary
JToolTip
を親にして背景色などをJToolTip
風に設定したJPopupMenu
を作成し、その内部に配置したJLabel
をドラッグして表示位置を変更します。
Screenshot

Advertisement
Source Code Examples
class ToolTipEditorPane extends JEditorPane {
private final JPanel panel;
protected ToolTipEditorPane(JPanel panel) {
super();
this.panel = panel;
}
@Override public JToolTip createToolTip() {
JToolTip tip = super.createToolTip();
tip.addHierarchyListener(e -> {
boolean showing = e.getComponent().isShowing();
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && showing) {
panel.setBackground(tip.getBackground());
Container p = SwingUtilities.getAncestorOfClass(JPopupMenu.class, panel);
if (p instanceof JPopupMenu) {
// ((JPopupMenu) p).setLightWeightPopupEnabled(false);
((JPopupMenu) p).show(tip, 0, 0);
}
}
});
return tip;
}
}
class DragLabel extends JLabel {
private transient MouseAdapter handler;
@Override public void updateUI() {
removeMouseListener(handler);
removeMouseMotionListener(handler);
super.updateUI();
handler = new PopupDragListener();
addMouseListener(handler);
addMouseMotionListener(handler);
Color bgc = UIManager.getColor("ToolTip.background");
if (bgc != null) {
setBackground(bgc.darker());
}
setOpaque(true);
}
@Override public Dimension getPreferredSize() {
return new Dimension(16, 64);
}
}
class PopupDragListener extends MouseAdapter {
private final Point startPt = new Point();
@Override public void mousePressed(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
Component c = e.getComponent();
Container popup = SwingUtilities.getAncestorOfClass(JPopupMenu.class, c);
SwingUtilities.convertMouseEvent(c, e, popup);
startPt.setLocation(e.getPoint());
}
}
@Override public void mouseDragged(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
Component c = e.getComponent();
Window w = SwingUtilities.getWindowAncestor(c);
// Popup$HeavyWeightWindow
if (w != null && w.getType() == Window.Type.POPUP) {
Point pt = e.getLocationOnScreen();
w.setLocation(pt.x - startPt.x, pt.y - startPt.y);
}
}
}
}
View in GitHub: Java, KotlinDescription
JToolTip
が表示状態になったらそのJToolTip
を親にしてJPopupMenu#.show(tip, 0, 0)
でJPopupMenu
を表示するようJEditorPane#createToolTip()
をオーバーライド- JToolTipの文字列を選択・コピー可能にすると同様の方法
JPopupMenu
にドラッグ可能なJLabel
を配置- JPopupMenuにマウスドラッグで位置変更を可能にするヘッダを追加するの
MouseAdapter
とほぼ同一だが、親がJFrame
などではなくJToolTip
になるのでLightWeightWindow
を使用するJPopupMenu
で位置変更ができない - これを回避するため、
JPopupMenu#setLightWeightPopupEnabled(false)
で常にHeavyWeightWindow
を使用してJPopupMenu
を開くよう設定
- JPopupMenuにマウスドラッグで位置変更を可能にするヘッダを追加するの