我的应用程序中有一个JTable,它有100多行,一个接一个地动态添加。
它存储有关订购了某些东西的客户的数据,并且白天订单越多,所有订单就越多。 当我们有100多个订单的忙碌的一天时,JTable在滚动时变得非常慢。
我使用自定义渲染器来更改几个单元格的背景颜色。我尝试使用TableModelEvent只改变可见行的颜色。
这样做会使速度提高一点但仍不足以平滑滚动。 有什么选择我必须尝试优化我的JTable,它有/将拥有大量数据?
编辑:如果需要,我可以提供我的Jtable和CustomCellRenderer。
private static class CustomRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = -5699527287605065L;
public CustomRenderer() {
setHorizontalAlignment(SwingConstants.CENTER);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row,
column);
vis.set(row, column);
if (vis.isVisible(table)) {
Object o = table.getValueAt(row, column);
if (column != 1 && column != 5 && column != 10 && !isSelected) {
cellComponent.setBackground(Color.WHITE);
if ((row % 2) == 0) cellComponent.setBackground(Colors.gray);
}
if (o != null) {
if (o.toString().contains("Liqui") && !isSelected) {
cellComponent.setBackground(Colors.green);
cellComponent.setForeground(Color.BLACK);
} else if (o.toString().contains("Green Alert") && !isSelected) {
cellComponent.setBackground(Colors.yellow);
cellComponent.setForeground(Color.BLACK);
} else if (o.toString().contains("Red Alert") && !isSelected) {
cellComponent.setBackground(Colors.red);
cellComponent.setForeground(Color.WHITE);
} else if (column == 10 && o.toString().contains("Finalizado")
&& !isSelected) {
cellComponent.setBackground(Colors.green);
cellComponent.setForeground(Color.BLACK);
} else if (column == 10 && o.toString().contains("Cancelado")
&& !isSelected) {
cellComponent.setBackground(Colors.red);
cellComponent.setForeground(Color.WHITE);
} else if (column == 10
&& o.toString().contains("Comprovante em analise")
&& !isSelected) {
cellComponent.setBackground(Colors.yellow);
cellComponent.setForeground(Color.BLACK);
} else if (column == 10 && o.toString().contains("Aguardando retirada")
&& !isSelected) {
cellComponent.setBackground(Colors.ltOrange);
cellComponent.setForeground(Color.BLACK);
} else if (column == 10 && o.toString().contains("Entrega agendada")
&& !isSelected) {
cellComponent.setBackground(Colors.orange);
cellComponent.setForeground(Color.BLACK);
} else if (column == 1
&& o.toString().toLowerCase().contains("test1")
&& !isSelected) {
cellComponent.setBackground(Colors.test1);
cellComponent.setForeground(Color.BLACK);
} else if (column == 1 && o.toString().contains("test2")
&& !isSelected) {
cellComponent.setBackground(Colors.test2);
cellComponent.setForeground(Color.WHITE);
} else if (column == 1 && o.toString().contains("test3")
&& !isSelected) {
cellComponent.setBackground(Colors.test3);
cellComponent.setForeground(Color.WHITE);
} else if (!isSelected && (row % 2) == 0) {
cellComponent.setBackground(Colors.gray);
cellComponent.setForeground(Color.BLACK);
} else if (!isSelected) {
cellComponent.setBackground(Color.WHITE);
cellComponent.setForeground(Color.BLACK);
}
if (Lists.op_list != null) {
for (int i = 0; i < Lists.op_list.size(); i++) {
if (column == 8 && !isSelected) {
if (table.getValueAt(row, 8) != null && table.getValueAt(row, 7) != null) {
if (Lists.op_list.get(i).getFornIDSent() == 1
&& (int) table.getValueAt(row, 7) == Lists.op_list.get(i)
.getOperationID()) {
cellComponent.setBackground(Colors.green);
} else if (Lists.op_list.get(i).getFornIDSent() == 2
&& (int) table.getValueAt(row, 7) == Lists.op_list.get(i)
.getOperationID()) {
cellComponent.setBackground(Colors.yellow);
} else if ((int) table.getValueAt(row, 7) == Lists.op_list.get(i)
.getOperationID()) {
cellComponent.setBackground(Color.WHITE);
if ((row % 2) == 0) cellComponent.setBackground(Colors.gray);
}
}
}
if (table.getValueAt(row, 10).toString().contains("Comprovante em analise") && column == 10
&& !isSelected) {
if (Lists.op_list.get(i).getSituation() == 1
&& (int) table.getValueAt(row, 7) == Lists.op_list.get(i).getOperationID()) {
cellComponent.setBackground(Colors.green);
cellComponent.setForeground(Color.BLACK);
} else if (Lists.op_list.get(i).getComprovanteAllowed() == 1
&& (int) table.getValueAt(row, 7) == Lists.op_list.get(i).getOperationID()) {
cellComponent.setBackground(Colors.green_dark);
cellComponent.setForeground(Color.BLACK);
} else if (Lists.op_list.get(i).getComprovanteAllowed() == 2
&& (int) table.getValueAt(row, 7) == Lists.op_list.get(i).getOperationID()) {
cellComponent.setBackground(Colors.yellow_dark);
cellComponent.setForeground(Color.WHITE);
}
}
if (column == 9 && !isSelected) {
if (Lists.op_list.get(i).getPreBolSent() == 1
&& (int) table.getValueAt(row, 7) == Lists.op_list.get(i).getOperationID()) {
cellComponent.setBackground(Colors.green);
} else if (Lists.op_list.get(i).getPreBolSent() == 2
&& (int) table.getValueAt(row, 7) == Lists.op_list.get(i).getOperationID()) {
cellComponent.setBackground(Colors.yellow);
} else if (Lists.op_list.get(i).getPreBolSent() == 0
&& (int) table.getValueAt(row, 7) == Lists.op_list.get(i).getOperationID()) {
cellComponent.setBackground(Color.WHITE);
if ((row % 2) == 0) cellComponent.setBackground(Colors.gray);
}
}
}
}
}
} else {
cellComponent.setBackground(Color.WHITE);
cellComponent.setForeground(Color.BLACK);
}
vis.reset();
return cellComponent;
}
}
答案 0 :(得分:2)
这是一个MCVE,它在屏幕上放置了一百万行(249,698条记录)的表格。使用渲染器。
它看起来很快,并且在滚动时没有显示延迟或延迟。
所以这支持了这个 必须 成为我们尚未测试的代码中的问题的想法。
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.*;
import java.util.ArrayList;
public class UnicodeTable {
private JComponent ui = null;
UnicodeTable() {
initUI();
}
public final void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
ArrayList<Integer> definedCharacters = new ArrayList<Integer>();
for (int codePoint = 0; codePoint < Character.MAX_CODE_POINT; codePoint++) {
if (Character.isDefined(codePoint)) {
definedCharacters.add(codePoint);
}
}
System.out.println("Number of codepoints: " + definedCharacters.size());
TableModel tm = new UnicodeTableModel(definedCharacters);
JTable table = new JTable(tm);
table.setAutoCreateRowSorter(true);
ui.add(new JScrollPane(table));
table.setDefaultRenderer(String.class, new UnicodeTableCellRenderer());
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
UnicodeTable o = new UnicodeTable();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
class UnicodeTableModel extends AbstractTableModel {
ArrayList<Integer> codePoints;
String[] colNames = {
"Number", "Name", "Alphabetic", "Digit", "ISO Control"
};
Class[] colClass = {
Integer.class, String.class,
Boolean.class, Boolean.class, Boolean.class
};
public UnicodeTableModel(ArrayList<Integer> codePoints) {
this.codePoints = codePoints;
}
@Override
public int getRowCount() {
return codePoints.size();
}
@Override
public int getColumnCount() {
return colNames.length;
}
@Override
public String getColumnName(int columnIndex) {
return colNames[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return colClass[columnIndex];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Integer codePoint = codePoints.get(rowIndex);
switch (columnIndex) {
case 0:
return codePoint;
case 1:
return Character.getName(codePoint);
case 2:
return Character.isAlphabetic(codePoint);
case 3:
return Character.isDigit(codePoint);
case 4:
return Character.isISOControl(codePoint);
default:
return new Object();
}
}
}
class UnicodeTableCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
if (column == 1) {
JLabel l = (JLabel) c;
Font f = l.getFont();
f = new Font(Font.MONOSPACED, Font.ITALIC, f.getSize());
l.setFont(f);
}
return c;
}
}