jTableの各セルをペイントする重い(あまり重くない)タスクを持つjTableを構築しようとしています。しかし、私は非常に頻繁に絵を描いているわけではありません。 jTableを実装した後、私はjava.lang.OutOfMemoryError: Java heap space
に遭遇しました。私はそれがpaint(Graphics g, JComponent c)
に1マイクロ秒の呼び出しのためにあることを理解しました。テーブルが更新/変更された場合にのみ、常にこのメソッドを呼びたくはありません。この問題を解決する方法はありますか?jTable paint()はjava.lang.OutOfMemoryErrorにつながります。Javaヒープスペース
編集:私は手動で塗料を呼び出していない
。このテーブルには、setUI
メソッドを使用して手動で作成されたUIが設定されています。このUIを使用して、複数の行または列にまたがる(つまり、少数のセルを結合する)セルを作成しました。
setUI(new MultiSpanCellTableUI());
クラスMultiSpanCellTableUI
は毎秒呼ばなっているpaint()
メソッドを実装します。 OutOfMemoryError
が行われている間、それが後に、毎秒呼び出されるので
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);
}
}
。私は、細胞内の何かを更新するときに細胞を再描画する必要があり、簡単に得ることができる情報です。しかし、その情報に基づいてどのようにしてpaint()
に電話を制限できますか?あなたが持っているpaintComponent()
を上書きする代わりにpaint()
2してくださいいくつかのJComponentがあれば、JTable's Cel
リットル内のコンポーネントのタイプのためにあなたは、paint()
によって
1)塗装を必要としない理由
[sscce](http://www.sscce.org)を含めてください。また、 'paint'を明示的に呼び出すべきではありません。 – mre
@Крысaそれに応じて質問を更新しました。 –
例:http://www.java2s.com/Code/Java/Swing-Components/MultiSpanCellTableExample.htmを試してみましたが、大したことはもうありません。 – mKorbel