java - Reference of graphics 2d object doesn't work in orphan Thread -


i trying design simple game using graphics2d in jpanel. able draw normal objects overriding paintcomponent() method. when reference graphics2d object inside orphan thread, not work. going wrong?

public void paintcomponent(graphics g) {      super.paintcomponent(g);     g2d = (graphics2d) g;      g2d.drawstring("sample",60,100); //works fine      if(<certain condition>){        new thread(new runnable(){             //some code here             public void run() {                try{                  g2d.drawstring("sample2",60,100); //does not work.. :(                  system.out.println("test print"); //shows output                }                catch (exception e)                {                }              }        }).start();    } } 

here complete code reference. 'ping pong ball' game. working not able highlight increase in score when ball hits striker. important part of code highlighted. it's sscce.

import java.awt.*; import java.awt.event.*; import javax.swing.*;  import java.util.random;  public class movingball extends jpanel {     int xpos, ypos;     int speedx, speedy;     int diameter;     private jbutton jbutton1 = new jbutton();     private jbutton jbutton2 = new jbutton();     private jlabel jlabel1 = new jlabel();     private static timer timer;     private static movingball movingball;     private int w,h;      private int strikerheight;     private int strikerwidth;      private int score;     private boolean isballmoving;      int strikerypos;     graphics2d g2d;      public movingball() {          //striker properties         strikerheight = 100;         strikerwidth = 20;         strikerypos = strikerheight/2;          //ball properties         isballmoving = false;         xpos = strikerwidth + 5;         ypos = 0;         random r = new random();         speedx = 2+ math.abs(r.nextint()) % 5;         speedy = 2+ math.abs(r.nextint()) % 5;         diameter = 50;          //ui objects         try {             jbinit();         } catch (exception e) {             e.printstacktrace();         }          movingball = this; //helps access current class object in inner classes          //create timer animation         timer = new timer(1, new actionlistener() {             public void actionperformed(actionevent evt) {                 movingball.repaint();             }             });         timer.start();     }      public void paintcomponent(graphics g) {          super.paintcomponent(g);         g2d = (graphics2d) g;          dimension size = getsize();         insets insets = getinsets();          w =  size.width - insets.left - insets.right;         h =  size.height - insets.top - insets.bottom;          //paint striker         g2d.setcolor(color.dark_gray);         if(strikerypos < strikerheight/2) //top end             g2d.fillrect(0,0, strikerwidth, strikerheight);         else if(strikerypos > (h-strikerheight/2)) //bottom end             g2d.fillrect(0,h-strikerheight, strikerwidth, strikerheight);         else //anywhere in middle             g2d.fillrect(0,strikerypos - (strikerheight/2), strikerwidth, strikerheight);          //paint ball         if (isballmoving) {             xpos += speedx;             ypos += speedy;              g2d.drawoval(xpos, ypos, diameter,diameter);              if((xpos+diameter) >= w)             {                 //speedx *= -1;                 speedx = ((int)math.signum((double)speedx))*(-1) * (2+ math.abs(new random().nextint()) % 5);                 xpos = w-diameter-1;             }             if(xpos <= strikerwidth)             {                 if((ypos+diameter/2) >= (strikerypos-strikerheight/2) && (ypos+diameter/2) <= (strikerypos+strikerheight/2))                 {                     score++;                      //////////////////////////////////////////////////////////////////////                     /////this part focus on///////////////////////////////////////                     /////when ball hits striker, show '+1' text fading upwards point of hit                     /////(this highlight +1 increase in score)///////////////////                     //////now since ball may hit striker again before previous +1 has faded,                     //////i have made simple thread create +1 every time there hit. there can multiple                     //////+1 on screen.                     //-------------------------------sadly, wrong-------------------                      //print '+1' show score increase                     new thread(new runnable(){                         int ystart = strikerypos;                         int fadelength = 0;                         timer pointtimer;                         int max_fade_len = 50;                          public void run() {                             try                             {                                  pointtimer = new timer(1, new actionlistener() {                                          public void actionperformed(actionevent evt) {                                             if(fadelength >= max_fade_len)                                                 pointtimer.stop();                                             g2d.setcolor(new color(0,0,0,255));                                             g2d.setfont(new font("times",font.bold,20));                                             g2d.drawstring("+1",60,ystart - fadelength);                                             g2d.drawoval(100,100,50,50);                                             system.out.println("drawn +1 @ x = " + 60 + " y = " + (ystart - fadelength));                                             fadelength++;                                          }                                             });                                 pointtimer.start();                             }                             catch (exception e)                             {                              }                         }                      }).start();                     ////////////////thread ends here//////////////////////                 }                 else                 {                     score--;                 }                  //show score on label                 jlabel1.settext("score: " + score);                 speedx = ((int)math.signum((double)speedx))*(-1) * (2+ math.abs(new random().nextint()) % 5);                 xpos = strikerwidth+1;             }              if(ypos <= 0)             {                 speedy = ((int)math.signum((double)speedy))*(-1) * (2+ math.abs(new random().nextint()) % 5);                 ypos = 0;             }             if((ypos+diameter) >= h)             {                 speedy = ((int)math.signum((double)speedy))*(-1) * (2+ math.abs(new random().nextint()) % 5);                 ypos = h-diameter;             }         } else {             g2d.drawoval(xpos,ypos,diameter,diameter);             return;         }     }      public static void main(string[] args) {          jframe frame = new jframe("magic ball");         movingball = new movingball();         frame.setdefaultcloseoperation(jframe.exit_on_close);         frame.add(movingball);         frame.setsize(450, 700);         frame.setlocationrelativeto(null);         frame.setvisible(true);     }      private void jbinit() throws exception {         jbutton1.settext("start");         jbutton1.addactionlistener(new actionlistener() {                     public void actionperformed(actionevent e) {                         jbutton1_actionperformed(e);                     }                 });         jbutton2.settext("stop");         jbutton2.addactionlistener(new actionlistener() {                     public void actionperformed(actionevent e) {                         jbutton2_actionperformed(e);                     }                 });         jlabel1.settext("score:0");         this.add(jbutton1, null);         this.add(jbutton2, null);         this.add(jlabel1, null);         this.setbackground(color.white);         this.addmousemotionlistener(new mousemotionlistener() {                     public void mousemoved(mouseevent e) {                         int coordx = e.getx();                         if(coordx < 200)                             strikerypos = e.gety();                     }                      public void mousedragged(mouseevent e) {                     }                 });     }      private void jbutton1_actionperformed(actionevent e) {         if(!isballmoving)             isballmoving = true;     }      private void jbutton2_actionperformed(actionevent e) {         isballmoving = false;     } } 

i don't think many people consider 250 loc 'short' (though must admit deliberately vague when writing sscce document). otoh adapted shorter source seen here animated example shows 'fade effect' on mouse clicks. adapting needs left exercise ..you.

this source shows how change drawn string on period of 5 seconds. uses same thread (the edt) both main (bouncing ball) , fade animation.

fading strikes

import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.bufferedimage; import java.util.arraylist; import javax.swing.*;  class shapecollision {      private bufferedimage img;     private area walls;     int x;     int y;     int xdelta = 3;     int ydelta = 2;     arraylist<strike> strikes;      /**      * method determine if 2 instances of area intersect      */     public boolean doareascollide(area area1, area area2) {         boolean collide = false;          area collide1 = new area(area1);         collide1.subtract(area2);         if (!collide1.equals(area1)) {             collide = true;         }          area collide2 = new area(area2);         collide2.subtract(area1);         if (!collide2.equals(area2)) {             collide = true;         }          return collide;     }      shapecollision() {         int w = 400;         int h = 200;         img = new bufferedimage(w, h, bufferedimage.type_int_rgb);         final jlabel imagelabel = new jlabel(new imageicon(img));         x = w / 2;         y = h / 2;          strikes = new arraylist<strike>();          mouselistener strikelistener = new mouseadapter() {              @override             public void mouseclicked(mouseevent e) {                 strike s = new strike(e.getpoint(),system.currenttimemillis());                 strikes.add(s);             }         };         imagelabel.addmouselistener(strikelistener);          walls = new area(new rectangle(0, 0, w, h));          actionlistener animate = new actionlistener() {              @override             public void actionperformed(actionevent e) {                 animate();                 imagelabel.repaint();             }         };         timer timer = new timer(50, animate);          timer.start();         joptionpane.showmessagedialog(null, imagelabel);         timer.stop();     }      public void animate() {         graphics2d g = img.creategraphics();         g.setrenderinghint(                 renderinghints.key_antialiasing,                 renderinghints.value_antialias_on);          g.setcolor(color.black);         g.fillrect(0, 0, img.getwidth(), img.getheight());         x += xdelta;         y += ydelta;         int s = 15;         area player = new area(new ellipse2d.double(x, y, s, s));          // acid test of edge collision;         if (doareascollide(player, walls)) {             if (x + s > img.getwidth() || x < 0) {                 xdelta *= -1;             }             if (y + s > img.getheight() || y < 0) {                 ydelta *= -1;             }         }         g.setcolor(color.orange);         g.setcolor(color.yellow);         g.fill(player);          (strike strike : strikes) {             strike.draw(g);         }          g.dispose();     }      public static void main(string[] args) {         runnable r = new runnable() {              @override             public void run() {                 new shapecollision();             }         };         // swing guis should created , updated on edt         // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html         swingutilities.invokelater(r);     } }  class strike {      private point point;     private long started;     private final long duration = 5000;     private boolean expired = false;      strike(point point, long time) {         this.point = point;         started = time;     }      public void draw(graphics g) {         long = system.currenttimemillis();         long age = - started;         if (age>duration) {             expired = true;             return;         }         double fraction = 1d-((double)age/(double)duration);         int alpha = (int)(fraction*255d);         color c = new color(255,255,255,alpha);         g.setcolor(c);         string s = point.x + "," + point.y;         g.drawstring( s, point.x, point.y );     }      public boolean isexpired() {         return expired;     } } 

Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -