Swing/LineFocusTable のバックアップの現在との差分(No.6)
TITLE:JTableのフォーカスを一行全体に適用する
Posted by aterai at 2006-06-05
JTableのフォーカスを一行全体に適用する
JTableのフォーカスをセルではなく、一行全体に掛かっているように表示します。-
category: swing
folder: LineFocusTable
title: JTableのフォーカスを一行全体に適用する
tags: [JTable, Focus, Border]
author: aterai
pubdate: 2006-06-05T12:54:07+09:00
description: JTableのフォーカスをセルではなく、一行全体に掛かっているように表示します。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2011/05/change-border-of-focused-row-in-jtable.html lang: en
概要
JTable
のフォーカスをセルではなく、一行全体に掛かっているように表示します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
enum Type { START, END }
#spanend
#spandel
**サンプルコード [#t2e1e111]
#spanend
#spandel
#code{{
#spanend
#spandel
private class DotBorder extends EmptyBorder {
#spanend
private final BasicStroke dashed = new BasicStroke(1.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10.0f, new float[]{1.0f}, 0.0f);
public boolean isBorderOpaque() {return true;}
public DotBorder(Insets borderInsets) {
super(borderInsets);
}
public DotBorder(int top, int left, int bottom, int right) {
#spanadd
class DotBorder extends EmptyBorder {
#spanend
private static final BasicStroke DASHED = new BasicStroke(
1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
10f, new float[] {1f}, 0f);
private static final Color DOT_COLOR = new Color(200, 150, 150);
public final Set<Type> type = EnumSet.noneOf(Type.class);
#spanadd
#spanend
protected DotBorder(int top, int left, int bottom, int right) {
super(top, left, bottom, right);
}
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
Graphics2D g2 = (Graphics2D)g;
g2.translate(x,y);
if(isFocusedBorder()) {
g2.setPaint(new Color(200,150,150));
g2.setStroke(dashed);
int cbx = c.getBounds().x;
if(cbx==0) {
g2.drawLine(0,0,0,h);
}
if(end) {
g2.drawLine(w-1,0,w-1,h);
}
if(cbx%2==0) {
g2.drawLine(0,0,w,0);
g2.drawLine(0,h-1,w,h-1);
}else{
g2.drawLine(1,0,w,0);
g2.drawLine(1,h-1,w,h-1);
}
#spanadd
#spanend
@Override public boolean isBorderOpaque() {
return true;
}
#spanadd
#spanend
@Override public void paintBorder(
Component c, Graphics g, int x, int y, int w, int h) {
Graphics2D g2 = (Graphics2D) g.create();
g2.translate(x, y);
g2.setPaint(DOT_COLOR);
g2.setStroke(DASHED);
if (type.contains(Type.START)) {
g2.drawLine(0, 0, 0, h);
}
g2.translate(-x,-y);
if (type.contains(Type.END)) {
g2.drawLine(w - 1, 0, w - 1, h);
}
if (c.getBounds().x % 2 == 0) {
g2.drawLine(0, 0, w, 0);
g2.drawLine(0, h - 1, w, h - 1);
} else {
g2.drawLine(1, 0, w, 0);
g2.drawLine(1, h - 1, w, h - 1);
}
g2.dispose();
}
}
View in GitHub: Java, Kotlin解説
通常のJTableでは、JTable#setRowSelectionAllowed(true)とすることで選択状態は一行毎になりますが、フォーカスはセル毎のままです。上記のサンプルでは、レンダラーでフォーカスの有るセルをJTable#getSelectionModel()#getLeadSelectionIndex()で取得し、独自ラベルを使って最初と最後のセルの垂直の点線、途中のセルの水平点線を描画しています。このため、フォーカスが一行全体に掛かっているように見せることができます。解説
- デフォルトの
JTable
ではJTable#setRowSelectionAllowed(true)
を設定すると選択状態は一行ごとになるが、フォーカスはセル単位で描画される - 上記のサンプルではセルレンダラーの描画メソッド内で
JTable#getSelectionModel()#getLeadSelectionIndex()
を使用してフォーカスが存在するセルを取得し、独自ラベルを使って最初と最後のセルの垂直の点線、途中のセルの水平点線を追加することでフォーカスが一行全体に適用されているように見せている- カラム幅を変更するなどの操作を行ってもセル上下の水平点線のつなぎ目でドットが重ならないようにするため、偶数奇数ドット目のどちらで始まっているかを判断して開始位置のオフセットを決定する