Swing/LineFocusTable のバックアップの現在との差分(No.10)
-
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
サンプルコード
サンプルコード
#spanadd
enum Type { START, END }
#spanend
#spanadd
#spanend
class DotBorder extends EmptyBorder {
public enum Type { START, END; }
private static final BasicStroke dashed = new BasicStroke(
1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
10.0f, (new float[] {1.0f}), 0.0f);
private static final Color dotColor = new Color(200,150,150);
public DotBorder(int top, int left, int bottom, int right) {
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 EnumSet<Type> type = EnumSet.noneOf(Type.class);
#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;
g2.translate(x,y);
g2.setPaint(dotColor);
g2.setStroke(dashed);
if(type.contains(Type.START)) {
g2.drawLine(0,0,0,h);
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 (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);
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.translate(-x,-y);
g2.dispose();
}
}
View in GitHub: Java, Kotlin解説
通常のJTable
では、JTable#setRowSelectionAllowed(true)
とすることで選択状態は一行毎になりますが、フォーカスはセル毎のままです。上記のサンプルでは、レンダラーでフォーカスの有るセルをJTable#getSelectionModel()#getLeadSelectionIndex()
で取得し、独自ラベルを使って最初と最後のセルの垂直の点線、途中のセルの水平点線を描画しています。このため、フォーカスが一行全体に掛かっているように見せることができます。
解説
- デフォルトの
JTable
ではJTable#setRowSelectionAllowed(true)
を設定すると選択状態は一行ごとになるが、フォーカスはセル単位で描画される - 上記のサンプルではセルレンダラーの描画メソッド内で
JTable#getSelectionModel()#getLeadSelectionIndex()
を使用してフォーカスが存在するセルを取得し、独自ラベルを使って最初と最後のセルの垂直の点線、途中のセルの水平点線を追加することでフォーカスが一行全体に適用されているように見せている- カラム幅を変更するなどの操作を行ってもセル上下の水平点線のつなぎ目でドットが重ならないようにするため、偶数奇数ドット目のどちらで始まっているかを判断して開始位置のオフセットを決定する