0

I have a paintComponent method, inside a class.It makes a grid of 10*10. And I want to lower the frame rate, so that every time the function colors a rectangle in the grid, I can see the progression

    public void paint(Graphics g1) {
        super.paint(g1);
        Graphics2D g= (Graphics2D) g1;
        
        for(Object a: Maze_Generator.list) {
            Cell c =(Cell)a;
            if(c.top())
                g.drawLine(c.x(), c.y(), c.x()+c.length(), c.y());
            if(c.bottom())
                g.drawLine(c.x(), c.y()+c.length(),c.x()+c.length(),c.y()+c.length());
            if(c.left())
                g.drawLine(c.x(), c.y(), c.x(), c.y()+c.length());
            if(c.right())
                g.drawLine(c.x()+c.length(), c.y(), c.x()+c.length(), c.y()+c.length());
            
// I wish to delay the following code by a second, so that I can see as the square gets coloured one by one.
            if(c.visited()) {
                g.setColor(Color.cyan);
                g.fillRect(c.x()+1, c.y()+1, c.length()-1, c.length()-1);
                g.setColor(Color.black);
                
            }
        }   

I tried using Thread.sleep(), but for some reasons the App freezes, and UI crashes(I only see JFrame, with white background,and it does not close) But the program still runs in Background

try{Thread.sleep(2000);}catch(Exception e){ e.printStackTrace();}
            if(c.visited()) {
                g.setColor(Color.cyan);
                g.fillRect(c.x()+1, c.y()+1, c.length()-1, c.length()-1);
                g.setColor(Color.black);

Any Suggestions?

Code Hard
  • 43
  • 4

2 Answers2

2

The problem is that when you use the Thread.sleep() method, it stops the thread's work, and with that freezes your program. The solution involves asynchronous programming. In java we can create another thread to preform the task that takes time, and that we want to use Thread.sleep() in.

With the release of lambda expressions in Java 8, we can use this syntax:

Thread newThread = new Thread(() -> {
    // Code that you want to perform asynchronously
});
newThread.start();
amitlisha
  • 140
  • 1
  • 8
  • Correct, but generally better to use the Executors framework built into modern Java, rather than directly manipulate `Thread`. – Basil Bourque Dec 02 '20 at 08:30
  • I tried this method, but it does not executes the grapic/draw code inside. It works when i tried to print some text to console, but it does not executes the fillRect command. What should I do? – Code Hard Dec 03 '20 at 04:50
  • when debugging, can you see it execute? – amitlisha Dec 03 '20 at 11:01
  • yes, when I put some print code, inside new Thread, it works fine and prints into console, only the graphic methods like(fillRect and others) does not seems to be working – Code Hard Dec 03 '20 at 12:21
  • After some search, I found out that Graphics2D can only work single threaded. But they offer some solutions for your problem. Look here: https://stackoverflow.com/questions/16545075/reference-of-graphics-2d-object-doesnt-work-in-orphan-thread – amitlisha Dec 04 '20 at 12:47
1

I think your program should have two treads:

  • GUI thread (Used for rendering GUI)
  • Logic thread (Used for making some logical judgement) GUI thread will have a updateGUI method for passing message to GUI thraed and rendering based on the passed message.

please take a look following answers:

Hugo Zhang
  • 51
  • 3