0

i am new in java and wanna to draw some random size & color rectangles concurrently. I use Jframe and Canvas to present the output of my threads. And awt to draw my rectangles. I Also making my class to implements Runnable to make it multi-threading;

What my code runs just shows the output of one thread(which draws 10 random rectangles here). And it seems like two thread are not showing their output in the same canvas.(otherwise it will be 20) And since my canvas is called in main class first and then two threads been called, so i don't know how to make the canvas globally to let both two threads draw on it.

how to solve this problem?

(there are many useless api imported just in case)

import java.awt.Graphics;
import java.awt.image.*;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.io.*;
import javax.imageio.*;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Draw1 extends Canvas implements Runnable {

    //set thread attributes
    private Thread t;

    public static void main(String[] args) {
        JFrame frame = new JFrame("my test draw");
        Canvas canvas = new Draw1();
        frame.setSize(400, 400);
        frame.add(canvas);
        frame.pack();
        frame.setVisible(true);



        Draw1 R1 = new Draw1();
        R1.start();

        Draw1 R2 = new Draw1();
        R2.start();
    }

    public void paint(Graphics g) {
        // DrawRect(int x, int y, int width, int height, Style style)
        // Returns DrawRect with given rectangle.

        //each thread draw 10 rects
        for(int i = 10; i>0; i--)
        {
            //ramdom color
            int c1 = (int) (Math.random() * ((255 - 0) + 1)) + 0;
            int c2 = (int) (Math.random() * ((255 - 0) + 1)) + 0;
            int c3 = (int) (Math.random() * ((255 - 0) + 1)) + 0;
            g.setColor(new Color(c1, c2, c3));
            //set the x,y position and height,width
            int x = (int) (Math.random() * ((400 - 0) + 1)) + 0;
            int y = (int) (Math.random() * ((400 - 0) + 1)) + 0;
            int w = (int) (Math.random() * ((100 - 0) + 1)) + 0;
            int h = (int) (Math.random() * ((100 - 0) + 1)) + 0;
            g.drawRect(x, y, w, h);
        }
    }

    @Override
    public void run() {
        System.out.println("Running " );
        try {
            repaint();
        } catch (Exception e) {
            System.out.println("Thread  interrupted.");
        }
        System.out.println("Thread  exiting.");     
    }

    public void start() {
        System.out.println("Starting ");
        if (t == null) {
            t = new Thread(this);
            t.start();
        }
    }

}
  • 1. Don't use AWT's Canvas but rather use JPanel. 2. Draw inside the JPanel's paintComponent method. 3. Call the super's same paintComponent method within your override. 4. Create the Rectangles in a Swing Timer, if you want to create them with delay. 5. Put the Rectangles into a collection, such as an `ArrayList`. Use a for loop in the paintComponent method to draw each Rectangle in the list. 6. Call `repaint()` in your Swing Timer after creating each Rectangle and adding it to the ArrayList. – Hovercraft Full Of Eels Feb 01 '20 at 22:32
  • Been many years since I've used AWT, but don't assume that `repaint()` calls `paint()`. Documentation says that `repaint()` _causes_ a call to `paint()` "as soon as possible." My _guess_ is that that subsequent `paint()` call always will happen in AWT's Event Dispatch Thread (EDT), and not in your R1 thread or your R2 thread. – Solomon Slow Feb 01 '20 at 22:36
  • Are there some way to do with AWT and canvas? As these apis are recommended in the assignment description... – Cghhqx5944 Feb 01 '20 at 23:46
  • Been many years since I've used AWT. I don't know whether there's any way to get a `Graphics` context that is meaningful to draw on outside of some component's `paint(g)` method. If this is a school assignment, that's a shame because nobody should be using AWT anymore. AWT was abandoned by its creators something like twenty years ago when they created Swing, and Swing itself has been considered to be "old-school" for a good long time now. – Solomon Slow Feb 02 '20 at 18:46

0 Answers0