Results 1 to 11 of 11

Thread: repaint()?

  1. #1
    santa's Avatar
    santa is offline Senior Member
    Join Date
    Nov 2009
    Location
    Sweden
    Posts
    208
    Rep Power
    6

    Default repaint()?

    Just to be sure a call to repaint() will start a new thread to paint on the screen?

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: repaint()?

    Quote Originally Posted by santa View Post
    Just to be sure a call to repaint() will start a new thread to paint on the screen?
    No, not in the least. A call to repaint sends a request to the paint manager to repaint the component which it may do by calling the component's paint method passing in to the method's parameter a current Graphics object. No new threads are created with this method call.

  3. #3
    santa's Avatar
    santa is offline Senior Member
    Join Date
    Nov 2009
    Location
    Sweden
    Posts
    208
    Rep Power
    6

    Default Re: repaint()?

    I was thinking that there would be another thread because in Y. Daniel Liangs book it says: "The repaint method lodges a request to update the viewing area and returns immediately.Its effect is asynchronous, meaning that it is up to the JVM to execute the paintComponent method in a separate thread.

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: repaint()?

    Quote Originally Posted by santa View Post
    I was thinking that there would be another thread because in Y. Daniel Liangs book it says: "The repaint method lodges a request to update the viewing area and returns immediately.Its effect is asynchronous, meaning that it is up to the JVM to execute the paintComponent method in a separate thread.
    I stand corrected. The request to the Swing RepaintManager is made asynchronously, which then creates a Runnable which is queued on the event dispatch thread as described here: Painting in AWT and Swing

    But I disagree on the last bit. According to my article, paintComponent is always executed on the EDT.

  5. #5
    santa's Avatar
    santa is offline Senior Member
    Join Date
    Nov 2009
    Location
    Sweden
    Posts
    208
    Rep Power
    6

    Default Re: repaint()?

    so what will happen if you call repaint() from a thread? will the new thread draw the objects or can there only be one thread drawing graphics?

    My problem is that i'm creating a game and i want one thread to move the background and another to move the character and a new thread for each "monster". It causes me a problem with the performance to but to much in the paintcomponent method. Can this be solved by passing around the graphics object to the different threads?

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: repaint()?

    Quote Originally Posted by santa View Post
    so what will happen if you call repaint() from a thread? will the new thread draw the objects or can there only be one thread drawing graphics?
    This I can guarantee: all drawing within paintComponent will be done on the EDT. The new thread created by a repaint request is for the request only. The RepaintManager will then do all painting on the EDT.

    My problem is that i'm creating a game and i want one thread to move the background and another to move the character and a new thread for each "monster". It causes me a problem with the performance to but to much in the paintcomponent method. Can this be solved by passing around the graphics object to the different threads?
    Are you using BufferedImages? In particular, are you using a BufferedImage for your background? This can speed things up considerably. There are other tricks for creating games with Swing that I'm not familiar with as I do not do this. Another thing I've gleaned from my reading as that most serious Java games with graphics don't use Swing but instead other rendering/graphics libraries such as the Lightweight Java Game Library or LWJGL.

  7. #7
    santa's Avatar
    santa is offline Senior Member
    Join Date
    Nov 2009
    Location
    Sweden
    Posts
    208
    Rep Power
    6

    Default Re: repaint()?

    So there will only be one thread painting?

    Im using buffered images, basically I'v been programming Erlang so much that I'v forgot about java.

    I got one tip on the forum that was "just focus on drawing what you want to draw and then worry about the performance", well i'm now in the worrying stage . I'v done some code that is pretty embarrassing and I now wish to worry about quality and performance for this code.

    So basically I have an array of 1000x1000 objects, witch will be the "tiles" witch together will provide the background. And the embarrassing code that i'v written displays only the objects that currently is on screen. (background will move when you press the arrow keys.)

    Here is the code without the stuff i don't want to ask about (variables/comments/etc) . Don't read the code now just skip to the end questions !
    Java Code:
    public class MainPanel extends JPanel implements ComponentListener {
       private Dimension screenImage = new Dimension();
    
     
       public MainPanel(){
    
    
        addKeyListener(new KeyAdapter(){
                @Override
            public void keyPressed(KeyEvent e){
            switch (e.getKeyCode()){
                case KeyEvent.VK_DOWN:
                    if ((objectToStartWithY + numOfBlocksY) < 1001)
                    positionInWorldY += testSpeed;
    //                repaint();                                     // was repainting from here before ! 
                    
                break;
                case KeyEvent.VK_UP:
                    if (objectToStartWithY > 0 || positionWithinObjectY>testSpeed){
                    positionInWorldY -= testSpeed;
    //                repaint();
                    }
                break;
                case KeyEvent.VK_LEFT:
                    if (objectToStartWithX > 0 || positionWithinObjectX>testSpeed){
                    positionInWorldX -= testSpeed;
    //                repaint();
                    }
                break;
                case KeyEvent.VK_RIGHT:
                    if ((objectToStartWithX + numOfBlocksX) < 1001){  
                    positionInWorldX += testSpeed;
     //               repaint();
                    }
                break;
                }
    
            }
    
        });
           // the will cause a BUG in the future, FIX IT LATER! 
        screenImage.height = (539 + 160);
        screenImage.width = (784 + 160);
        addComponentListener(this);
        setBackground(Color.BLACK);
    
            
        }
    
    
    
    
    
    
    
    
        @Override
    public void paintComponent(Graphics g){
            super.paintComponent(g);
    Graphics2D g2d = ((Graphics2D) g);
    
    if (getSize().width <= 0 || getSize().height <= 0){
         return;
    }
      paintPositionInWorld(g2d);
    
         repaint();
    
    
    
        
    }
    
        private void paintPositionInWorld(Graphics2D g2d){
          objectToStartWithX = getStartObj(positionInWorldX);
          objectToStartWithY = getStartObj(positionInWorldY);
          positionWithinObjectX = getPosInStartObj(positionInWorldX,objectToStartWithX);
          positionWithinObjectY = getPosInStartObj(positionInWorldY,objectToStartWithY);
    
            paintX = 0;
            paintY = 0;
    
          for ( int i = objectToStartWithY; i < (objectToStartWithY +
           calNumObjects(positionWithinObjectY,screenImage.height)+1);i++){
    
              if(i == objectToStartWithY){
                for(int ii =objectToStartWithX;ii < (objectToStartWithX+
                        calNumObjects(positionWithinObjectX,screenImage.width)+1);ii++){
    
                    
                    if(ii == objectToStartWithX){
                    Map.currentMap[i][ii].paintMe(g2d,paintX,paintY,positionWithinObjectX,
                            positionWithinObjectY,40-positionWithinObjectX,40-positionWithinObjectY);
         
                    paintX += 40 -positionWithinObjectX;
                    }else if ((screenImage.width - paintX)< 40 && (screenImage.width - paintX) > 0){
    
                        Map.currentMap[i][ii].paintMe(g2d,paintX,paintY,0,positionWithinObjectY,
                                (screenImage.width - paintX),40 - positionWithinObjectY);
                        paintX += screenImage.width - paintX;
                        break;
                    }else{
                         Map.currentMap[i][ii].paintMe(g2d,paintX,paintY,0,positionWithinObjectY,40,40 -positionWithinObjectY);
                        paintX += 40;
                    }
                    }
                paintY += 40 -positionWithinObjectY;
                }else if((screenImage.height - paintY)< 40 && (screenImage.height - paintY) > 0){
    
    
    
                    for(int ii =objectToStartWithX;ii < (objectToStartWithX+
                        calNumObjects(positionWithinObjectX,screenImage.width)+1);ii++){
    
    
                    if(ii == objectToStartWithX){
                    Map.currentMap[i][ii].paintMe(g2d,paintX,paintY,positionWithinObjectX,
                            0,40-positionWithinObjectX,screenImage.height - paintY);
    
                    paintX += 40 -positionWithinObjectX;
                    }else if ((screenImage.width - paintX)< 40 && (screenImage.width - paintX) > 0){
    
                        Map.currentMap[i][ii].paintMe(g2d,paintX,paintY,0,0,
                                (screenImage.width - paintX),screenImage.height - paintY);
                        paintX += screenImage.width - paintX;
                        break;
                    }else{
                         Map.currentMap[i][ii].paintMe(g2d,paintX,paintY,0,0,40,screenImage.height - paintY);
                        paintX += 40;
                    }
                    }
                paintY += screenImage.height - paintY;
                break;
    
                }else {
                  for(int ii =objectToStartWithX;ii < (objectToStartWithX+
                        calNumObjects(positionWithinObjectX,screenImage.width)+1);ii++){
    
    
                    if(ii == objectToStartWithX){
                    Map.currentMap[i][ii].paintMe(g2d,paintX,paintY,positionWithinObjectX,
                            0,40-positionWithinObjectX,40);
    
                    paintX += 40 -positionWithinObjectX;
                    }else if ((screenImage.width - paintX)< 40 && (screenImage.width - paintX) > 0){
    
                        Map.currentMap[i][ii].paintMe(g2d,paintX,paintY,0,0,
                                (screenImage.width - paintX),40);
                        paintX += screenImage.width - paintX;
                        break;
                    }else{
                         Map.currentMap[i][ii].paintMe(g2d,paintX,paintY,0,0,40,40);
                        paintX += 40;
                    }
                    }
    
      paintY += 40;
     }
                paintX = 0;
                
    
    
           }
        }
    private int getPosInStartObj(int positionInWorld,int startingObj){
       return (int) Math.floor((((positionInWorld / 40.0) - startingObj) * 40) +0.5f);
    }
      private int getStartObj(int worldPosition){
          return (int) Math.floor(worldPosition/40.0);
      }
    
    private int calNumObjects(int posInObject,int screenWidth){
    double d = screenWidth/40.0;
        if((int)d == d){
            return (int)d;
        }else{
            return (int) ((Math.ceil(((screenWidth - posInObject)/40.0)))+1);
        }
    
    
    
    }
    PaintMe just paints that object with drawimage.







    Questions:
    1. Do you see anywhere in the code where i can make it better/improve the quality? please let me know ! =) (I know this code suck! But i couldn't solve it out mathematically )

    2. I have a general idea that paintComponent should not be doing this much. Should i make another thread to do the calculations and then just pas around the graphics object? ex. thread number one draws the background then passes the object to thread number 2 who draws the mobs ? or should i have one thread who is just looping first drawing background to an image then draws the mobs to the image and then pass the image to the paintcomponent? I am a new beginner in graphics/threads in general, I just want to get some general directions what way the painting should be architectured?

    3. As you can see i started you doing repaints in the keylistener and that got kind of blurry. So just for testing i looped repaint in paintcomponent and the result was better but not satisfying. So this question is for the keylistener is there a better way of listening ? should i have a loop in staid? Because now it jumps 1 pixel then stops and then start looping uneven.

    I do now that probably no one is going to read all that code but i cant shorten it more without ruining its purpose.

    If you guys have any tip, thank you in advance =) and sorry for the code quality but i just wanted it to work

  8. #8
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: repaint()?

    That's a lot of code to go through

    One thing that shouldn't be there is a repaint() call from within the paintComponent method which is almost like recursion.

    And no, don't pass a Graphics object obtained from paintComponent out into a background thread as I have a strong suspicion that that is asking for trouble. Sure you can do this with the Graphics object from a BufferedImage object that is not currently being rendered to screen but not to the current active Graphics object.

  9. #9
    santa's Avatar
    santa is offline Senior Member
    Join Date
    Nov 2009
    Location
    Sweden
    Posts
    208
    Rep Power
    6

    Default Re: repaint()?

    I know i should not be doing that ... but while its recursing forever i get a better framerate then from the actionlisteners. I did it to try and find whats slowing it down.

    So basically I can start writing to an image ... pass it to different threads and then draw it to the screen maybe?

    Anyway is there it possible to do a while loop in a actionlistener? for example while( keypressed:VK_DOWN){ y += 1} or do i have to break it from key released ? because when i do it by events it reacts to the pressing and then there is a delay before reacting more.

  10. #10
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: repaint()?

    Quote Originally Posted by santa View Post
    I know i should not be doing that ... but while its recursing forever i get a better framerate then from the actionlisteners. I did it to try and find whats slowing it down.
    Just don't do it. Period.

    So basically I can start writing to an image ... pass it to different threads and then draw it to the screen maybe?
    You could draw images in a background thread, and then when done use them, yes.

    Anyway is there it possible to do a while loop in a actionlistener? for example while( keypressed:VK_DOWN){ y += 1} or do i have to break it from key released ? because when i do it by events it reacts to the pressing and then there is a delay before reacting more.
    I'd use a Swing Timer for stuff like this.

  11. #11
    santa's Avatar
    santa is offline Senior Member
    Join Date
    Nov 2009
    Location
    Sweden
    Posts
    208
    Rep Power
    6

Similar Threads

  1. repaint every
    By 3xpr1ment in forum AWT / Swing
    Replies: 10
    Last Post: 03-23-2010, 06:39 PM
  2. Repaint problem
    By citizenXL in forum New To Java
    Replies: 4
    Last Post: 10-28-2009, 04:02 PM
  3. Trying to do a simple repaint
    By IYIaster in forum New To Java
    Replies: 9
    Last Post: 10-14-2009, 11:30 PM
  4. Repaint() not working
    By Catkill in forum AWT / Swing
    Replies: 3
    Last Post: 09-09-2009, 11:51 PM
  5. repaint() problems
    By Emily1100125 in forum AWT / Swing
    Replies: 5
    Last Post: 02-03-2009, 05:11 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •