В моем приложении Java 8 JTable
используется внутри JScrollPane
. В настоящее время таблица содержит более 10 столбцов, и данные добавляются с использованием DefaultTableModel
's addRow(someObjectArray)
. Все ячейки в столбце в настоящее время имеют один и тот же тип данных, но столбцы 4+ могут содержать ячейки со значением «ноль» (0-3 всегда содержат данные! = Ноль!).
Если данные в первых трех столбцахне совпадают с данными в предыдущей строке, первые три ячейки в текущей строке написаны черным, жирным шрифтом, в противном случае они используют обычный, простой и темно-серый шрифт - это просто способ отметить началоновых данных:
![enter image description here](https://i.stack.imgur.com/hW1Nm.png)
При заполнении таблицы и прокрутке по вертикали шрифт жирный и обычный шрифт устанавливаются правильно, но при прокрутке вправо, а затем обратно к первым трем столбцамжирный шрифт испорчен: иногда он устанавливается для каждой ячейки, иногда для неправильных ячеек, а иногда меняет середину текста:
![enter image description here](https://i.stack.imgur.com/et77L.png)
ПрокруткаВниз и вверх сбрасывает ячейки так, как они должны выглядеть.
Вот как настроена таблица:
JTable myTable = new JTable() {
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
if (column<3) {
if(row==0) { //Always mark column 0-2 in row 0
c.setFont(c.getFont().deriveFont(Font.BOLD));
c.setForeground(Color.BLACK);
} else {
if(column==0) { //Check if column 0-2 should be marked and mark column 0 (or not)
Object prevColumnA = getValueAt(row-1, column); //String
Object currColumnA = getValueAt(row, column); //String
Object prevColumnB = getValueAt(row-1, column+1); //int
Object currColumnB = getValueAt(row, column+1); //int
Object prevColumnC = getValueAt(row-1, column+2); //String
Object currColumnC = getValueAt(row, column+2); //String
if(!prevColumnA.equals(currColumnA) || !prevColumnB.equals(currColumnB) || !prevColumnC.equals(currColumnC)) {
markRow = true;
c.setFont(c.getFont().deriveFont(Font.BOLD));
c.setForeground(Color.BLACK);
} else {
markRow = false;
c.setFont(c.getFont().deriveFont(Font.PLAIN));
c.setForeground(Color.DARK_GRAY);
}
} else { //Mark column 1-2 (or not)
if(markRow) {
c.setFont(c.getFont().deriveFont(Font.BOLD));
c.setForeground(Color.BLACK);
} else {
c.setFont(c.getFont().deriveFont(Font.PLAIN));
c.setForeground(Color.DARK_GRAY);
}
}
}
} else {
c.setFont(c.getFont().deriveFont(Font.PLAIN));
c.setForeground(Color.DARK_GRAY);
}
//System.out.println("row="+row+", column="+column+", markRow="+markRow);
return c;
}
};
Как это исправить?
Редактировать: MRE скопировано с чдо :
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class SomeMRE extends JPanel {
boolean markRow = false;
public SomeMRE() {
JTable myTable = new JTable() {
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
if (column<3) {
if(row==0) { //Always mark column 0-2 in row 0
c.setFont(c.getFont().deriveFont(Font.BOLD));
c.setForeground(Color.BLACK);
} else {
if(column==0) { //Check if column 0-2 should be marked and mark column 0 (or not)
Object prevColumnA = getValueAt(row-1, column); //String
Object currColumnA = getValueAt(row, column); //String
Object prevColumnB = getValueAt(row-1, column+1); //int
Object currColumnB = getValueAt(row, column+1); //int
Object prevColumnC = getValueAt(row-1, column+2); //String
Object currColumnC = getValueAt(row, column+2); //String
if(!prevColumnA.equals(currColumnA) || !prevColumnB.equals(currColumnB) || !prevColumnC.equals(currColumnC)) {
markRow = true;
c.setFont(c.getFont().deriveFont(Font.BOLD));
c.setForeground(Color.BLACK);
} else {
markRow = false;
c.setFont(c.getFont().deriveFont(Font.PLAIN));
c.setForeground(Color.DARK_GRAY);
}
} else { //Mark column 1-2 (or not)
if(markRow) {
c.setFont(c.getFont().deriveFont(Font.BOLD));
c.setForeground(Color.BLACK);
} else {
c.setFont(c.getFont().deriveFont(Font.PLAIN));
c.setForeground(Color.DARK_GRAY);
}
}
}
} else {
c.setFont(c.getFont().deriveFont(Font.PLAIN));
c.setForeground(Color.DARK_GRAY);
}
//System.out.println("row="+row+", column="+column+", markRow="+markRow);
return c;
}
};
myTable.setModel(new DefaultTableModel(
new Object[][] {
{"ColumnA text 1", 123, "ColumnC text 1", 1, null, "bla", "bla", "bla", null},
{"ColumnA text 2", 234, "ColumnC text 2", 2, null, "bla", "bla", null, null},
{"ColumnA text 2", 234, "ColumnC text 2", 3, null, "bla", "bla", "bla", null},
{"ColumnA text 2", 234, "ColumnC text 2", 4, null, "bla", "bla", null, null},
{"ColumnA text 2", 234, "ColumnC text 2", 5, null, "bla", null, null, null},
{"ColumnA text 1", 123, "ColumnC text 1", 6, null, "bla", "bla", "bla", null},
{"ColumnA text 2", 234, "ColumnC text 2", 7, null, "bla", null, null, null},
{"ColumnA text 2", 234, "ColumnC text 2", 8, null, "bla", "bla", null, null},
{"ColumnA text 2", 234, "ColumnC text 2", 9, null, "bla", "bla", null, null}
},
new String[] {
"ColumnA", "ColumnB", "ColumnC", "ColumnD", "ColumnE", "ColumnF", "ColumnG", "ColumnH", "ColumnI"
}
));
setLayout( new BorderLayout() );
add(new JScrollPane(myTable));
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("SomeMRE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SomeMRE());
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args) throws Exception {
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
}
}