Swing/ListCellHyperlinkListener のバックアップ(No.7)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/ListCellHyperlinkListener へ行く。
- category: swing folder: ListCellHyperlinkListener title: JListのセルレンダラーとして設定したJEditorPaneからHyperlinkEventを取得する tags: [JList, JEditorPane, ListCellRenderer, HyperlinkListener, MouseListener, Html] author: aterai pubdate: 2016-11-28T02:00:47+09:00 description: JListのセルレンダラーとして使用しているJEditorPaneに複数リンクを表示し、マウスクリックイベントを転送してHyperlinkEventが発生するように設定します。 image: https://drive.google.com/uc?id=1ZRAf_BbeW7l2RWn7LDGbJAZwkwtXgKZuuA
概要
JList
のセルレンダラーとして使用しているJEditorPane
に複数リンクを表示し、マウスクリックイベントを転送してHyperlinkEvent
が発生するように設定します。
Screenshot
Advertisement
サンプルコード
DefaultListModel<SiteItem> m = new DefaultListModel<>();
m.addElement(new SiteItem("aterai",
Arrays.asList("https://ateraimemo.com", "https://github.com/aterai")));
m.addElement(new SiteItem("example",
Arrays.asList("http://www.example.com", "https://www.example.com")));
JList<SiteItem> list = new JList<>(m);
list.setFixedCellHeight(120);
list.setCellRenderer(new SiteListItemRenderer());
list.addMouseListener(new MouseAdapter() {
@Override public void mouseClicked(MouseEvent e) {
Point pt = e.getPoint();
int index = list.locationToIndex(pt);
if (index >= 0) {
SiteItem item = list.getModel().getElementAt(index);
Component c = list.getCellRenderer().getListCellRendererComponent(
list, item, index, false, false);
if (c instanceof JEditorPane) {
Rectangle r = list.getCellBounds(index, index);
c.setBounds(r);
MouseEvent me = SwingUtilities.convertMouseEvent(list, e, c);
me.translatePoint(pt.x - r.x - me.getX(), pt.y - r.y - me.getY());
c.dispatchEvent(me);
// pt.translate(-r.x, -r.y);
// c.dispatchEvent(new MouseEvent(
// c, e.getID(), e.getWhen(), e.getModifiers() | e.getModifiersEx(),
// pt.x, pt.y, e.getClickCount(), e.isPopupTrigger()));
}
}
}
});
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JList
に設定したMouseListener
のクリックイベントをそのListCellRenderer
として使用しているJEditorPane
にdispatchEvent
で転送し、HyperlinkListener
でリンククリックイベントが取得できるように設定しています。
MouseEvent
は、そのクリック位置をJList
からJEditorPane
相対に変更する必要があるSwingUtilities.convertMouseEvent(list, e, editor)
ではうまく変換できないので、自前で位置を変換し、new MouseEvent(...)
でイベントを作り直しているSwingUtilities.convertMouseEvent(list, e, editor)
でマウスイベントのソースをセルエディタに変換し、座標はMouseEvent#translatePoint(...)
メソッドを使用してセルエディタ相対に変換
参考リンク
- JListのセル中に配置したコンポーネント毎にカーソルを変更する
JList
からセルレンダラーへの座標変換は、こちらと同じものを使用