Swing/ScrollBarSearchHighlighter のバックアップ差分(No.4)
- バックアップ一覧
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/ScrollBarSearchHighlighter へ行く。
- 1 (2013-01-28 (月) 02:11:33)
- 2 (2013-01-28 (月) 10:59:53)
- 3 (2013-02-01 (金) 20:39:21)
- 4 (2013-08-01 (木) 17:20:11)
- 5 (2013-08-18 (日) 23:10:11)
- 6 (2013-08-19 (月) 11:24:23)
- 7 (2013-08-19 (月) 14:43:11)
- 8 (2013-08-19 (月) 17:13:49)
- 9 (2013-08-20 (火) 19:57:12)
- 10 (2013-08-23 (金) 16:09:26)
- 11 (2014-02-14 (金) 00:47:04)
- 12 (2014-09-28 (日) 01:18:33)
- 13 (2014-11-01 (土) 00:46:09)
- 14 (2014-11-23 (日) 16:55:43)
- 15 (2014-12-31 (水) 01:44:57)
- 16 (2015-07-07 (火) 16:25:06)
- 17 (2016-05-25 (水) 13:17:41)
- 18 (2017-03-28 (火) 15:07:42)
- 19 (2017-11-02 (木) 15:34:40)
- 20 (2018-01-30 (火) 19:39:19)
- 21 (2018-02-24 (土) 19:51:30)
- 22 (2019-05-22 (水) 19:35:38)
- 23 (2020-01-28 (火) 16:32:40)
- 24 (2021-07-24 (土) 23:33:52)
- 25 (2022-08-20 (土) 22:15:25)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JScrollBarに検索結果をハイライト表示
#navi(../)
#tags(JScrollBar, JScrollPane, JTextArea, JTextComponent, JViewport, MatteBorder, Icon)
RIGHT:Posted by &author(aterai); at 2013-01-28
*JScrollBarに検索結果をハイライト表示 [#i481e1eb]
``JScrollBar``などに``JTextArea``の文字列検索の結果をハイライト表示します。
-&jnlp;
-&jar;
-&zip;
//#screenshot
#ref(https://lh4.googleusercontent.com/-69jv_2q3f8g/UQT6FH3HXbI/AAAAAAAABcY/FmYcY3aLr6w/s800/ScrollBarSearchHighlighter.png)
**サンプルコード [#g03baf61]
#code(link){{
scrollbar.setUI(new WindowsScrollBarUI() {
@Override protected void paintTrack(
Graphics g, JComponent c, Rectangle trackBounds) {
super.paintTrack(g, c, trackBounds);
Rectangle rect = textArea.getBounds();
double sy = trackBounds.getHeight() / rect.getHeight();
AffineTransform at = AffineTransform.getScaleInstance(1.0, sy);
g.setColor(Color.YELLOW);
try{
for(Integer pos: poslist) {
Rectangle r = textArea.modelToView(pos);
Rectangle s = at.createTransformedShape(r).getBounds();
int h = 2; //Math.max(2, s.height-2);
g.fillRect(trackBounds.x, trackBounds.y+s.y, trackBounds.width, h);
}
}catch(BadLocationException e) {
e.printStackTrace();
}
}
});
}}
**解説 [#y104c6ca]
上記のサンプルでは、``ScrollBarUI#paintTrack(...)``メソッドをオーバーライドして、``JTextArea``内の文字列の検索結果を縦の``JScrollBar``内部に描画しています。
- 注:
-- 一行分のハイライトの高さは``2px``で固定
-- 検索結果の位置取得には``JTextComponent#modelToView(text.indexOf(pattern, pos));``を使用しているため、ハイライト対象の文字列が折り返しで二行になっても、ハイライトされるのは一行目のみ
----
以下のように、``Icon``を使った``MatteBorder``を設定したコンポーネントを作成し、これを``JViewport``に追加して``JScrollPane#setRowHeader(...)``で設定する方法もあります。こちらは、縦``JScrollBar``に直接ハイライトを描画しないので、上下の増減ボタンは考慮せず、またノブの代わりに現在表示位置を示す領域を半透明で描画しています。
#code{{
final JScrollPane scroll = new JScrollPane(textArea);
JLabel label = new JLabel();
label.setBorder(BorderFactory.createMatteBorder(0, 4, 0, 0, new Icon() {
private final Color THUMB_COLOR = new Color(0,0,255,50);
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
if(poslist.isEmpty()) return;
Rectangle rect = textArea.getBounds();
Dimension sbSize = scrollbar.getSize();
Insets sbInsets = scrollbar.getInsets();
double sy=(sbSize.height-sbInsets.top-sbInsets.bottom)/rect.getHeight();
AffineTransform at = AffineTransform.getScaleInstance(1.0, sy);
g.setColor(Color.RED);
try{
for(Integer pos: poslist) {
Rectangle r = textArea.modelToView(pos);
Rectangle s = at.createTransformedShape(r).getBounds();
int h = 2; //Math.max(2, s.height-2);
g.fillRect(x, y+sbInsets.top+s.y, getIconWidth(), h);
}
//paint Thumb rectangle
JViewport vport = scroll.getViewport();
Rectangle vrect = c.getBounds();
vrect.y = vport.getViewPosition().y;
g.setColor(THUMB_COLOR);
Rectangle rr = at.createTransformedShape(vrect).getBounds();
g.fillRect(x, y+sbInsets.top+rr.y, getIconWidth(), rr.height);
}catch(BadLocationException e) {
e.printStackTrace();
}
}
@Override public int getIconWidth() {
return 4;
}
@Override public int getIconHeight() {
return scrollbar.getHeight();
}
}));
scroll.setVerticalScrollBar(scrollbar);
JViewport vp = new JViewport();
vp.setView(label);
scroll.setRowHeader(vp);
add(scroll);
}}
//**参考リンク
**コメント [#jab8403b]
#comment