Sometimes it correctly displays my BufferedImage drawing, but if you run the program a few times, it ceases to display anything.
I've vastly simplified the compilable code below to simply draw a single rectangle into a BufferedImage contained by a JPanel. Usually, but not always, a rectangle will appear as planned, but if you run the program a few times things begin to go awry; a rectangle will appear for only a millisecond then disappear, or not appear at all in the first place. Please help me find the problem there.
Also, I can't get my listeners to do anything at all. In the Action menu, "Re-run Program" is supposed to discard the first rectangle and draw another one. The "Paint On This Image" selection should keep the first rectangle while drawing another randomly placed rectangle on, or near, the first one.
Here's the stripped down, compilable, runnable code:
import java.util.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; public class ArtMaker extends JFrame { private static final int WIDTH = 600; private static final int HEIGHT = 600; private JMenuBar mBar; private JMenu menu1; private JMenuItem menuItem1; private JMenuItem menuItem2; private PixelPainter panel; private ArtMaker artMaker; public ArtMaker() { setTitle("ArtMaker (First Experiments)"); setSize(WIDTH, HEIGHT); setResizable(true); setDefaultCloseOperation(EXIT_ON_CLOSE); createContents(); panel = new PixelPainter(); add(panel); validate(); setVisible(true); } //*************************************************************** private void createContents() { mBar = new JMenuBar(); menu1 = new JMenu("Actions"); menuItem1 = new JMenuItem("Re-run Program"); menuItem2 = new JMenuItem("Paint On This Image"); //these two listeners don't hear so well // when items are chosen in the "Actions" menu menuItem1.addActionListener(new RunListener()); menuItem2.addActionListener(new RunListener()); menu1.add(menuItem1); menu1.add(menuItem2); mBar.add(menu1); setJMenuBar(mBar); } //*************************************************************** // these two listeners don't work when items are chosen in the // "Actions" menu private class RunListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (e.getSource() == menuItem1) { panel.repaint(); } else if (e.getSource() == menuItem2) { panel.paintAgain(); } } } //*************************************************************** public static void main(String[] args) { System.setProperty("apple.laf.useScreenMenuBar", "true"); new ArtMaker(); } } // end class ArtMaker
Then here's the class with the paintComponent():
import java.util.*; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; public class PixelPainter extends JPanel { private static final int WIDTH = 600; private static final int HEIGHT = 600; private static int[] colors = {0, 0, 64, 0, 128, 0, 0, 0}; private static Color black = new Color(0, 0, 0); private static Color midGray = new Color(128, 128, 128); private static Color white = new Color(255, 255, 255); private static Color ltGray = new Color(192, 192, 192); private static Color dkGray = new Color(64, 64, 64); private static Color grayWhite = new Color(223, 223, 223); private static Color[] color = {ltGray, dkGray, black, midGray, black, dkGray}; private static BufferedImage art; //*************************************************************** public PixelPainter() { repaint(); } //*************************************************************** public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; if (art == null) { int x = 290; int y = 290; int w = this.getWidth(); int h = this.getHeight(); art = (BufferedImage)(this.createImage(w,h)); Graphics2D cg = art.createGraphics(); g2.setColor(colorChooser()); g2.drawRect(x, y, ((int)(Math.random() * 300)), ((int)(Math.random() * 300))); cg.drawImage(art, null, 0, 0); } } //*************************************************************** // This method is my rookie attempt to draw a new rectangle on top of the // the first one whenever the "Paint On This Image" is chosen from the // Action menu. But my listeners aren't working, and this method probably // isn't my best bet, either. public void paintAgain() { Graphics2D g2d = art.createGraphics(); if (art != null) { int x = 250; int y = 250; g2d.setColor(colorChooser()); g2d.drawRect(x, y, ((int)(Math.random() * 300)), ((int)(Math.random() * 300))); g2d.drawImage(art, null, 0, 0); } } //*************************************************************** public static Color colorChooser() { int randomPicker = ((int)(Math.random() * 6)); Color colorChoice = color[randomPicker]; return colorChoice; } // end colorChooser } // end class PixelPainter
Any suggestions would be greatly appreciated!