0

I'm trying to learn how to do custom GUI stuff in Java for a group project I'm working on. I've done user form type GUIs in the past so I know the gist of what I'm doing here, but the custom drawing stuff still confuses me.

I copied this code from online and I've been trying to figure out how it works, but I don't get why I can't loop the drawing method. As a simple test I'm trying to make the program draw an oval on my cursor. It draws the oval on the cursor, but only once on runtime and then does nothing.

How can I make this loop so I can continue to draw things? Or is there a different way I need to call/use the methods?

public class BombermanGUI extends JFrame {
   public static final int CANVAS_WIDTH  = 640;
   public static final int CANVAS_HEIGHT = 480;

   private DrawCanvas canvas;

   public BombermanGUI() {
      canvas = new DrawCanvas();  
      canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));

      Container cp = getContentPane();
      cp.add(canvas);

      this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
      this.pack();             
      this.setTitle("......"); 
      this.setVisible(true);    
   }

   private class DrawCanvas extends JPanel{
      @Override
      public void paintComponent(Graphics g){
         super.paintComponent(g);  
         setBackground(Color.BLACK); 

         int x, y;
         x = MouseInfo.getPointerInfo().getLocation().x - this.getLocationOnScreen().x;
         y = MouseInfo.getPointerInfo().getLocation().y - this.getLocationOnScreen().y;
         g.setColor(Color.YELLOW);    
         g.drawOval(x, y, 10, 10);

      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            new BombermanGUI(); 
         }
      });
   }
}
Nat
  • 890
  • 3
  • 11
  • 23
  • 1
    Either add an event listener and have it call the `repaint` method, e.g. a mouse motion listener for tracking your mouse cursos, or have some thread run your game and trigger `repaint` in regular intervals. – tobias_k Sep 07 '14 at 15:59
  • Whoops I screwed up the code a bit when removing unneccesary bits, ill fix it now – Nat Sep 07 '14 at 16:01
  • Also look at [TimerBasedAnimation](http://www.java2s.com/Tutorial/Java/0240__Swing/Timerbasedanimation.htm) for ideas. – DavidPostill Sep 07 '14 at 16:02
  • [How can I make a Java Swing animation smoother](http://stackoverflow.com/questions/15511282/how-can-i-make-a-java-swing-animation-smoother) – DavidPostill Sep 07 '14 at 16:03
  • Ahh repaint is what I was looking for, that should solve my problem. Thanks for the suggestion davidpostill. No answers so I can't select best answer... – Nat Sep 07 '14 at 16:05

2 Answers2

2

Painting a complex series of callbacks and responses to changes within the system. The first thing to remember is that you don't control the painting process, but rather make suggestions to the system so that it can make decisions about what and when it should repaint...

Take a look at Painting in AWT and Swing and Performing Custom Painting for more details.

Painting is a destructive process. It is assumed that when a repaint occurs, that you will repaint the entire state of the current component. This means that you will need some kind of model which maintains all the content that needs to be painted...

Have a look at 2D Graphics, in particular, have a look at the section on Shape

MouseInfo is a seriously crappy way to detect the location of the mouse for this purpose, instead, you should be using a MouseListener and/or MouseMotionListener to detect mouse events.

Basically, when the user presses a mouse button, you would record the location of the mouse press. When the mouse is moved, you would calculate the width and height of the movement relative to the mouse press and update the "current" shape. You would call repaint to request that the UI be updated and paint this shape via the paintComponent method (painting all the previous shapes first).

When the mouse button is released, you would commit the "current" shape to the model, so it will be painted every time paintComponent is called.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Wow, thats a hell of a lot to wrap my head around. Luckily I have time to figure this all out though, thanks – Nat Sep 08 '14 at 00:39
  • @user2856410 Conceptually, it's really simple (no offense, I know it seems really complicated), the problem is, it's a non-linear problem as you are running in an event driven environment, so you need to maintain "stateful" details from one event to the next, which don't always relate directly – MadProgrammer Sep 08 '14 at 00:51
0

THIS IS tobais_k ANSWER IM ANSWERING TO CLOSE THE QUESTION!

Either add an event listener and have it call the repaint method, e.g. a mouse motion listener for tracking your mouse cursos, or have some thread run your game and trigger repaint in regular intervals.

PsyCode
  • 644
  • 5
  • 14