5

I have this method paint() which receive a Graphics2D parameter. The weird thing that happen is that unless there is a System.out.println present(which i comment out in the block below), the canvas will not draw anything.

public class Map{

    public void paint(Graphics2D g){

        //fill background to black
        g.setColor(Color.black);
        g.fillRect(0, 0, TILE_SIZE*WIDTH, TILE_SIZE*HEIGHT);

        //draw the tiles and buildings

        for(int i=0;i<WIDTH;i++){
            for(int j=0;j<HEIGHT;j++){
                if(map[j][i] == CLEAR){
                    //System.out.println("");
                    g.setColor(Color.gray);
                    g.fillRect(i*TILE_SIZE, j*TILE_SIZE, TILE_SIZE, TILE_SIZE);
                    g.setColor(Color.red);
                    g.drawRect(i*TILE_SIZE, j*TILE_SIZE, TILE_SIZE, TILE_SIZE);

                }
            }
        }
    }
}

Here I use BufferStrategy to draw on Canvas and add it to a Frame. This method is in class Map which will be passed a Graphics2D from the getDrawGraphics() method from BufferStrategy(I hope many people are familiar with this stuff to understand what I'm doing).

public class MapTest extends Canvas{

    private Map map;

    public MapTest(){

        Frame frame = new Frame("MAP");
        frame.add(this);
        frame.setVisible(true);

        createBufferStrategy(2);
        strategy = getBufferStrategy();

        //draw the map

        Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
        //g.translate(100, 100);
        map.paint(g);

        g.dispose();
        strategy.show();

    }
}

This code is from the Canvas class. As you can see the paint() method is separate from the Canvas class(which I name GameTest). So if I comment out the println statement then no graphics is shown in the canvas, otherwise it is displayed correctly. Anyone can help me???

Phat RedDevil
  • 63
  • 1
  • 6
  • 7
    One thing that comes to my mind is that I had similar issues regarding to this, and have found out that the `System.out.println()` causes Thread synchronization. – everton Mar 22 '12 at 16:44
  • I know this is a serious issue, and you need some answers, but I just couldn't resist LOL when I read your question subject :) – dbrin Mar 22 '12 at 17:44
  • 2
    Yup, sounds like a thread synchronization problem. I'm guessing that you're calling this from a thread other than the event-dispatching thread, which is the cause of most bugs of this sort. Have a look at http://en.wikipedia.org/wiki/Event_dispatching_thread for a pretty good discussion of the topic. – GreyBeardedGeek Mar 22 '12 at 17:55
  • For better help sooner, post an [SSCCE](http://sscce.org/). Why are you using an AWT based `Canvas` & `Frame` in this millennium? – Andrew Thompson Mar 22 '12 at 18:33
  • The wikipedia article that was linked links to the different methods. – Corbin Mar 23 '12 at 08:20
  • @GreyBeardedGeek: I update the code so you can see that I don't create any thread other than the event dispatching thread from the system. – Phat RedDevil Mar 23 '12 at 08:25
  • @DmitryB: I know this problem is so stupid man :) – Phat RedDevil Mar 23 '12 at 08:26
  • @AndrewThompson: I try to use BufferStrategy from a Canvas to draw and add this Canvas to a Frame to display. Similar to this: http://www.cokeandcode.com/index.html?page=tutorials/tilemap1 – Phat RedDevil Mar 23 '12 at 08:34

1 Answers1

2

You should use the SwingUtilities to switch to the Event Dispatch Thread(EDT), see below. This is required for almost all interactions with AWT and Swing classes.

  SwingUtilities.invokeLater(new Runnable(){
      public void run(){
          new MapTest();
      }    
   }

Notice that this uses a swing helper library, that should be fine for AWT, but even better is to start using Swing.

Thirler
  • 20,239
  • 14
  • 63
  • 92
  • Thanks for your answer but it still not show anything :( I guess the problem is not because of thread synchronization. Actually my code is based on the tutorial from cokeandcode.com and the site's code runs perfectly! (with no invokeLater() stuff) – Phat RedDevil Mar 23 '12 at 08:51
  • 1
    You could test if it works properly when you using `JPanel` from swing. (Have your Map class extend JPanel and add it to a JFrame). The JPanel is double buffered by default and the paint function looks compatible. That way you can see if the problem is in the BufferedStrategy. – Thirler Mar 23 '12 at 09:05
  • It worked!! I change Map to JPanel and add it to the JFrame and delete all the BufferStrategy stuff and everything worked fine! So the problem is in BufferStrategy right?? But what can be wrong?? Why BufferStrategy mess up with a println()? – Phat RedDevil Mar 23 '12 at 10:53
  • Well there could be another synchronization problem or a race condition that running it from the wrong thread, I don't have much experience with the BufferedStrategy. – Thirler Mar 23 '12 at 11:03
  • I find out the solution! Putting all my drawing stuff in a loop solves the problem. Seems to me that BufferStrategy can mess up if you try to use it to draw a single screen. By the way I use double buffering. Is that related to my problem? – Phat RedDevil Mar 23 '12 at 16:38