FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Mac OS X 10.8.5 (Mountain Lion)
A DESCRIPTION OF THE PROBLEM :
This very same bug was reported as http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7181956 in December 2012. It disappeared from the bug database during the spring 2013...
This test class demonstrates an OutOfMemoryError that occurs on Mac OS X 10.8.5 running Java 1.7.0_40 (using default JVM parms) and the Mac OS X look and feel. The problem happen when having a very large string in single column JTable. It occurs at a certain level when increasing the value of TableColumn.setPreferredWidth(). Just before the OutOfMemoryError happen some garbage graphics is painted in the table header. For me the garbage in the table header is rendered when setting preferred width to a value around 5000 (scroll horizontally and the garbage will appear). The OutOfMemoryError occur at a value of approx 10000 and when clicking in the table. This is the full error:
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: can't create offscreen surface
at sun.java2d.opengl.OGLSurfaceData.initSurfaceNow(OGLSurfaceData.java:298)
at sun.java2d.opengl.OGLSurfaceData.access$000(OGLSurfaceData.java:98)
at sun.java2d.opengl.OGLSurfaceData$1.run(OGLSurfaceData.java:324)
at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run(OGLRenderQueue.java:234)
Running the same test program with Java 1.6.0_51 works fine with a preferred width set to several millions.
Note the problem occur only with the Mac OS X L&F. I've tried Metal and Alloy and these work fine.
REGRESSION. Last worked in version 6u45
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the test case and set the width for the column to 5000 (and press enter). Now scroll horizontally and you will notice garbage graphics in the column header.
Increase the width to 10000 and now scroll horizontally, the OOME exception is thrown
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JTableHeader should renderer the column header just fine and there should be no OOME
ACTUAL -
If running setPreferredWidth() to a high value an OOME is reported.
Also, the JTableHeader is rendering garbage in the header for the failing column
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: can't create offscreen surface
at sun.java2d.opengl.OGLSurfaceData.initSurfaceNow(OGLSurfaceData.java:298)
at sun.java2d.opengl.OGLSurfaceData.access$000(OGLSurfaceData.java:98)
at sun.java2d.opengl.OGLSurfaceData$1.run(OGLSurfaceData.java:324)
at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run(OGLRenderQueue.java:234)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
public class BigStringErrorOnOSX extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
BigStringErrorOnOSX t = new BigStringErrorOnOSX();
t.setSize(1000, 200);
t.setVisible(true);
}
});
}
public BigStringErrorOnOSX() {
final JTable table = new JTable(new DummyModel());
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
final JTextField widthField = new JTextField(10);
widthField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
table.getColumnModel().getColumn(0).setPreferredWidth(Integer.parseInt(widthField.getText()));
}
});
JPanel topPanel = new JPanel(new FlowLayout());
topPanel.add(new JLabel("setPreferredWidth for column 0:"));
topPanel.add(widthField);
add(topPanel, BorderLayout.NORTH);
add(new JScrollPane(table), BorderLayout.CENTER);
}
class DummyModel extends AbstractTableModel {
private String bigString;
DummyModel() {
StringBuilder b = new StringBuilder();
int n = 0;
for (int i = 0; i < 100000; i++) {
b.append(n++);
if (n > 9) {
n = 0;
}
}
bigString = b.toString();
}
@Override
public int getRowCount() {
return 1;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return bigString;
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Do not use the AquaLookAndFeel