1

My code is supposed to draw a random sized image three times in random locations. For some reason, when I run this code using BlueJ, all that shows up is a gray screen. I think it is because PaintComponent isn't being called, but I am not quite sure. What went wrong with my code and how can I fix it?

class PanelHolder extends JPanel{//class PanelHolder extends JPanel
//variables
public boolean threesharks;
public int xcoord;
public int ycoord;
public int ratio;
public Image i;
public int w;
public int h;
public boolean background=true;
Color water = new Color(136, 180, 231);
public PanelHolder(){//constructor
 i = Toolkit.getDefaultToolkit().getImage("$harkz.png");
}
public void randomxy(){
 for(int x=0;x<3;x++){
 threesharks=true;
 ycoord=(int)(Math.random()*300+200);//use math.random to figure out coordinates and sizing
 xcoord=(int)(Math.random()*1000+0);//make a loop
 ratio=(int)(Math.random()*5+1);
 w=ratio*523;
 h=ratio*195;
 repaint();
 System.out.println("I'm in randomxy");
 //call repaint() each time
 //after three times, make threesharks=false
 }
 threesharks=false;
}
public void paintComponent(Graphics g){
 if(threesharks){
 setBackground(water);
 System.out.print("hi!");
 if(background){
 super.paintComponent(g);//set backgroun
 background=false;
 }
 g.drawImage(i, xcoord, ycoord, w, h, this);
 }
 }

}

asked Sep 17, 2015 at 1:41
16
  • You should always call super.paintComponent, you're risking some nasty paint artifactes if your don't Commented Sep 17, 2015 at 1:42
  • 1) For better help sooner, post a minimal reproducible example or Short, Self Contained, Correct Example. 2) One way to get image(s) for an example is to hot link to images seen in this Q&A. 3) See Detection/fix for the hanging close bracket of a code block for a problem I could no longer be bothered fixing. Commented Sep 17, 2015 at 1:43
  • When do you call randomxy? Commented Sep 17, 2015 at 1:43
  • You don't seem to understand how painting works in Swing, I suggest you take a look at Painting in AWT and Swing and Performing Custom Painting for starters. Painting is destructive, each time paintComponent is called, you are expected to repaint the entire state of your component, from scratch Commented Sep 17, 2015 at 1:45
  • @MadProgrammer I tried changing the repaint(); to super.paintComponent(), but the compiler gives me an error and says "required:java.awt.Graphics; found: no arguments; reason: actual and formal argument lists differ in length. Commented Sep 17, 2015 at 1:48

1 Answer 1

1

You seem to have a misunderstanding with how painting works in Swing. Swing will call your paintComponent when ever it thinks your component needs to be repainted, this might occur for many different reasons, many of which you don't have control over.

Painting in Swing is destructive, that is, each time your paintComponent method is called, you are expected to repaint the entire state of the component from scratch, painting is not accumalitive.

This means that you need to store the state of things you want to paint in some meaningful manner and re-use these values are needed.

Have a look at Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing

Random Ponies

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
 public static void main(String[] args) {
 new Test();
 }
 public Test() {
 EventQueue.invokeLater(new Runnable() {
 @Override
 public void run() {
 try {
 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
 } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
 ex.printStackTrace();
 }
 JFrame frame = new JFrame("Testing");
 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 frame.add(new PanelHolder());
 frame.pack();
 frame.setLocationRelativeTo(null);
 frame.setVisible(true);
 }
 });
 }
 class PanelHolder extends JPanel {//class PanelHolder extends JPanel
//variables
 public boolean threesharks;
 public BufferedImage i;
 public boolean background = true;
 Color water = new Color(136, 180, 231);
 private Point[] points;
 private Image[] images;
 public PanelHolder() {
 //constructor
 try {
 i = ImageIO.read(...);
 } catch (IOException ex) {
 ex.printStackTrace();
 }
 randomxy();
 }
 @Override
 public Dimension getPreferredSize() {
 return new Dimension(800, 800);
 }
 public void randomxy() {
 points = new Point[3];
 images = new Image[3];
 for (int x = 0; x < 3; x++) {
 points[x] = new Point();
 double ratio = (Math.random() * 6d) + 0.1d;
 int width = (int) (ratio * i.getWidth());
 int height = (int) (ratio * i.getHeight());
 points[x].y = Math.max(0, (int) (Math.random() * 800) - height);//use math.random to figure out coordinates and sizing
 points[x].x = Math.max(0, (int) (Math.random() * 800) - width);//make a loop
 images[x] = i.getScaledInstance(width, height, Image.SCALE_SMOOTH);
 }
 }
 public void paintComponent(Graphics g) {
 super.paintComponent(g);//set backgroun
 g.setColor(water);
 g.fillRect(0, 0, getWidth(), getHeight());
 if (points != null && images != null) {
 for (int index = 0; index < points.length; index++) {
 g.drawImage(images[index], points[index].x, points[index].y, this);
 }
 }
 }
 }
}

This is a rough example, which uses Image#getScaledInstance which is not generally recommended, but works for the example.

Have a look at The Perils of Image.getScaledInstance() for more details

Have a look at Quality of Image after resize very low -- Java and Java: maintaining aspect ratio of JPanel background image for possible (scaling) alternatives

I'd also have a look at Reading/Loading an Image for a better mechanism for loading images

answered Sep 17, 2015 at 2:05
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.