Results 1 to 16 of 16
  1. #1
    santa's Avatar
    santa is offline Senior Member
    Join Date
    Nov 2009
    Location
    Sweden
    Posts
    208
    Rep Power
    5

    Default Threads lagging ?

    Okey I have two threads, first one is :

    Java Code:
     public void run() {
         try {
            while(true){
    
                repaint();
                Thread.sleep(17);
                
                
            }
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
        }
    This thread repaints a JPanel at ~58 FPS .

    Java Code:
       public void run(){
            switch (MOVE_DIRECTION){
                //DOWN
                case 1:
                    try{
                        
                        while(MainPanel.getInstance().getKeyPressed()){
                           
                            MainPanel.getInstance().addPositionInWorldY(1);
                            Thread.sleep(15);
                           
                            
                        }
                    }catch(Exception e){
                        e.printStackTrace();
                    }
    
    
    
    
    
                break;
                //UP
                case 2:
                    try{
                        
                        while(MainPanel.getInstance().getKeyPressed()){
                            MainPanel.getInstance().decreasePositionInWorldY(1);
                            Thread.sleep(15);
                        }
                    }catch(Exception e){
                        e.printStackTrace();
                    }
    
    
    
                break;
                //LEFT
                case 3:
                   try{
                       
                        while(MainPanel.getInstance().getKeyPressed()){
                            MainPanel.getInstance().decreasePositionInWorldX(1);
                            Thread.sleep(15);
                        }
                    }catch(Exception e){
                        e.printStackTrace();
                    }
    
    
    
                break;
                //RIGHT
                case 4:
                     try{
                         
                        while(MainPanel.getInstance().getKeyPressed()){
                            MainPanel.getInstance().addPositionInWorldX(1);
                            Thread.sleep(15);
                        }
                    }catch(Exception e){
                        e.printStackTrace();
                    }
    
    
    
                break;
                }
    
    
    
    
    
    
        }
    This one is a switch case statement switching what to paint on the screen with 1 pixel every 15 sec if a button is pressed.

    My questions are :
    1. Why do the FPS thread take 30% of my cpu power? Or is that netbeans related? Because when i idle the cpu is around 30% all the time.

    2. When i move the background it goes smooth until a certain point where it starts lagging and after 5 sec it goes smooth again
    (im walking through a 1000x1000 array of small images). I thought first that this problem was that the position was updated while repainting but then i added a boolean so that the movement could only change if the repaint thread was sleeping. But still the same problem accrued ... do you guys think that this might be the graphics memory that goes full or the repaint thread that has a priority problem?

    Thanks =)

  2. #2
    DarrylBurke's Avatar
    DarrylBurke is online now Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,244
    Rep Power
    19

    Default Re: Threads lagging ?

    You're probably calling Swing methods off of the EDT. Go through this Lesson: Concurrency in Swing (The Java™ Tutorials > Creating a GUI With JFC/Swing)

    To get better help sooner, post a SSCCE (Short, Self Contained, Compilable and Executable) example that demonstrates the problem. And note that the first 'S' stands for Short.

    Also, get out of the habit of using excess vertical whitespace -- it makes the code hard to follow. See Code Conventions for the Java Programming Language: Contents

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

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

    Default Re: Threads lagging ?

    Thank you for posting the link I will read the tutorial to see if i missed something. I have read the SSCCE before and I just posted a switch statement... come on man... had i posted the whole class then I would see you point ... however lesson learned. The spaces was a mistake ... sorry about that.

  4. #4
    DarrylBurke's Avatar
    DarrylBurke is online now Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,244
    Rep Power
    19

    Default Re: Threads lagging ?

    Quote Originally Posted by santa View Post
    I have read the SSCCE before and I just posted a switch statement... come on man... had i posted the whole class then I would see you point ... however lesson learned.
    Evidently you didn't read it carefully. If it's not compilable, we can't test it. And since you're seeking help with a performance problem, you clearly don't know what's causing it.

    Neither do we, in the absence of a code we can compile and run ourselves. Or at least peruse in its entirety to see if something's rather obviously wrong.

    Looking at a switch statement gets us, and you, nowhere even close to a possible solution.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

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

    Default Re: Threads lagging ?

    Okey, sense I'm stuck I'll hope that you will forgive that I post ALL of the code because the program won't be "runnable" whiteout it:


    The main class:

    Java Code:
        public static void main(String[] args) {
    
         final  Thread initializer = new Thread(new Init());
          initializer.start();
    
            SwingUtilities.invokeLater(new Runnable(){
              public void run() {
                    try {
                        initializer.join();
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
        GUI gui = new GUI();
        gui.setTitle("Editor ALFA.");
        gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gui.setSize(800, 600);
        gui.setResizable(false);
        gui.setLocationRelativeTo(null);
        gui.setVisible(true);
    
        FrameRate frames = new FrameRate(); // framerate thread is posted above
        Thread frameRate = new Thread(frames);
    
        frameRate.start();
                }
            });
     }
    Main class will create 2 threads one for uploading the pictures to the game and to create the map and the other one creates the GUI. As it is now, the GUI will wait until everything in the init thread has loaded. (I know it's dump but I don't have any loading screen yet so the GUI has to wait).


    The init class: (Skip this class though its probably not the problem - It's just loading images and creating a map)
    Java Code:
    public class Init implements Runnable {
     
     public void run() {
            Block.backgroundimgs = loadFolder("tiles//");
            System.out.println(Block.backgroundimgs.length);
            for(int i = 0;i<Block.backgroundimgs.length;i++){
                System.out.println(Block.backgroundimgs[i].getName());
            }
            Map map = new Map();
            map.setAsCurrentMap();
    
        }
    
    public static ImageSpecs[] loadFolder(String path){
           File file = new File(path);
           if (file.isDirectory()){
    
            String[] files = file.list();
            ImageSpecs[] imgs = new ImageSpecs[files.length];
    
            for (int i= 0; i< files.length;i++){
                
                    try {
                        BufferedImage image = ImageIO.read(new File(path + files[i]));
                        imgs[i] = new ImageSpecs();
                        imgs[i].setImg(image);
                        imgs[i].setName(files[i]);
    
                    } catch (IOException ex) {
                        System.out.println(path );
                        ex.printStackTrace();
                    }
                  }
            System.out.println("Loaded " + imgs.length + " images from path "+path+".");
            return imgs;
           }else{
               file.mkdir();
               JOptionPane.showMessageDialog(null, "No images found in"+ path +", please check");
               System.exit(0);
              return null;
           }
    
    
           }
    
    }
    The GUI class: (Just for building the GUI)
    Java Code:
    public class GUI extends JFrame {
       
     Dimension mainSize = new Dimension();
        
    public GUI(){
    
        //LAYOUT STUFF HERE
        setLayout(new BorderLayout(20,10));
    
        // MAIN PANEL HERE
        MainPanel mainPanel = MainPanel.getInstance();
       mainSize.setSize(700, 550);
       add(mainPanel,BorderLayout.CENTER);
        mainPanel.setPreferredSize(mainSize);
        mainPanel.setBorder(BorderFactory.createLoweredBevelBorder());
        mainPanel.setFocusable(true);
     
    }
    
    }
    MainPanel class: (I suspect my problems lies within this class- Its basically only doing the painting on a JPanel)
    Java Code:
    public class MainPanel extends JPanel {
        private static MainPanel instance = null;
        private Dimension screenImage = new Dimension();
        private boolean keyPressed = false;
    
        private int positionWithinObjectX = 0,positionWithinObjectY =0,
                    paintX = 0,paintY = 0,objectToStartWithX =0,
                    objectToStartWithY =0,
    
                    positionInWorldX = 80,positionInWorldY =80;
       protected MainPanel(){
    
    
        addKeyListener(new KeyAdapter(){
    
                @Override
            public void keyReleased(KeyEvent e){
                
                keyPressed = false;
            }
                @Override
            public void keyPressed(KeyEvent e){
            switch (e.getKeyCode()){
     
                case KeyEvent.VK_DOWN:
                    if (keyPressed == false){
                    keyPressed = true;
                    new Thread(new MoveThread(1)).start();                //MoveThread is the switch statement in the previous post
                    }
                break;
    
                case KeyEvent.VK_UP:
                    if (keyPressed == false){
                     keyPressed = true;
                    new Thread(new MoveThread(2)).start();
                    }
                break;
    
                case KeyEvent.VK_LEFT:
                    if (keyPressed == false){
                     keyPressed = true;
                    new Thread(new MoveThread(3)).start();
                    }
                 break;
                
                case KeyEvent.VK_RIGHT:
                    if (keyPressed == false){
                     keyPressed = true;
                    new Thread(new MoveThread(4)).start();
                    }
    
                break;
                }
            }
        });
           // will cause a BUG in the future
        screenImage.height = (539 + 160);
        screenImage.width = (784 + 160);
        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);
    g2d.dispose();   
    }
    
     // I probably should not be doing so many for loops, but i just wanted it to work and i did not think about performance
        private void paintPositionInWorld(Graphics2D g2d){
          
          objectToStartWithX = getStartObj(positionInWorldX);
          objectToStartWithY = getStartObj(positionInWorldY);
          positionWithinObjectX = getPosInStartObj(positionInWorldX,objectToStartWithX);
          positionWithinObjectY = getPosInStartObj(positionInWorldY,objectToStartWithY);
         int calculatedNumObjectsY = (calNumObjects(positionWithinObjectY,screenImage.height)+1);
         int calculatedNumObjectsX = (calNumObjects(positionWithinObjectX,screenImage.width)+1);
         paintX = 0;
         paintY = 0;
    
          for ( int i = objectToStartWithY; i < (objectToStartWithY +
           calculatedNumObjectsY);i++){
    
              if(i == objectToStartWithY){
                for(int ii =objectToStartWithX;ii < (objectToStartWithX+
                        calculatedNumObjectsX);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+calculatedNumObjectsX);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+
                        calculatedNumObjectsX);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].paintMeNormal(g2d, paintX, paintY);
                        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);
        }
    
    
    
    }
    public void setPositionInWorldX(int X){
        positionInWorldX = X;
    }
    public void setPositionInWorldY(int Y){
        positionInWorldY = Y;
    }
    public void addPositionInWorldY(int num){
        positionInWorldY += num;
    }
    public void decreasePositionInWorldY(int num){
        positionInWorldY -= num;
    }
    public void decreasePositionInWorldX(int num){
        positionInWorldX -= num;
    }
    public void addPositionInWorldX(int num){
        positionInWorldX += num;
    }
    
    public int getPositionInWorldX(){
        return positionInWorldX;
    }
    public int getPositionInWorldY(){
        return positionInWorldY;
    }
    public boolean getKeyPressed(){
        return keyPressed;
    }
    public static MainPanel getInstance() {
          if(instance == null) {
             instance = new MainPanel();
          }
          return instance;
       }
    ------------------------------------------------------------------------------------------------------------------------
    Non important objects under here: Just posted to be able to run it
    ------------------------------------------------------------------------------------------------------------------------

    Map Class - only creates a 2d array of Block objects
    Java Code:
    public class Map {
    public static Block[][] currentMap;
    private Block[][]  map;
    
    public Map(){
    map = new Block[1000][1000];
    for(int i=0;i<map.length;i++){
        for (int g=0; g<map[i].length;g++){
            map[i][g] = new Block(g * 40, i *40);
        }
        currentMap = map;
    }
    }
    
    public Map(int mapSizeX,int mapSizeY){
        map = new Block[mapSizeY][mapSizeX];
    for(int i=0;i<map.length;i++){
        for (int g=0; g<map[i].length;g++){
            map[i][g] = new Block(g * 40, i *40);
        }
    }
    }
    
    public Block[][] getMap(){
        return map;
    }
    public void setAsCurrentMap(){
        currentMap = map;
    }
    }
    Block Class - For storing tiles ... blocks paints them self to the mainpanel
    Java Code:
    public class Block {
    public static ImageSpecs[] backgroundimgs;
    private Rectangle mySize = new Rectangle();
    private ImageSpecs currentBackground;
    
    Block(int x,int y){
    mySize.height = 40;
    mySize.width = 40;
    mySize.x = x;
    mySize.y = y;
    currentBackground = backgroundimgs[3];
    }
    
    // Paints part of image
    public void paintMe(Graphics2D g2d, int posX, int posY,int subPosX,int subPosY, int subSizeX, int subSizeY){
    BufferedImage draw = currentBackground.getImg().getSubimage(subPosX, subPosY, subSizeX, subSizeY);
     g2d.drawImage(draw, posX, posY, draw.getWidth(), draw.getHeight(), null);
    }
    // Paints full image
    public void paintMeNormal(Graphics2D g2d, int posX, int posY){
    g2d.drawImage(currentBackground.getImg(), posX, posY, mySize.width, mySize.height, null);
    
    }
    public void setSize(int x,int y){
        mySize.height = y;
        mySize.width = x;
    }
    public int getHeight(){
       return mySize.height;
    }
    public int getWidht(){
        return mySize.width;
    }
    public ImageSpecs getCurrentBackground(){
        return currentBackground;
    }
    public void setCurrentBackground(ImageSpecs img){
        currentBackground = img;
    }
    }
    Class ImageSpecs - A object just to store the image with its name
    Java Code:
    public class ImageSpecs {
    private BufferedImage img;
    private String name;
    
    public BufferedImage getImg(){
        return img;
    }
    public void setImg(BufferedImage img){
    this.img = img;
    }
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    }


    Please note that this was my last option, I did not want to post all this code. The code works ... but it does not get the wanted frame rate and sometimes starts to lagg. Also the cpu is going 20-30% if you just open the program and let it idle.

    Thanks for any tips.

  6. #6
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,015
    Rep Power
    20

    Default Re: Threads lagging ?

    I'm sorry, but it must be possible to reduce that lot to the bare minimum to show your problem.
    If nothing else it might actually show you where the problem lies.

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

    Default Re: Threads lagging ?

    My problem is that Im not sure where there is a problem otherwise i would be able to limit the code ... Basically most of the code comes from the paintComponent and it wont display without it ...

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

    Default Re: Threads lagging ?

    I'm pretty sure that mainPanel class and the paintPositionInWorld method is the bad egg.. basically it draws ~240 objects to the screen and I don't see why that would cause it to lagg? strange thing is when it starts it lags a bit... then it goes smooth for a while and then gradually starts to lag and after awhile it goes smooth again and continues like this. I'm going crazy about it...

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

    Default Re: Threads lagging ?

    Is it possible that I'm filling the video memory or something?

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

    Default Re: Threads lagging ?

    Nobody? Could someone please tell me if its okay to do as much in the paintComponent method as i do? I'm guessing the program gets lagged there :P I find it strange that it does not lag all the time..

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

    Default Re: Threads lagging ?

    You've got to do some debugging and perhaps some profiling. That's way too much code to ask a volunteer to go through.

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

    Default Re: Threads lagging ?

    Yeah I understand ... Basically I'm doing that as we speak. but the code does what its supposed to do it draws exactly whats supposed to be on the screen and it does so for about 30 sec of "walking" (when looping in the array displaying other objects). But after a while of scrolling the screen trough the objects it gets slower and get a small (but very annoying) lag. But after 30 sec it goes running smooth as hell and it continues like this. I'm basically doing a game engine, but It's not acceptable to lag just going through a array of bufferedImages painting ~300 of them =(

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

    Default Re: Threads lagging ?

    To answer one of your questions: no your paintComponent method is not good as it appears to call a method that performs a *lot* of program logic and will likely slow things down. The paintComponent method (and any methods it calls) should do nothing but draw. It should be small and fast and again contain no program logic whatsoever.

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

    Default Re: Threads lagging ?

    So basically the logic would be done in another thread and then given to the paintComponent for it to draw? Could you give a simple example of a good approach? Just having the paintComponent checking some variables for what to paint ? My head is stuck in a deadlock. I will spend tonight trying to improve the performance of paintComponent.

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

    Default Re: Threads lagging ?

    I can't tell what you should do based on the mass of code presented, but general rules to follow are that if the code takes time to complete, it should probably be in a background thread. The code should update the state of the class by changing state fields and then call repaint so that the paintComponent can use the state fields to help it decide what to draw.

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

Similar Threads

  1. New to threads
    By armyson in forum Threads and Synchronization
    Replies: 0
    Last Post: 12-09-2011, 07:52 AM
  2. Threads per Connection or Threads per Request
    By Felic in forum New To Java
    Replies: 4
    Last Post: 11-22-2011, 09:15 PM
  3. threads
    By brindha1688 in forum New To Java
    Replies: 3
    Last Post: 05-24-2011, 08:07 PM
  4. How to stop lagging in a JPanel?
    By rajkobie in forum AWT / Swing
    Replies: 1
    Last Post: 04-17-2011, 12:04 PM
  5. When to use threads
    By simorgh in forum Threads and Synchronization
    Replies: 2
    Last Post: 02-12-2010, 07:43 AM

Posting Permissions

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