Results 1 to 12 of 12
  1. #1
    diggitydoggz is offline Member
    Join Date
    Dec 2008
    Posts
    55
    Rep Power
    0

    Default drawing to a JPanel

    Hey all, I've been working on a Tetris program and I'm a little rusty with GUI's. Couple this with the fact that I'm using a lot of new concepts that I just learned and what you get is me totally messing up the drawing. Basically my situation here is I'm trying to create an image on a JPanel as a double buffer and then draw it to the JPanel using a Graphics object. Here's the code for those parts:

    Java Code:
     private void gameRender() {
        if(dbImage == null) {
          dbImage = createImage(PWIDTH, PHEIGHT);
        }
     
        dbg = dbImage.getGraphics();
        dbg.setColor(Color.BLACK);
        dbg.fillRect(0, 0, PWIDTH, PHEIGHT);
        
        Tetroid.draw(dbg);
      }
      
      private void paintScreen() {
        try {
          Graphics g = this.getGraphics();
          if((g != null) && (dbImage != null)) {
            g.drawImage(dbImage, 0, 0, null);
          }
          g.dispose();
        }
        catch (Exception e) {
          System.out.println("Graphics context error: " + e);
        }
      }
    I call it from method "startGame", which is called from the constructor:

    Java Code:
    public TetrisPanel() {
        setBackground(Color.white);
        setPreferredSize(new Dimension (PWIDTH, PHEIGHT));
        
        setFocusable(true);
        requestFocus(); //this allows the panel to receive key events.
        startGame();
      }
      
      public void startGame() {
        if(animator == null && !running) {
          animator = new Thread(this);
          animator.start();
        }
        gameRender();
        paintScreen();
      }
    I added this JPanel to my main JFrame here:

    Java Code:
    import javax.swing.*;
    import java.awt.*;
    
    public class Tetris extends JFrame {
      private TetrisPanel tp;
      
      public Tetris() {
        setTitle("Tetris");
        setLayout(new BorderLayout());
        tp = new TetrisPanel();
    
        add(tp, BorderLayout.CENTER);
        repaint();
        pack();
        setResizable(false);
        setVisible(true);
      }
      
      public static void main(String[] args) {
        new Tetris();
      }
    }
    When I run it, no picture shows up (right now I'm just trying to draw a big black rectangle just to test it out) and the try-catch block in the paintScreen method is displaying a null pointer exception?

    Like I said there's a lot of new concepts I'm using here and I confused the hell out of myself debugging - any help would be GREATLY appreciated.
    Last edited by diggitydoggz; 03-05-2009 at 04:08 PM.

  2. #2
    diggitydoggz is offline Member
    Join Date
    Dec 2008
    Posts
    55
    Rep Power
    0

    Default

    bumpbumpbump

  3. #3
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

    Default

    Never use getGraphics for custom painting in Swing. Learn the correct approach here:
    Lesson: Performing Custom Painting (The Java™ Tutorials > Creating a GUI with JFC/Swing)

    db

  4. #4
    marclurr is offline Member
    Join Date
    Mar 2009
    Posts
    8
    Rep Power
    0

    Default

    Hey there. I was having a similar dilemma not so long ago with Swing. You should be overriding the paint method of JPanel, if your TetrisPanel class is extending JPanel, that is. I've attached some trivial code that should show you what I mean. Double buffering is a whole different ball game but isn't impossible. If you need help on this I'd be happy to.

    Here's the code:

    Java Code:
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Graphics;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    
    public class Test {
    
    	static class MyPanel extends JPanel {
    		
    		@Override
    		public void paint(Graphics g) {
    			g.setColor(Color.BLACK);
    			g.drawRect(0, 0, 100, 100)	;
    		}
    	}
    	
    	public static void main(String[] args) {
    		JFrame frame= new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setBounds(100, 100, 200, 200);
    		
    		frame.add(new MyPanel(), BorderLayout.CENTER);
    		frame.setVisible(true);
    		
    	}
    }

  5. #5
    diggitydoggz is offline Member
    Join Date
    Dec 2008
    Posts
    55
    Rep Power
    0

    Default

    Thanks for the replies, guys. I'm aware of both of the options (overriding the paint/paintComponent methods of JPanel) - I'm actually trying out a new method that I learned from Andrew Davison's book "Killer Java Game Programming." I'll paste the rationale behind the gamerender/paintscreen methods, and then show you the code from the example program that I tried to model.

    Here's the excerpt from the book - "Since a a call to repaint() is only a request, it's difficult to know when the repaint has been completed. This means that the sleep time in the animation loop is little more than a guess; if the specified daelay is too long, then the animation speed is impaired for no reason. If the delay is too short, then repaint requests may be queued by the JVM and skipped if the load becomes too large."

    That's why I'm trying to do the actual drawing to the JPanel in a separate method.

    Here are the methods from the book I was trying to emulate:

    Java Code:
    private void gameRender()
      {
        if (dbImage == null){
          dbImage = createImage(PWIDTH, PHEIGHT);
          if (dbImage == null) {
            System.out.println("dbImage is null");
            return;
          }
          else
            dbg = dbImage.getGraphics();
        }
    
        // clear the background
        dbg.setColor(Color.white);
        dbg.fillRect (0, 0, PWIDTH, PHEIGHT);
    
     dbg.setColor(Color.blue);
        dbg.setFont(font);
    
        // report frame count & average FPS and UPS at top left
     // dbg.drawString("Frame Count " + frameCount, 10, 25);
     dbg.drawString("Average FPS/UPS: " + df.format(averageFPS) + ", " +
                                    df.format(averageUPS), 20, 25);  // was (10,55)
    
     dbg.setColor(Color.black);
    
        // draw game elements: the obstacles and the worm
        obs.draw(dbg);
        fred.draw(dbg);
    
        if (gameOver)
          gameOverMessage(dbg);
      }
    Java Code:
    private void paintScreen()
      // use active rendering to put the buffered image on-screen
      { 
        Graphics g;
        try {
          g = this.getGraphics();
          if ((g != null) && (dbImage != null))
            g.drawImage(dbImage, 0, 0, null);
          g.dispose();
        }
        catch (Exception e)
        { System.out.println("Graphics context error: " + e);  }
      } // end of paintScreen()
    Please let me know if you have any input.
    Last edited by diggitydoggz; 03-06-2009 at 02:03 AM.

  6. #6
    marclurr is offline Member
    Join Date
    Mar 2009
    Posts
    8
    Rep Power
    0

    Default

    Okay I see what you're doing now.

    I noticed something in your startGame() method:

    Java Code:
    public void startGame() {
        if(animator == null && !running) {
          animator = new Thread(this);
          animator.start();
        }
        gameRender();
        paintScreen();
    }
    The gameRender() and paintScreen() methods are only going to get called once, I'm guessing you want these to get called for every frame? You need a loop of some kind to keep this process going.

  7. #7
    diggitydoggz is offline Member
    Join Date
    Dec 2008
    Posts
    55
    Rep Power
    0

    Default

    But even if it gets called just once, shouldn't something show up when I run it? That's the thing that's confusing me.

  8. #8
    marclurr is offline Member
    Join Date
    Mar 2009
    Posts
    8
    Rep Power
    0

    Default

    Yeah, perhaps it is drawing it, but then the default paint() method draws over it. I'm trying to do what you're doing to see if I can get it to work, but createImage(int, int) is always returning null for me :\

  9. #9
    marclurr is offline Member
    Join Date
    Mar 2009
    Posts
    8
    Rep Power
    0

    Default

    Okay I managed to find a PDF of that document you're reading, by any chance have you included this override?

    Java Code:
    public void paintComponent(Graphics g)
    {
    super.paintComponent(g);
    if (dbImage != null)
    g.drawImage(dbImage, 0, 0, null);
    }
    This basically takes your buffered image and draws it to the screen with the graphics object passed in..

  10. #10
    diggitydoggz is offline Member
    Join Date
    Dec 2008
    Posts
    55
    Rep Power
    0

    Default

    Where did you find that code? The reason I ask is because the code that I am looking at doesn't draw the dbImage in a paintComponent method - it doesn't have a paintComponent method at all, it just draws it in the paintScreen method that I pasted above.

  11. #11
    diggitydoggz is offline Member
    Join Date
    Dec 2008
    Posts
    55
    Rep Power
    0

    Default

    Also based on my testing code, the Image is not null and the image is being drawn. The only mystery to me is why it isn't showing up.

  12. #12
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

    Default

    See #3 and go through the tutorial linked. Or don't, if you find it more fun to muddle along.

    db

Similar Threads

  1. Looking for help on drawing stuff in a jPanel
    By Gatts79 in forum AWT / Swing
    Replies: 3
    Last Post: 08-28-2009, 07:00 PM
  2. Drawing points on a JPanel
    By josephdcoleman in forum New To Java
    Replies: 6
    Last Post: 02-25-2009, 04:47 PM
  3. Drawing a map
    By Karp in forum AWT / Swing
    Replies: 4
    Last Post: 11-07-2008, 01:26 PM
  4. Help with 2-D Drawing
    By Deathmonger in forum New To Java
    Replies: 4
    Last Post: 06-18-2008, 03:23 AM
  5. X&Y Coordinate Drawing on jPanel
    By BHCluster in forum Java 2D
    Replies: 2
    Last Post: 03-27-2008, 11:47 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
  •