I found a solution a few hours after posting this. Instead of this --
Image image = w.createImage(new MemoryImageSource(20, 20, pixels, 0, 20));
-- do this:
BufferedImage image = new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB); image.setRGB(0, 0, 20, 20, pixels, 0, 20);
I don't know why the original code had the problem, however. I'm leaving the remainder of this message alone in case anyone can learn from (or explain) the mistake.
The program compiles without errors or warnings. When it runs, paintComponent() is called repeatedly, about a thousand times per second, even though no events seem to be occurring that would make repainting necessary. If drawImage() is commented out, so that only drawLine() is called, there is no such repetition of paintComponent(); so the problem seems to involve a difference between drawImage() and drawLine(). This program doesn't do anything useful other than exhibit the problem; it's the result of simplifying a larger program. (Note: drawImage() has no visible effect since the pixels are all zeros, but that's not the problem. The problem is that paintComponent() is called too much.)
import java.awt.*; import java.awt.image.*; import java.awt.event.*; import javax.swing.*; public class Test { public Test() {} public static TestWin w; public static void main(String args[]) { Runnable runner = new Runnable() { public void run() { Test Test = new Test(); try { w = new TestWin(); } catch (Exception e) { System.out.println("Ouch: " + e); } } }; EventQueue.invokeLater(runner); } static void testImage(Graphics g) { int pixels[] = new int[400]; if (g != null && pixels != null) { Image image = w.createImage(new MemoryImageSource(20, 20, pixels, 0, 20)); if (image != null) { g.drawLine(10, 10, 20, 20); g.drawImage(image, 20, 20, w); } } } } class TestWin extends JFrame { public TestPanel panel; public TestWin() { panel = new TestPanel(); getContentPane().add(panel); setBounds(100, 100, 300, 300); setVisible(true); toFront(); } public void handleMouseEvent(MouseEvent m) {} public void handleActionEvent(ActionEvent ae, final int command) {} public void handleResizeEvent(ComponentEvent e) {} public void handleWindowEvent(WindowEvent e) {} protected class TestPanel extends JPanel { public TestPanel() {} public int paintComponentCount; public void paintComponent(Graphics g) { System.out.println("paintComponent " + paintComponentCount++); super.paintComponent(g); Test.testImage(g); } } }
Thanks in advance for any help!