Results 1 to 12 of 12
  1. #1
    Join Date
    Nov 2010
    Posts
    6
    Rep Power
    0

    Default Putting graphics into the run() method.

    Hello guys I'm having trouble calling the paintComponent() method with my run() method. I'm a little new to threads and programming in general, so I would definitely appreciate any help.

    Main Class
    Java Code:
    import javax.swing.JOptionPane;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import java.awt.FlowLayout;
    class mainFrame extends JFrame{
     
        
            public static void main(String[] args){
              JFrame f = new JFrame("POOOOP");
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
              Thread t1 = new Thread(new Orb());
              
              t1.start();
              
              f.setSize(500, 500);
              f.setVisible(true);
      }
    }
    Other Class
    Java Code:
    import java.awt.*;
    import javax.swing.*;
    import java.util.Random;
    /**
    * "extends" is the word for inheriting a class
    */
    public class Orb extends JPanel implements Runnable
    {  
      //Create random Integers
      Random xAxis = new Random();
     Random yAxis = new Random();
     Random increaseX = new Random();
     Random increaseY = new Random();
     //Assign random integers to Variables
     public int x;
     public int y;
     int numberX;
     int numberY;
     //Constructor
     public Orb()
     {
       x = xAxis.nextInt(500);
       y = yAxis.nextInt(500);
       numberX = increaseX.nextInt(2);
       numberY = increaseY.nextInt(2);
      Graphics g = this.getGraphics();
     }
     
       //this paintComponent method creates the circle
     
     public void paintComponent(Graphics g){
      super.paintComponent(g);
      g.setColor(Color.BLUE);
      g.fillOval( x,  y, 50,50);
    
     }
    
      //this method draws a circle by calling the paintComponent method
     public void run(){
       try{
       paintComponent(g);
       
       }
       catch(Exception e){}
    
      }
    }
    The app isn't finished yet, but a critique on the code will still be appreciated! Thanks in advance guys.
    Last edited by Eranga; 11-15-2010 at 02:05 AM. Reason: code tags added

  2. #2
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    20

    Default

    Please use code tags next time posting code segments here in the forum. Unformated codes are really hard to read. If you don't know how to do that, check on my forum signature. You can find the relevant link.

  3. #3
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    20

    Default

    In run() method, you've pass a parameter without defining it.

    Java Code:
    paintComponent(g);
    How can you solve it. I mean is it correct? Think about it and let me know what you think. I'll help you to solve it.

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

    Default

    You never call paintComponent directly. Instead you want to call repaint. Please read a tutorial on Swing graphics as this should all be explained there.

  5. #5
    Join Date
    Nov 2010
    Posts
    6
    Rep Power
    0

    Default

    Thanks for the reply and sorry for my ignorance of the code formatting.

    regarding of the parameters of paintComponent(g), I was thinking that the method would catch the (g) from the constructor:

    Java Code:
    public Orb()
     {
       x = xAxis.nextInt(500);
       y = yAxis.nextInt(500);
       numberX = increaseX.nextInt(2);
       numberY = increaseY.nextInt(2);
      Graphics g = this.getGraphics();
     }
    But it didn't. I tried sticking the "Graphics g = this.getGraphics();" all over the place and didn't get any results. I put it in the field of the class, and inside the run() method. But I always ended up with no circle.



    Thanks for the help, I appreciate it.

  6. #6
    DarrylBurke's Avatar
    DarrylBurke is online now Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,300
    Rep Power
    20

    Default

    Never never never use getGraphics() of a Component. Or at least, not until you have as much knowledge on the subject as Fubarable.

    As Fubarable has already told you, paintComponent(Graphics) is not to be invoked from client code. Just call repaint() and let the RepaintManager do the rest.

    db

  7. #7
    Join Date
    Nov 2010
    Posts
    6
    Rep Power
    0

    Default

    Thanks for the suggestions guys. None of the tutorials I read gave me any help with running the paintComponent method inside a run() method. I tried using the repaint() method inside my run() method but I still don't get any results.


    MAIN CLASS
    Java Code:
    import javax.swing.JOptionPane;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import java.awt.FlowLayout;
    class mainFrame extends JFrame{
     
        
            public static void main(String[] args){
              JFrame f = new JFrame("POOOOP");
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              mainPanel m = new mainPanel();
              f.add(m);
              Thread t1 = new Thread(new Orb());
              
              t1.start();
              
              f.setSize(500, 500);
              f.setVisible(true);
      }
    }
    OTHER CLASS

    Java Code:
    import java.awt.*;
    import java.awt.image.ImageObserver;
    import java.text.AttributedCharacterIterator;
    import java.awt.Graphics;
    import javax.swing.*;
    import java.util.Random;
    /**
    * "extends" is the word for inheriting a class
    */
    public class Orb extends JPanel implements Runnable
    {  
      
      //Create random Integers
      Random xAxis = new Random();
     Random yAxis = new Random();
     Random increaseX = new Random();
     Random increaseY = new Random();
     //Assign random integers to Variables
     public int x;
     public int y;
     int numberX;
     int numberY;
     
    
     //Constructor
     public Orb()
     {
       x = xAxis.nextInt(500);
       y = yAxis.nextInt(500);
       numberX = increaseX.nextInt(2);
       numberY = increaseY.nextInt(2);
      
     }
     
       //this paintComponent method creates the circle
     
     public void paint(Graphics g){
      super.paint(g);
      g.setColor(Color.BLUE);
      g.fillOval( x,  y, 50,50);
    
     }
    
      //this method draws a circle by calling the paintComponent method
     public void run(){
       try{
        
      repaint();
       
       }
       catch(Exception e){}
    
      }


    Yes so, thats how my code looks right now. Is the problem with the complexity of the run() method? Or am I simply missing the bigger picture?

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

    Default

    There are some problems:

    1) What the heck is mainPanel class that you're using?
    2) If you're going to be drawing to Orb, you'd better display it. In other words it needs to be added to the JFrame.
    3) If you're going to be changing the values of Orb fields and using this to draw, then the object having the field changed needs to be the same one as the one being displayed. So you'd better use the same Orb object in your Thread as you display in the GUI.
    4) Don't draw in a JPanel's paint method. Draw in its paintComponent method. And call super.paintComponent(g) first.
    5) If you're going to use a Runnable and a background thread, then you'll likely need a loop such as a while loop in the Runnable and a Thread.sleep(....) in there as well to set the loop's speed. Inside of the loop you change your class's fields (likely x and y in this case), and call repaint().
    6) You almost NEVER ignore exceptions as you are doing here.
    7) You appear to be doing some animations (it would help IMMENSELY) if you gave us a small synopsis of what you're trying to do with this code, what it's goal is.
    8) If so, you are probably better off not using a background thread and Runnable but instead using a Swing Timer.

    For example, my comments begin with //!!


    Java Code:
    import java.awt.Color;
    import java.awt.Graphics;
    import java.util.Random;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class MainFrame extends JFrame {
    
       public static void main(String[] args) {
          JFrame f = new JFrame("POOOOP");
          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          // !! mainPanel m = new mainPanel(); //!! what the hell is "mainPanel"?
          Orb orb = new Orb(); // !! added
          // !! f.add(m);
          f.add(orb);
          //!! Thread t1 = new Thread(new Orb());
          Thread t1 = new Thread(orb); //!!
    
    
          f.setSize(500, 500);
          f.setVisible(true);
          t1.start();
    
       }
    }
    
    class Orb extends JPanel implements Runnable {
    
       // Create random Integers
       Random xAxis = new Random();
       Random yAxis = new Random();
       Random increaseX = new Random();
       Random increaseY = new Random();
       // Assign random integers to Variables
       public int x;
       public int y;
       int numberX;
       int numberY;
    
       // Constructor
       public Orb() {
          x = xAxis.nextInt(100);
          y = yAxis.nextInt(100);
          numberX = increaseX.nextInt(2);
          numberY = increaseY.nextInt(2);
       }
    
       // this paintComponent method creates the circle
    
       public void paintComponent(Graphics g) { //!! draw in paintComponent, not paint
          super.paintComponent(g);  //!! will need to change super's call to reflect this as well
          g.setColor(Color.BLUE);
          g.fillOval(x, y, 50, 50);
    
       }
    
       public void run() {
          try {
             // change x and y in a Timer or background thread
             while ((x + 50 < getWidth() && y + 50 < getHeight())) {
                x++;  // the most basic of animation just to illustrate a point
                y++;
                repaint();
                Thread.sleep(20); 
             }
          } catch (Exception e) {
             //!! almost never ignore exceptions at least print stack trace
             e.printStackTrace(); //!! added
          }
    
       }
    }

  9. #9
    Join Date
    Nov 2010
    Posts
    6
    Rep Power
    0

    Default

    Thanks a lot Fubarable, your critique really helped me understand how to program with Threads.

    I must apologize for forgetting to include my mainPanel class in my code. I will include it in this post.

    The ultimate goal for my app is to have multiple circles moving randomly on the screen simultaneously. With that in mind I tried instantiating multiple objects of the Orb class into multiple threads. Unfortunately, when I run the mainFrame class I only get one orb. Is it because all of the objects have the same x and y value? Here is the code I have now.

    Main Class

    Java Code:
    import javax.swing.JOptionPane;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import java.awt.FlowLayout;
    class mainFrame extends JFrame{
     
        
            public static void main(String[] args){
              
              JFrame f = new JFrame("POOOOP");
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              mainPanel m = new mainPanel();
              f.add(m);
        
              Orb orb1 = new Orb();
              Orb orb2 = new Orb();
              Orb orb3 = new Orb();
              f.add(orb1);
              f.add(orb2);
              f.add(orb3);
              Thread t1 = new Thread(orb1);
              Thread t2 = new Thread(orb2);
              Thread t3 = new Thread(orb3);
              f.setSize(500, 500);
              f.setVisible(true);
              t1.start();
              t2.start();
              t3.start();
      }
    }

    Orb Class

    Java Code:
    import java.awt.*;
    import java.awt.image.ImageObserver;
    import java.text.AttributedCharacterIterator;
    import java.awt.Graphics;
    import javax.swing.*;
    import java.util.Random;
    /**
    * "extends" is the word for inheriting a class
    */
    public class Orb extends JPanel implements Runnable
    {  
      
      //Create random Integers
      Random xAxis = new Random();
     Random yAxis = new Random();
     
     //Assign random integers to Variables
     public int x;
     public int y;
     int numberX;
     int numberY;
     
    
     //Constructor
     public Orb()
     {
       super();
       x = xAxis.nextInt(500);
       y = yAxis.nextInt(500);
      
     }
     
       //this paintComponent method creates the circle
     
     public void paintComponent(Graphics g){
      super.paintComponent(g);
      g.setColor(Color.BLUE);
      g.fillOval( x,  y, 50,50);
    
     }
    
      //this method draws a circle by calling the paintComponent method
        public void run() {
          try {
             // change x and y in a Timer or background thread 
             while ((x + numberX < getWidth() && y + numberY < getHeight())) {
            //Create random integers for random movement.
               Random increaseXadd = new Random();
               Random increaseYadd = new Random();
               Random increaseXsubtract = new Random();
               Random increaseYsubtract = new Random();
               int numberXsubtract = increaseXsubtract.nextInt(4);
               int numberYsubtract = increaseYsubtract.nextInt(4);
               numberX = increaseXadd.nextInt(4)-numberXsubtract;
               numberY = increaseYadd.nextInt(4)-numberYsubtract;
                x+= numberX; 
                y+= numberY;
                repaint();
                Thread.sleep(20); 
             }
          } catch (Exception e) {
             e.printStackTrace(); 
          } 
      
    }
    }
    Main Panel

    Java Code:
    import java.awt.*;
    import java.awt.image.ImageObserver;
    import java.text.AttributedCharacterIterator;
    import java.awt.Graphics;
    import javax.swing.*;
    import java.util.Random;
    
    
    public class mainPanel extends JPanel{
      public mainPanel(){
        setBorder(BorderFactory.createLineBorder(Color.black));
        setBackground(Color.WHITE);
      }
      public Dimension getPreferredSize() {
        return new Dimension(500, 500);
      }
    
          
        }
    So there is my code. I got the circle to move randomly, but if you see the animation it is really sporadic. Do you have any ideas to make the animation smoother? Thanks a lot for the help guys.

  10. #10
    curmudgeon is offline Senior Member
    Join Date
    May 2010
    Posts
    436
    Rep Power
    5

    Default

    Have a look at the layout manager section of the Oracle Swing tutorial. There you will see that JFrame uses BorderLayout as its default layout manager. When you add all these things to the JFrame, you're adding them by default BorderLayout.CENTER and every component added will completely cover any components added previously. So you will only see the last Orb JPanel added and nothing else. A way to fix this is to not have Orb subclass JPanel but instead hold just the logic that your blue disks require and then do all your graphics in one JPanel that holds an ArrayList of Orb objects and draws them.

  11. #11
    DarrylBurke's Avatar
    DarrylBurke is online now Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,300
    Rep Power
    20

    Default

    every component added will completely cover any components added previously. So you will only see the last Orb JPanel added and nothing else.
    Perceptually it doesn't make a difference, but that statement is not strictly correct.

    BorderLayout will only layout the last component added at each constraint. However, as this layout manager ignores any earlier added component, it doesn't change any size that's explicitly set. Try swapping the order of adding the panel and label in this example.
    Java Code:
    import java.awt.Color;
    import java.awt.Dimension;
    import javax.swing.*;
    import javax.swing.border.LineBorder;
    
    public class BorderLayoutOverlay {
    
      public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
    
          public void run() {
            new BorderLayoutOverlay().makeUI();
          }
        });
      }
    
      public void makeUI() {
        JPanel panel = new JPanel();
        panel.setSize(100, 100);
        panel.setBackground(Color.yellow);
        JLabel label = new JLabel("sjdfhlsdk");
        label.setBorder(new LineBorder(Color.red));
        label.setSize(new Dimension(200, 200));
    
        JFrame frame = new JFrame();
        //frame.add(label);
        frame.add(panel);
        frame.add(label);
    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    }
    Note that this is not an endorsement for adding more than one component at the same BorderLayout constraint. Also notice that the earlier added component displays over the one added later (which is sized by the layout).

    db

  12. #12
    Join Date
    Nov 2010
    Posts
    6
    Rep Power
    0

    Default

    Thanks for the replies guys. I've been reading up on layouts, but I still don't understand how they influence multiple instantiations of different objects. Could you guys please elaborate?

Similar Threads

  1. Using Graphics outside of a paint method
    By Catfish1 in forum New To Java
    Replies: 6
    Last Post: 10-26-2010, 08:57 PM
  2. Replies: 5
    Last Post: 10-22-2010, 01:55 PM
  3. Method Graphics.drawString() - Symbol not found
    By km0r3 in forum AWT / Swing
    Replies: 1
    Last Post: 08-27-2010, 02:55 PM
  4. java graphics within main method
    By jforce93 in forum New To Java
    Replies: 4
    Last Post: 02-02-2010, 10:33 PM
  5. Putting your own type in a Set
    By Java Tip in forum java.lang
    Replies: 0
    Last Post: 04-15-2008, 07:32 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
  •