jTable paint()导致java.lang.OutOfMemoryError:java堆空间
我正在尝试构建jTable,其中我有一项繁重(不是很繁重)的任务,即绘制jTable的每个单元。但我并不经常画画(很少画/更新每个单元格)。在实现jTable之后,我遇到了jTable paint()导致java.lang.OutOfMemoryError:java堆空间,java,swing,jtable,heap-memory,Java,Swing,Jtable,Heap Memory,我正在尝试构建jTable,其中我有一项繁重(不是很繁重)的任务,即绘制jTable的每个单元。但我并不经常画画(很少画/更新每个单元格)。在实现jTable之后,我遇到了java.lang.OutOfMemoryError:java堆空间。我发现这是由于每微秒调用paint(Graphics g,JComponent c)造成的。我不希望只在更新/修改表的情况下一直调用此方法。有没有办法解决这个问题 编辑: 我没有手动调用paint。该表有一个手动创建的UI,该UI是使用setUI方法设置的。
java.lang.OutOfMemoryError:java堆空间
。我发现这是由于每微秒调用paint(Graphics g,JComponent c)
造成的。我不希望只在更新/修改表的情况下一直调用此方法。有没有办法解决这个问题
编辑:
我没有手动调用paint。该表有一个手动创建的UI,该UI是使用setUI
方法设置的。我使用此UI创建了可以跨多行或多列的单元格(即,将少数单元格合并在一起)
setUI(新的MultiSpanCellTableUI())代码>
类multiPancellTableUI
实现了一个paint()
方法,该方法每秒都会被调用
public void paint(Graphics g, JComponent c) {
Rectangle oldClipBounds = g.getClipBounds();
Rectangle clipBounds = new Rectangle(oldClipBounds);
int tableWidth = table.getColumnModel().getTotalColumnWidth();
clipBounds.width = Math.min(clipBounds.width, tableWidth);
g.setClip(clipBounds);
int firstIndex = table.rowAtPoint(new Point(0, clipBounds.y));
int lastIndex = table.getRowCount() - 1;
Rectangle rowRect = new Rectangle(0, 0, tableWidth,
table.getRowHeight() + table.getRowMargin());
rowRect.y = firstIndex * rowRect.height;
for (int index = firstIndex; index <= lastIndex; index++) {
if (rowRect.intersects(clipBounds)) {
paintRow(g, index);
}
rowRect.y += rowRect.height;
}
g.setClip(oldClipBounds);
}
private void paintRow(Graphics g, int row) {
System.out.println("paintRow called");
Rectangle rect = g.getClipBounds();
boolean drawn = false;
AttributiveCellTableModel tableModel = (AttributiveCellTableModel) table
.getModel();
CellSpan cellAtt = (CellSpan) tableModel.getCellAttribute();
int numColumns = table.getColumnCount();
for (int column = 0; column < numColumns; column++) {
Rectangle cellRect = table.getCellRect(row, column, true);
int cellRow, cellColumn;
if (cellAtt.isVisible(row, column)) {
cellRow = row;
cellColumn = column;
} else {
cellRow = row + cellAtt.getSpan(row, column)[CellSpan.ROW];
cellColumn = column
+ cellAtt.getSpan(row, column)[CellSpan.COLUMN];
}
if (cellRect.intersects(rect)) {
drawn = true;
System.out.println("paintCell called!");
paintCell(g, cellRect, cellRow, cellColumn);
} else {
if (drawn)
break;
}
}
}
private void paintCell(Graphics g, Rectangle cellRect, int row, int column) {
int spacingHeight = table.getRowMargin();
int spacingWidth = table.getColumnModel().getColumnMargin();
Color c = g.getColor();
g.setColor(table.getGridColor());
g.drawRect(cellRect.x, cellRect.y, cellRect.width - 1,
cellRect.height - 1);
g.setColor(c);
cellRect.setBounds(cellRect.x + spacingWidth / 2, cellRect.y
+ spacingHeight / 2, cellRect.width - spacingWidth,
cellRect.height - spacingHeight);
if (table.isEditing() && table.getEditingRow() == row
&& table.getEditingColumn() == column) {
Component component = table.getEditorComponent();
component.setBounds(cellRect);
component.validate();
} else {
TableCellRenderer renderer = table.getCellRenderer(row, column);
Component component = table.prepareRenderer(renderer, row, column);
if (component.getParent() == null) {
rendererPane.add(component);
}
rendererPane.paintComponent(g, component, table, cellRect.x,
cellRect.y, cellRect.width, cellRect.height, true);
}
}
public void绘制(图形g、JC组件c){
矩形oldClipBounds=g.getClipBounds();
矩形剪贴簿=新矩形(旧剪贴簿);
int tableWidth=table.getColumnModel().getTotalColumnWidth();
clipBounds.width=Math.min(clipBounds.width,tableWidth);
g、 setClip(剪贴簿);
int firstIndex=table.rowAtPoint(新点(0,clipBounds.y));
int lastIndex=table.getRowCount()-1;
矩形rowRect=新矩形(0,0,tableWidth,
table.getRowHeight()+table.getRowMargin());
rowRect.y=firstIndex*rowRect.height;
对于(int index=firstIndex;index不确定为什么需要
1) 通过paintComponent()
,请针对JTable的Cel
l中的哪种类型的组件进行绘制,如果存在某些JComponent,您必须覆盖paintComponent()
,而不是paintComponent()
2) 设计不好,无法在较大的JTable
3) 您必须查看渲染器
,如果使用某种颜色进行绘制,最好是prepareRenderer
4) JTable
默认情况下返回JLabel
,您可以在那里设置图标
instaead以进行一些自定义绘制
5) 也许可以帮助您提高JTable的性能
如果上面没有发布代码,我假设您正在JTable
组件上强制执行paint()
。
不需要对JTable
对象调用paint()
。要自定义单元格绘制,请改用TableCellRenderer
public class MyCellRenderer extends JLabel implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) {
if (isSelected) {
// Is cell selected?
}
if (hasFocus) {
// Does this cell have the focus
}
// Configure the component with the specified value, here we are using JLabel
setText(value.toString());
// Set tool tip if desired
setToolTipText((String)value);
// Since the renderer is a component, return itself
return this;
}
}
请包括一个。此外,如果您正在这样做,您永远不应该显式调用paint
。@我已经相应地更新了问题。如果我尝试了一个示例,那么我会遇到很多其他异常,永远不会出现