idkmanidk
idkmanidk

Reputation: 13

Graphics loop glitches, how to fix?

I've been trying to make this work so that there are 20 boxes each with 3 different sizes and 3 different colours that chosen at random, but i cant make them come out at different times and they just glitch into eachother and the colours are glitching together and stuff like that, anyone know how to fix it? Heres what i got so far:

    import java.awt.*;
    import javax.swing.*;
public class testwork extends JPanel { //JPanel is a class

int l = 0;
private int x = 10; 
private int y = 500; 
private void move()
{
x++;
}
boolean red = false;
boolean blue = false;
boolean green = false;


@Override
public void paint(Graphics g) { //JPanel is a class defined in
super.paint(g);
Graphics2D g2d = (Graphics2D) g;

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON); 

Color rectColor = new Color(0, 66, 89);
g2d.setColor(rectColor);
//belt
g2d.setColor(Color.lightGray);
g2d.fillRect(0,450,1500,200);
g2d.fillRect(700,0,200,1000);
g2d.setColor(Color.orange);
for (int i = -10000; i<10000; i=i+50) {
    int m= i++;
    g2d.fillRect(m, 450, 25, 200);
}
g2d.setColor(Color.DARK_GRAY);
g2d.fillRect(700, 450, 200, 200);
//boxes
while (l<=20) {
if (Math.random() < 0.5) 
{g2d.setColor(Color.RED);;}
else if (Math.random() < 0.5) {g2d.setColor(Color.GREEN);}
else {g2d.setColor(Color.BLUE);}

if (Math.random() < 0.5) 
{g2d.fillRect(x,y,50,50);}
else if (Math.random() < 0.5) {g2d.fillRect(x,y,50,100);}
else {g2d.fillRect(x,y,100,50);}
l++;
}

}

public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Frame"); //Add our JPanel to the frame
frame.add(new attempt());//instantiate a new object

frame.setSize(1500, 1000);

frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testwork p = new testwork();
frame.add(p);
while (true)
{
p.move(); //Updates the coordinates
p.repaint();
Thread.sleep(10); //Pauses for a moment
}}

}

Upvotes: 0

Views: 112

Answers (1)

WJS
WJS

Reputation: 40034

Unfortunately, you are doing a number of things incorrectly.

  1. Override paintComponent and not paint.
  2. Don't use Thread.sleep. Use a Swing timer and an ActionListener
  3. You are doing too much in the painting method. All event handling including calls to repaint() is done on the Event Dispatch Thread(EDT). So all your updating are done inside of paintComponent so only the last painted objects will be shown when you exit. Update your coordinates, data structure and anything else that needs to be painted outside of your paint method.

Put your boiler plate code inside your Testwork class constructor. Here is an example.

  public Testwork() {

      setPreferredSize(new Dimension(1000, 700));
      Timer timer = new Timer(0, this);
      frame.setVisible(true);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      frame.add(this);
      // sizes the frame and jpanel and organizes the components.
      frame.pack();
      // centers the window in the screen
      frame.setLocationRelativeTo(null);
      // sets the delay in milliseconds
      timer.setDelay(100);
      // starts the timer
      timer.start();
   }

Here would be your actionListener code.

     public void actionPerformed(ActionEvent ae) {
       // update any variables that need to be used int he
       // paint routine here. That means if you want to move something
       // update the coordinates here and then use them in the paint method.

     }

when you start up, your app, do it like this

    public static void main(String[] args) {
      SwingUtilities.invokeLater(() -> new Testwork());
    }

There is much more to painting. I recommend checking out Custom Painting in the Java tutorials. Here is another example on this (SO) site.

Upvotes: 1

Related Questions