Swing/LineFocusTable のバックアップの現在との差分(No.1)
TITLE:JTableのフォーカスを一行全体に適用する
JTableのフォーカスを一行全体に適用する
編集者:Terai Atsuhiro~
作成日:2006-06-05
更新日:2021-04-22 (木) 21:55:53
- 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
のフォーカスをセルではなく、一行全体に掛かっているように表示します。
Screenshot
Advertisement
概要
JTableのフォーカスをセルではなく、一行全体に掛かっているように表示します。サンプルコード
#spanend
#spanadd
enum Type { START, END }
#spanend
#spandel
#screenshot
#spanend
#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);
#spandel
**サンプルコード [#t2e1e111]
#spanend
private class DotBorder extends EmptyBorder {
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) {
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);
}
}
g2.translate(-x,-y);
}
}
protected DotBorder(int top, int left, int bottom, int right) {
super(top, left, bottom, right);
}
-&jnlp;
-&jar;
-&zip;
@Override public boolean isBorderOpaque() {
return true;
}
#spandel
**解説 [#lbc490ab]
#spanend
#spandel
レンダラーでフォーカスの有るセルをJTable#getSelectionModel()#getLeadSelectionIndex()で取得し、独自ラベルで最初と最後のセルの垂直の点線、途中のセルの水平点線を描画しています。水平の点線はセルが偶数奇数ドット目のどちらで始まっているかで開始位置をずらしています。
#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);
}
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();
}
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlinコメント
解説
- デフォルトの
JTable
ではJTable#setRowSelectionAllowed(true)
を設定すると選択状態は一行ごとになるが、フォーカスはセル単位で描画される - 上記のサンプルではセルレンダラーの描画メソッド内で
JTable#getSelectionModel()#getLeadSelectionIndex()
を使用してフォーカスが存在するセルを取得し、独自ラベルを使って最初と最後のセルの垂直の点線、途中のセルの水平点線を追加することでフォーカスが一行全体に適用されているように見せている- カラム幅を変更するなどの操作を行ってもセル上下の水平点線のつなぎ目でドットが重ならないようにするため、偶数奇数ドット目のどちらで始まっているかを判断して開始位置のオフセットを決定する