Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (522)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (590)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Drawing on a JPanel, repaint request ignored.  (Read 2222 times)
0 Members and 1 Guest are viewing this topic.
Offline stef569

Junior Devvie





« Posted 2007-09-12 14:38:08 »

Hi, I've split logic from drawing  Grin with controller view model.

so in the class of my JPanel ControlPanel
I have

Game_Interface :
LEFT_MARGIN = 10;
CONTROL_PANEL_WEIGHT = 250;
PANEL_HEIGHT = 150;

public class ControlPanel extends JPanel  implements Game_Interface {

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
  protected void paintComponent(Graphics g) {
    // paint frame contents first...
    super.paintComponent(g);
    // then, make sure lightweight children paint
    g.drawString("Next Piece:", LEFT_MARGIN,18);
    g.drawString("Move with the ArrowKeys", LEFT_MARGIN, 300);
    g.drawString("Drop: Down ArrowKey", LEFT_MARGIN, 320);
    g.drawString("Glide: Spacebar", LEFT_MARGIN, 340);
    g.drawString("Pauze: P", LEFT_MARGIN, 360);
  }


1  
2  
3  
  public Dimension getPreferredSize() {
    return new Dimension(CONTROL_PANEL_WEIGHT, PANEL_HEIGHT);
  }


and the problem occurs here:
1  
2  
3  
4  
5  
  public void draw_Score(int score, Graphics2D g) {
    g.setColor(Color.BLACK);
    repaint(LEFT_MARGIN, 150,150,80);
    g.drawString("Score: " + score, LEFT_MARGIN, 150);
  }


1. I'm trying to repaint (erase to default background) a pixel rectangle
2. draw a text (the score)

at the moment the second score overlaps the first score. It's Ignoring my repaint request!
I alsoo would like to add the draw_Score into the paintComponent BUT then i need to store the score and the JPanel shouldn't know what the score is?

I'm thinking/ Doing something wrong?
Offline Ask_Hjorth_Larsen

Junior Devvie




Java games rock!


« Reply #1 - Posted 2007-09-12 16:46:30 »

A call to the repaint method makes sure that a repaint request is appended to the swing event queue. Swing constantly dispatches events from the eventqueue, eventually reaching the repaint request. However, you draw the string right after the repaint call, meaning that the repainting will be performed AFTER you have drawn the string. This is your problem.

The solution involves making sure that no drawing operation (by drawing operations I mean method calls on Graphics objects, as opposed to, say, repaint() requests) takes place outside of the paintComponent method, which is the normal way to do things (unless you want to draw on an image buffer or something). Throwing Graphics2D objects around OUTSIDE the paintComponent method is sure to cause trouble. Also, for the sake of things being easy, just call repaint() without any argument. If the game gets sluggish, you can worry about limiting the repaint rectangle at some other time.

As for your last question, the JPanel might not need to know what the score is, but it could call a method which *returns* the score every time it is drawn, i.e. something like game.getScore(). That way the panel will just have to know one object which takes care of the game-related stuff such as scoring.
Offline stef569

Junior Devvie





« Reply #2 - Posted 2007-09-12 17:46:51 »

Thx  for the excellent reply Ask_Hjorth_Larsen Smiley
I understand what I done wrong. Grin

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
  /**
   * Tells the controller what to draw.
   */

  private void paintScreen() {

    if( board != null)
      controller.draw_GameBoard(board);

    if( showFPS )
      controller.draw_FPS(usedTime);

    if( quit )
      controller.draw_Message(Color.RED, "Game Over");

    if( showStartScreen())
      controller.draw_Message(Color.GREEN, "Welcome, fancy a quick game?");
}


But to folow the model - view - controller thing
I realy have to give arguments to the controller and then the controller passes them through to the JPanel. At least I think  Huh
So I have 2 options:

Wrap all my custom functions into the paintComponent function as in Huh but it's not allowed to call it directly (have to use repaint)

1  
2  
3  
4  
5  
6  
7  
  protected void paintComponent(Graphics g, Color col1, String msg,Color scoreCol, int score ) {
    super.paintComponent(g);
    g.setColor(col1);
    g.drawString("Next Piece:", LEFT_MARGIN,18);
    g.setColor(scoreCol);
    g.drawString("Score: " + score, LEFT_MARGIN, 150);
  }


or I make a bufferImage and paint on that
and when I'm finished I would call repaint() and draw the bufferImage?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Ask_Hjorth_Larsen

Junior Devvie




Java games rock!


« Reply #3 - Posted 2007-09-12 23:04:04 »

First of all, about MVC: it wouldn't be necessary to use the controller for any communication between view and model. You will want the view to have direct access to the model, since the view is likely a graphical representation of (some of the) model. See the graph here: http://en.wikipedia.org/wiki/Model-view-controller .

The controller should basically handle the way in which user input affects the model. E.g. when the user presses 'space', the controller adds a 'missle' object somewhere in the model, or something similar. Thus, the paintScreen() method would have something to do with the *view*, not the controller - something like view.drawGameBoard, view.drawFPS, etc. (The underscore, by the way, is against java naming conventions).

I notice that there are some extra arguments in the paintComponent method you listed. When a repaint event is resolved by swing, it will call paintComponent(Graphics), and any method with the name paintComponent which accepts a different set of parameters will NOT be invoked.

You could do something like

1  
2  
3  
4  
5  
6  
7  
protected void paintComponent(Graphics g){
  super.paintComponent(g);
  if(showScore){
    int score = model.getScore();
    g.drawString(.... appropriate arguments ... )
  }
}


You could also use an image as a buffer, true, but at present I think you should just get used to the way swing works and not care about the other stuff.
Offline stef569

Junior Devvie





« Reply #4 - Posted 2007-09-14 12:29:57 »

I understand Smiley

I changed everything, and now the view only get's painted when Swing thinks it's needed (minimize, maximize, other screen before part of the view)
I understand why, and how to solve it (I need to call repaint) but
How would I call the repaint() from the model game.run loop

Should I set a boolean when there should be a repaint
then some sort of loop that checks when to repaint inside the view
and when we repainted set the boolean back to false?

or just put repaint() in the paintComponent method?
or some other way Huh

I'm nearly there  Grin
thanks for the help already given realy appriciated  Wink
Offline broumbroum

Junior Devvie





« Reply #5 - Posted 2007-09-14 22:20:02 »

simply call repaint() as required by swing and wait for the component to refresh its content. DON'T put the repaint() call in the paintComponent() block, otherwise you'll get an undesirable infinite loop. That is, repaint() sends an update-is-required-event to Swing which will satisfy the request as soon as possible by calling the update() component method.
Usually, there's a steady RepaintManager instance that is intended to check which are the part of the component to be actually repainted. These fonctions check for any a.k.a "dirty regions" to repaint. Cheesy

::::... :..... :::::: ;;;:::™ b23:production 2006 GNU/GPL @ http://b23prodtm.webhop.info
on sf.net: /projects/sf3jswing
Java (1.6u10 plz) Web Start pool
dev' VODcast[/ur
Offline stef569

Junior Devvie





« Reply #6 - Posted 2007-09-15 17:46:00 »

simply call repaint() as required by swing  Huh  => MVC model doesn't know the view...
all my paint functions are within the paintComponents method.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
  /**
   * Custom PaintComponent Method
   * @param g Graphical Context
   */

  protected void paintComponent(Graphics g) {
    // paint Frame contents first...
    super.paintComponent(g);

    Graphics2D g2D = (Graphics2D) g;

    if( canShowStartScreen())
      drawMessage(Color.GREEN, "Welcome", g2D);
  }


1  
2  
3  
4  
5  
6  
7  
8  
9  
  private void drawMessage(Color col, String msg, Graphics2D g) {
    Dimension size = getSize();
    if (col == null)
      g.setColor(Color.WHITE);
    else
      g.setColor(col);

    g.drawString(msg, 55, (float) size.getHeight()/2);
  }


It goes to the method once, when building the gui.
Then It only draws when Swing dirty regions come in.

When I add repaint to paintComponent  Cheesy I get 99% cpu usage doh  Lips Sealed
I need to tell swing to repaint whilst not knowing about the view... sounds....like trouble Roll Eyes
Offline broumbroum

Junior Devvie





« Reply #7 - Posted 2007-09-15 19:31:17 »

try not to call super.paintComponent when you paint a frame (you'll certainly loose the graphics access) ! Plus, verify that the messages you want to display are on their correct positions when you make calculations, like width divided, that means to log the args to std console output, too !
That be my recommandations. Cheesy

::::... :..... :::::: ;;;:::™ b23:production 2006 GNU/GPL @ http://b23prodtm.webhop.info
on sf.net: /projects/sf3jswing
Java (1.6u10 plz) Web Start pool
dev' VODcast[/ur
Offline stef569

Junior Devvie





« Reply #8 - Posted 2007-09-18 20:59:00 »

Quote
try not to call super.paintComponent when you paint a frame (you'll certainly loose the graphics access)
I paint inside a JPanel

The calculations aren't finished yet Wink

but my question still stands!
Offline JAW

Senior Devvie


Medals: 2



« Reply #9 - Posted 2007-09-19 13:22:46 »

1) Maybe you want to use active drawing and not passive drawing. There is sample code in the net for JFrame using BufferStrategy and such stuff to get a graphics from the frame and actively draw on it.

2) You need to call all drawing in the paint method, so showScore must be called from paint or be inlined.

-JAW
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline stef569

Junior Devvie





« Reply #10 - Posted 2007-09-19 20:42:04 »

Thx.

The solution was to use an EventHandler
http://java.sun.com/j2se/1.4.2/docs/api/java/beans/EventHandler.html

from http://www.ibm.com/developerworks/java/library/j-tetris/

btw I highly suggest looking and learning from the given source above for novice game devs who are just starting
as it is extremly clean and nicely done everything conform the java guidelines.

Nice Job Scott!
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

trollwarrior1 (33 views)
2014-11-23 06:13:56

xFryIx (73 views)
2014-11-14 06:34:49

digdugdiggy (52 views)
2014-11-13 15:11:50

digdugdiggy (46 views)
2014-11-13 15:10:15

digdugdiggy (40 views)
2014-11-13 15:09:33

kovacsa (65 views)
2014-11-08 13:57:14

TehJavaDev (69 views)
2014-11-04 16:04:50

BurntPizza (67 views)
2014-11-04 12:54:52

moogie (82 views)
2014-11-04 00:22:04

CopyableCougar4 (82 views)
2014-11-02 17:36:41
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-10 16:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-03 16:36:02

List of Learning Resources
by Longor1996
2014-08-17 04:40:00

List of Learning Resources
by SilverTiger
2014-08-06 13:33:27

Resources for WIP games
by CogWheelz
2014-08-02 10:20:17

Resources for WIP games
by CogWheelz
2014-08-02 10:19:50

List of Learning Resources
by SilverTiger
2014-08-01 10:29:50

List of Learning Resources
by SilverTiger
2014-08-01 10:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!