Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (109)
games submitted by our members
Games in WIP (536)
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  
  repaint with swing - paintComponent method never gets called...  (Read 2940 times)
0 Members and 1 Guest are viewing this topic.
Offline _Spare_Ribs_

Junior Newbie




meep meep


« Posted 2007-08-19 23:14:17 »

Hi all,

New to this forum so this is my first post! I'm fairly new to Java game programming so I thought I would start myself off with a nice 2D game based around awt/swing components. I'm having problems calling the paintComponent method in one of my classes. I make a call to repaint() which makes a call to paint which then invokes paintComponent, if my understanding is correct. I therefore placed my paint code inside the overriden method paintComponent. However, when repaint is called, no call to paintComponent is made in the subclass, or parent class for that matter. I inserted break points into my code at the line where repaint is called and it the first line of my paintComponent method and then debugged the project in JBuilder which also confirmed the paintComponent method was not being called. Here is a copy of the class in question. As you can see it extends a class called GameWindow (which extends JPanel) which has its own paintComponent method.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
class DealCards extends GameWindow{
    private static final long serialVersionUID = 1L;
    private static Logger log = Logger.getLogger(GameWindow.class.getName());
    private Rectangle startRect;
    private Rectangle compRect;
    private Rectangle playerRect;
    private int x;
    private int y;
    private final double SPEED = 19.0; // speed of cards
   private final long DELAY = 5; // delay between cards
   private final int MAX_CARDS = 9; //cards to deal in the sequence
   private int lastCard;
    private int currentCard;
    private int nextCard;
    private int startx = 200;
    private int starty = 175;
    private int comprx = 180;
    private int compry = 175;
    private int playerrx = 20;
    private int playerry = 367;
    private int count = 0;
    private boolean bPlayerMove = true;
    private boolean bCompMove = true;
    private boolean bDealing = false;
    private boolean bShufflingIsDone = false; // use later
   final private static String images_prefix = "C:/Documents and Settings/Paulo/jbproject/Canasta_Game/src/images/";

    BufferedImage nextcard1 = loadImage2(images_prefix + "card0.gif");
    BufferedImage currentcard1 = loadImage2(images_prefix + "card1.gif");
    BufferedImage lastcard1 = loadImage2(images_prefix + "card2.gif");

    public BufferedImage loadImage2(String name2){
        try {
            log.debug("ImageIO string is " + ImageIO.read(new File(name2)));
            BufferedImage im = ImageIO.read(new File(name2));
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            int transparency = im.getColorModel().getTransparency();
            BufferedImage copy = gc.createCompatibleImage(im.getWidth(), im.getHeight(), transparency );
            Graphics2D g2d = copy.createGraphics();
            g2d.drawImage(im, 0, 0, null);
            g2d.dispose();
            return copy;
        } catch (IOException ex) {
            log.error("Load image error: " + ex);
            new ErrorWindow(ex.toString(), getClass().toString());
            return null;
        }
    }

    public void shuffleWait2() {
        log.debug("SHUFFLEWAIT2 CALLED");
        Thread shuffleThread = new Thread(shuffler2);
        shuffleThread.setPriority(Thread.NORM_PRIORITY);
        shuffleThread.start();
    }

    private void initRects() {
        int cardw = 70;
        int cardh = 100;
        startRect = new Rectangle(startx, starty, cardw, cardh);
        compRect = new Rectangle(comprx, compry, cardw, cardh);
        playerRect = new Rectangle(playerrx, playerry, cardw, cardh);
        this.x = startRect.x;
        this.y = startRect.y;
    }

    public void dealCard2() {
        start();
    }

    public void dealCards2() {
        log.debug("DEALCARDS2 CALLED");
        if(!bDealing) {
            new SoundApplet2("Deal.wav");
            Thread dealThread = new Thread(dealer);
            dealThread.setPriority(Thread.NORM_PRIORITY);
            dealThread.start();
        }
    }

    public void run() {
        while(bDealing) {
            try {
                Thread.sleep(DELAY);
            } catch (InterruptedException ex) {
                log.error("Dealing thread interrupted");
                new ErrorWindow(ex.toString(), getClass().toString());
                stop();
            }
            boolean finished = advanceCard2();
            if(finished) {
                stop();
            }
        }
    }

    public void start() {
        if(!bDealing) {
            next2();
            count = 0;
            bDealing = true;
            thread = new Thread(this);
            thread.setPriority(Thread.NORM_PRIORITY);
            thread.start();
        }
    }

    private void stop() {
        bDealing = false;
        if(nextCard == MAX_CARDS) {
            bShufflingIsDone = true;
        }
        if(thread != null)
            thread.interrupt();
        thread = null;
    }

    private boolean advanceCard2() {
        Point p1 = startRect.getLocation();
        Point p2 = playerRect.getLocation();
        Point p3 = compRect.getLocation();
        if(bPlayerMove) {
            double distance = p1.distance(p2);
            double d = ++count * SPEED;
            double x = p1.x + d;
            if (d > distance)
                x -= d - distance;
            moveCard2(x, p1.y);
            bCompMove = true;
            bPlayerMove = false;
            return d > distance;
        }
        if(bCompMove) {
            double distance = p1.distance(p3);
            double d = ++count * SPEED;
            double x = p1.x + d;
            if (d > distance)
                x -= d - distance;
            moveCard2(x, p1.y);
            bPlayerMove = true;
            bCompMove = false;
            return d > distance;
        }
        return true;
    }

    public void moveCard2(double x, double y) {
        this.x = (int)x;
        this.y = (int)y;
        //repaint(145,175,220,100);
       repaint();
    }

    public void next2() {
        if(nextCard+1 > 9)
            resetCards2();
        lastCard = currentCard;
        currentCard = nextCard;
        nextCard++;
        if(startRect == null)
            initRects();
        GameWindow.card_count--; // as we deal a card we take one off the stack
       x = startRect.x;
        y = startRect.y;
        log.debug("card_count is " + GameWindow.card_count);
    }

    public void resetCards2() {
        lastCard = -2;
        currentCard = -1;
        nextCard = 0;
        //repaint(145,175,220,100);
       repaint();
    }

    Runnable shuffler2 = new Runnable() {
        public void run() {
            log.debug("SHUFFLER2 RUNNER CALLED");
            int count = 0;
            for(; count < 1;){
                try {
                    log.debug("Sleep for 500ms");
                    Thread.sleep(500);
                    dealCards2();
                    count++;
                } catch (InterruptedException ex) {
                    log.error("runner thread error " + ex);
                    new ErrorWindow(ex.toString(), getClass().toString());
                }
            }
        }
    };

    Runnable dealer = new Runnable() {
        public void run() {
            int count = 0;
            final int WAIT_FOR_END_OF_DEAL = 50;
            while(count++ < MAX_CARDS) {
                dealCard2();
                while(bDealing) {
                    try {
                        Thread.sleep(WAIT_FOR_END_OF_DEAL);
                    } catch(InterruptedException ex) {
                        log.error("runner thread error " + ex);
                        new ErrorWindow(ex.toString(), getClass().toString());
                        stop();
                    }
                }
            }
        }
    };

    protected void paintComponent(Graphics g){
        if (bDealing) {
            try {
                Graphics2D g2 = (Graphics2D) g;
                log.debug("draw a card");
                g2.drawImage(nextcard1, startRect.x, startRect.y, this);
                if (lastCard > -1) {
                    g2.drawImage(lastcard1, playerRect.x, playerRect.y, this);
                    g2.drawImage(lastcard1, compRect.x, compRect.y, this);
                }
                if (currentCard > -1)
                    g2.drawImage(currentcard1, x, y, this);
            } catch (Exception ex) {
                log.error("Exception " + ex.toString());
                new ErrorWindow(ex.toString(), getClass().toString());
            }
        }
    }
}


I'm guessing this is probably a fairly straight forward question. I read the following article http://java.sun.com/products/jfc/tsc/articles/painting/index.html and I seem to be following everything that they say on here so I'm not sure what I'm doing wrong. The only way I can get it to work is if I put all this code into the GameWindow class but it's getting quite big and so is the paintComponent method in it so I would like to break the classes down into parts that all perform seperate actions of the game to make it easier to understand.

Thanks.

"Some days you're the bird and some days you're the statue."
Offline Kova

Senior Member





« Reply #1 - Posted 2007-08-20 01:00:20 »

your calling hierarchy guess is correct... repaint() calls paintComponent() but only not instantly, as fast as it can...
maybe your bDealing is false always? Put some output before it to check this and if paintComponent() really gets called, you don't need debugger...
one more thing that could make paintComponent() not get called is that you never added it to a visible container... also check if repaint() really gets called by putting some output before it.
Offline _Spare_Ribs_

Junior Newbie




meep meep


« Reply #2 - Posted 2007-08-20 02:25:03 »

ok i modified the moveCard2 and paintComponenet methods to the following so some more output would be displayed:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
    public void moveCard2(double x, double y) {
        this.x = (int)x;
        this.y = (int)y;
        //repaint(145,175,220,100);
       log.debug("about to call repaint from moveCards2");
        log.debug("value of bDealing is " + bDealing);
        repaint();
        log.debug("repaint called from moveCards2");
    }

    protected void paintComponent(Graphics g){
        log.debug("inside DealCards paintComponent method");
        log.debug("value of bDealing is " + bDealing);
        if (bDealing) {
            try {
                Graphics2D g2 = (Graphics2D) g;
                log.debug("draw a card");
                g2.drawImage(nextcard1, startRect.x, startRect.y, this);
                if (lastCard > -1) {
                    g2.drawImage(lastcard1, playerRect.x, playerRect.y, this);
                    g2.drawImage(lastcard1, compRect.x, compRect.y, this);
                }
                if (currentCard > -1)
                    g2.drawImage(currentcard1, x, y, this);
            } catch (Exception ex) {
                log.error("Exception " + ex.toString());
                new ErrorWindow(ex.toString(), getClass().toString());
            }
        }
    }


so now in my log i just see the following:

2007-08-20 01:13:15,406 [GameWindow.java] DEBUG - about to call repaint from moveCards2 (Thread-27)
2007-08-20 01:13:15,406 [GameWindow.java] DEBUG - value of bDealing is true (Thread-27)
2007-08-20 01:13:15,406 [GameWindow.java] DEBUG - repaint called from moveCards2 (Thread-27)

and nothing more. As for your point about a visivle container, well this could be where I have made the mistake. My assumption (probably wrong) is that GameWindow extends JPanel and therefore by DealCards extending GameWindow it would therefore be extending JPanel too since the paintComponent method works fine in the GameWindow class.  Huh

"Some days you're the bird and some days you're the statue."
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline broumbroum

Junior Member





« Reply #3 - Posted 2007-08-20 04:42:40 »

hello!
I think you missed the MediaTracker to get synched with the loading of your bufferedImage. Plus I'd put the log for "repaint called", quoting your code, in the paintComponent() method which will better reflect to time when the painting is actually made.
That is the point, each time you want to draw a new Image, add it to the MediaTracker and wait for it to load completely before to start rendering ! Cheesy
MediaTracker javadoc

::::... :..... :::::: ;;;:::™ 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 _Spare_Ribs_

Junior Newbie




meep meep


« Reply #4 - Posted 2007-08-20 18:47:52 »

The MediaTracker is not essential, all it does is ensure the image is loaded before it attempts to draw it and provides you with a way of prioritising the order in which images are loaded.

My problem is that the paintComponent method is not even being called. I have a line in the loadImage method which displays a line of output to my log file when an image is loaded, also in my loadImage method you can see the image is drawn and then dispose is called so this is not the problem.

My GameWindow class uses the same methodology, eg, same loadImage function with paintComponent method and this works fine.

Regardless of where I put my output lines, the fact is when I debug in JBuilder and step into every function called the paintComponent method is never called and as you can see from the output, the value of bDealer is true.

"Some days you're the bird and some days you're the statue."
Online Abuse

JGO Coder


Medals: 11


falling into the abyss of reality


« Reply #5 - Posted 2007-08-20 19:05:43 »

What top-level Container are you placing the JPanel into?

If it isn't a JFrame, JDialog, or JApplet (or JWindow), then that is the cause of your problem.

http://java.sun.com/docs/books/tutorial/uiswing/components/toplevel.html

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline _Spare_Ribs_

Junior Newbie




meep meep


« Reply #6 - Posted 2007-08-20 20:12:30 »

a JFrame initiated in my Main class

"Some days you're the bird and some days you're the statue."
Offline Kova

Senior Member





« Reply #7 - Posted 2007-08-20 22:48:01 »

hmm... are you sure you are overriding it? Maybe method from super class has public modifier and not protected? Didn't ever tried that so I don't know if it matters.
Well you said it already works for GameWindow so this doesn't matter...

Also, you cannot go into paintComponent() while debugging because paintComponent() is called from AWT-Swing thread (EDT?), it isn't called from repaint() in your thread. Repaint() only queues call to paintComponent() in Swing thread.

I don't know how we can help you anymore... make sure that it's visible (setVisible(true)) and that is added to a visible container.

If you don't solve it, instead if this build simplest JPanel with custom painting and try to implement it. If it works then build it little by little to your class.
Online Abuse

JGO Coder


Medals: 11


falling into the abyss of reality


« Reply #8 - Posted 2007-08-20 23:04:50 »

Does your super-class GameWindow override paint(Graphics) or update(Graphics) ?

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline _Spare_Ribs_

Junior Newbie




meep meep


« Reply #9 - Posted 2007-08-20 23:52:37 »

In reply to Kova, the paintComponenent method in my super class is set to protected too. The JFrame state is visible and other calls to paintComponent from GameWindow are executed and drawn in the JPane.

In reply to Abuse, GameWindow only overrides paintComponent

"Some days you're the bird and some days you're the statue."
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline broumbroum

Junior Member





« Reply #10 - Posted 2007-08-21 00:06:30 »

I'd be surprised that your GameWindow doesn't paint at all if you were actually calling the repaint() in one main Thread, but I can distiguish that the start() method does invoke the Runnable that is defined with the run(). Then you must have the call to repaint() written in one of those 2 methods, which is obviously not the case. Would you check for that?  Huh

::::... :..... :::::: ;;;:::™ 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 Kova

Senior Member





« Reply #11 - Posted 2007-08-21 00:38:57 »

In reply to Kova, the paintComponenent method in my super class is set to protected too. The JFrame state is visible and other calls to paintComponent from GameWindow are executed and drawn in the JPane.

how about size? Did you set the size?
edit: clarification, maybe you are using null layout manager and in that case you need to set size and position manually as I remember or they will be zero and paintComponent() wouldn't get called (?) ... try to do it manually
Offline _Spare_Ribs_

Junior Newbie




meep meep


« Reply #12 - Posted 2007-08-21 02:06:44 »

my main JFrame has the setSize attribute set, no setLocation but it renders fine....... as for the call to repaint in the start/run method, I tried placing it in there and still no joy.

I'm feeling rather like that animated gif you see around the internet every now and then of the stick man bashing his head against the keyboard!  Cheesy

"Some days you're the bird and some days you're the statue."
Offline Kova

Senior Member





« Reply #13 - Posted 2007-08-21 09:30:09 »

my main JFrame has the setSize attribute set, no setLocation but it renders fine....... as for the call to repaint in the start/run method, I tried placing it in there and still no joy.

I wasn't talking about JFrame, I was talking about your container and DealCards. Everything must be visible, put setVisible(true) just in case for every component. By default if you make JFrame visible then all children will be visible, but if you used some unstandard layout manager as null layout manager then you have to set sizes manually, I'm not talking about JFrame but for container.

edit: here's a simple example, if you uncomment any setVisible(false) or setLayout(null) the button will not appear

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ComponentVisibility extends JFrame {
   
    JPanel container = new JPanel();
    JButton button = new JButton("test");
   
    public ComponentVisibility() {
        super("Component Visibility");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setBounds(200,200,300,400);
        setContentPane(container);
//        container.setLayout(null);
       container.add(button);
//        container.setVisible(false);
//        button.setVisible(false);
       setVisible(true);
    }
   
    public static void main(String[] args) {
        new ComponentVisibility();
    }

}
Offline _Spare_Ribs_

Junior Newbie




meep meep


« Reply #14 - Posted 2007-08-23 23:09:59 »

In the end I could only get it to work when I merged the DealCards class code with the GameWindow class code..... oh well. Now to have fun getting the cards to be dealt to the correct places on the table!  Grin

"Some days you're the bird and some days you're the statue."
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.

CogWheelz (18 views)
2014-07-30 21:08:39

Riven (25 views)
2014-07-29 18:09:19

Riven (15 views)
2014-07-29 18:08:52

Dwinin (12 views)
2014-07-29 10:59:34

E.R. Fleming (33 views)
2014-07-29 03:07:13

E.R. Fleming (12 views)
2014-07-29 03:06:25

pw (43 views)
2014-07-24 01:59:36

Riven (43 views)
2014-07-23 21:16:32

Riven (30 views)
2014-07-23 21:07:15

Riven (31 views)
2014-07-23 20:56:16
List of Learning Resources
by SilverTiger
2014-07-31 18:29:50

List of Learning Resources
by SilverTiger
2014-07-31 18:26:06

List of Learning Resources
by SilverTiger
2014-07-31 13:54:12

HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54
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!