java - Error with creating a game launcher -
i'm making simple java game , trying implement launcher @ beginning of game.
for example, jframe
button in starts application when it's pressed.
what i'm trying have main method call separate class opens jframe
, , actionlistener
jbutton
calls new cliker();
when it's called.
however, when new cliker();
called outside of main
method, opens game jframe
, not jpanel
.
why error happening, , how fix it? relatively new programming apologize in advance unclear points question or program.
i appreciate help. if need more classes answer question, ask, or if have other questions feel free let me know.
package com.cliker; import java.awt.color; import java.awt.dimension; import java.awt.font; import java.awt.graphics; import java.awt.event.mouseevent; import java.awt.event.mouselistener; import javax.swing.imageicon; import javax.swing.jbutton; import javax.swing.jframe; import javax.swing.joptionpane; import javax.swing.jpanel; import com.cliker.accessories.music; public class cliker extends jframe { private static final long serialversionuid = 1l; int score = 0; jbutton ball = new jbutton(new imageicon("res/textures/ball/ball.png")); jframe gameframe = new jframe("cliker v1.0"); public static void main(string[] args){ new cliker(); } public cliker() { gameframe.setdefaultcloseoperation(jframe.exit_on_close); gameframe.add(new mypanel()); gameframe.pack(); gameframe.setvisible(true); gameframe.setresizable(false); gameframe.setlocationrelativeto(null); clikergame play = new clikergame(); play.run(this); } class mypanel extends jpanel implements mouselistener { private static final long serialversionuid = 1l; public mypanel() { setbackground(color.cyan); ball.addmouselistener(new mouselistener() { @override public void mousepressed(mouseevent e) { if (e.getsource() == ball) { score++; music.music(4); repaint(); } } @override public void mouseclicked(mouseevent e) { } @override public void mouseentered(mouseevent e) { } @override public void mouseexited(mouseevent e) { } @override public void mousereleased(mouseevent e) { } }); ball.setborder(null); add(ball); addmouselistener(this); } public void paintcomponent(graphics g) { super.paintcomponent(g); g.setfont(new font("fixedsys", font.bold, 30)); g.setcolor(color.black); g.drawstring(string.valueof(score), getwidth() / 2, 40); } public dimension getpreferredsize() { return new dimension(700, 500); } @override public void mousepressed(mouseevent e) { if (e.getsource() == this) { this.setbackground(color.red); gameframe.setvisible(false); clikerendgame senddata = new clikerendgame(); try { senddata.finish(score); } catch (exception e1) { joptionpane.showinputdialog(null,"the game has encountered error. error code: 001"); e1.printstacktrace(); } } } @override public void mouseclicked(mouseevent e) { } @override public void mouseentered(mouseevent e) { } @override public void mouseexited(mouseevent e) { } @override public void mousereleased(mouseevent arg0) { } } }
next class
package com.cliker; import javax.swing.jbutton; import javax.swing.joptionpane; import com.cliker.accessories.music; public class clikergame implements runnable { private int x, y, xa = 2, ya = 2; public void run(cliker panel) { jbutton ball = panel.ball; music.music(2); while (true) { try { x += xa; y += ya; if (x < 0 || x > 700 - 20 ) { music.music(1); xa = -xa; } else if (y < 0 || y > 500 - 20 ){ music.music(1); ya = -ya; } thread.sleep(15); ball.setbounds(x,y,30,30); } catch (exception e) { joptionpane.showmessagedialog(null,"error 1"); } } } public void run() { this.run(); }
}
basically, you're violating single thread rules of swing, clikergame
running while-loop
blocking event dispatching thread, preventing processing new events, including paint events.
the reason works main
, main
isn't called within edt, basically, fluke. when call new clicker()
within actionlistener
of jbutton
however, running within context of edt, hence problem.
take @ initial threads , concurrency in swing more details.
the "immediate" solution might using thread
, violate single rules of swing, swing not thread safe , should never update ui outside context of edt.
a better solution might use swing timer
act pseudo loop instead. notified, @ regular intervals, withing context of edt
maybe, like...
public class clikergame { private int x, y, xa = 2, ya = 2; private clicker clicker; private timer timer; public clikergame(clicker clicker) { this.clicker = clicker; timer = new timer(15, new actionlistener() { @override public void actionperformed(actionevent e) { try { x += xa; y += ya; if (x < 0 || x > 700 - 20) { music.music(1); xa = -xa; } else if (y < 0 || y > 500 - 20) { music.music(1); ya = -ya; } thread.sleep(15); clicker.ball.setbounds(x, y, 30, 30); clicker.ball.getparent().repaint(); } catch (exception e) { joptionpane.showmessagedialog(null, "error 1"); } } }); } public void start() { if (!timer.isrunning()) { music.music(2); timer.start(); } } public void stop() { timer.stop(); // stop music } }
Comments
Post a Comment