java - JPanel size is not known on start -
when create board instance square instance, try assign size of window integers x , y. fail because seems on start size 0. in constructor in board.java, x , y shouldn't -50 end now.
square.java:
package square; import javax.swing.*; public class square extends jframe { public square(){ add(new board()); setsize(800, 800); setvisible(true); } public static void main(string[] args){ new square(); } }
board.java
package square; import javax.swing.*; import java.awt.*; public class board extends jpanel{ int x,y; public board(){ x = width-50; y = height-50; } public int width = (int) getsize().getwidth(); public int height = (int) getsize().getheight(); public void paintcomponent(graphics g){ super.paintcomponent(g); g.fillrect(x,y, 100, 100); } }
full code clarification: square.java
package square; import javax.swing.*; public class square extends jframe { public square(){ board board = new board(); board.start(); add(board); settitle("square"); setsize(800, 800); setdefaultcloseoperation(windowconstants.exit_on_close); } public static void main(string[] args){ square square = new square(); square.setvisible(true); square.setlocation(2000, 150); } }
board.java
package square; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class board extends jpanel implements actionlistener{ timer timer; int x, y; int velx = 0; int vely = 0; public board(){ setfocusable(true); timer = new timer(1, this); addkeylistener(new tadapter()); } class tadapter extends keyadapter{ public void keypressed(keyevent e) { int keycode = e.getkeycode(); switch(keycode){ case keyevent.vk_escape: x = width()/2-50; y = height()/2-50; break; case keyevent.vk_right: velx = 1; break; case keyevent.vk_down: vely = 1; break; case keyevent.vk_left: velx = -1; break; case keyevent.vk_up: vely = -1; break; } } public void keyreleased(keyevent e){ velx = 0; vely = 0; } } public int width(){ return (int) getsize().getwidth();} public int height(){ return (int) getsize().getheight();} public void start(){ timer.setinitialdelay(100); timer.start(); x = width()/2-50; y = height()/2-50; } @override public void actionperformed(actionevent e) { x += velx; y += vely; repaint(); } public void paintcomponent(graphics g){ super.paintcomponent(g); g.setcolor(color.red); g.fillrect(x,y, 100, 100); } }
put calculation paintcomponent method. in general want avoid having code in paintcomponent slow down, these calls shouldn't give penalty. also, if program re-sizable, you'll need able re-calculate sizes of things on go this:
public void paintcomponent(graphics g){ super.paintcomponent(g); int x = getwidth() - 50; int y = getheight() - 50; g.fillrect(x, y, 100, 100); }
but of course in real program, want avoid "magic" numbers
another issue: don't call setsize()
on jframe. instead, if want specify hard size, in jpanel overriding getpreferredsize()
method. give suggested parameters can used calculations.
for example:
import java.awt.color; import java.awt.dimension; import java.awt.graphics; import java.awt.event.actionevent; import java.awt.event.actionlistener; import javax.swing.*; @suppresswarnings("serial") public class drawrect extends jpanel { private static final int pref_w = 800; private static final int pref_h = pref_w; private static final int delta = 50; private static final color rect_color = color.red; private static final int rect_width = 100; private static final int timer_delay = 15; private int rectx = pref_w - delta; private int recty = pref_h - delta; public drawrect() { new timer(timer_delay, new timerlistener()).start(); } @override protected void paintcomponent(graphics g) { super.paintcomponent(g); g.setcolor(rect_color); g.fillrect(rectx, recty, rect_width, rect_width); } @override public dimension getpreferredsize() { if (ispreferredsizeset()) { return super.getpreferredsize(); } return new dimension(pref_w, pref_h); } private class timerlistener implements actionlistener { @override public void actionperformed(actionevent e) { rectx--; recty--; repaint(); } } private static void createandshowgui() { jframe frame = new jframe("drawrect"); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.getcontentpane().add(new drawrect()); frame.pack(); frame.setlocationrelativeto(null); frame.setvisible(true); } public static void main(string[] args) { swingutilities.invokelater(new runnable() { public void run() { createandshowgui(); } }); } }
also, check out key bindings animation code this answer of mine.
import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.util.enummap; import java.util.hashmap; import java.util.map; public class gamepanel extends jpanel { private static final int animation_delay = 15; private final int height = 400; private final int width = 600; private square square; private enummap<direction, boolean> dirmap = new enummap<>(direction.class); private map<integer, direction> keytodir = new hashmap<>(); // !! private circle circle; private timer animationtimer; public gamepanel() { (direction dir : direction.values()) { dirmap.put(dir, boolean.false); } keytodir.put(keyevent.vk_up, direction.up); keytodir.put(keyevent.vk_down, direction.down); keytodir.put(keyevent.vk_left, direction.left); keytodir.put(keyevent.vk_right, direction.right); // !! addkeylistener(new directionlistener()); setkeybindings(); setbackground(color.white); setpreferredsize(new dimension(width, height)); setfocusable(true); square = new square(); animationtimer = new timer(animation_delay, new animationlistener()); animationtimer.start(); } private void setkeybindings() { int condition = when_in_focused_window; final inputmap inputmap = getinputmap(condition); final actionmap actionmap = getactionmap(); boolean[] keypressed = { true, false }; (integer keycode : keytodir.keyset()) { direction dir = keytodir.get(keycode); (boolean onkeypress : keypressed) { boolean onkeyrelease = !onkeypress; // make clear how bindings work keystroke keystroke = keystroke.getkeystroke(keycode, 0, onkeyrelease); object key = keystroke.tostring(); inputmap.put(keystroke, key); actionmap.put(key, new keybindingsaction(dir, onkeypress)); } } } public void paintcomponent(graphics g) { super.paintcomponent(g); square.display(g); } private class animationlistener implements actionlistener { @override public void actionperformed(actionevent evt) { boolean repaint = false; (direction dir : direction.values()) { if (dirmap.get(dir)) { square.move(dir); repaint = true; } } if (repaint) { repaint(); } } } private class keybindingsaction extends abstractaction { private direction dir; boolean pressed; public keybindingsaction(direction dir, boolean pressed) { this.dir = dir; this.pressed = pressed; } @override public void actionperformed(actionevent evt) { dirmap.put(dir, pressed); } } private static void createandshowgui() { gamepanel gamepanel = new gamepanel(); jframe frame = new jframe("gamepanel"); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.getcontentpane().add(gamepanel); frame.pack(); frame.setlocationrelativeto(null); frame.setvisible(true); gamepanel.requestfocusinwindow(); } public static void main(string[] args) { swingutilities.invokelater(new runnable() { public void run() { createandshowgui(); } }); } } enum direction { up(0, -1), down(0, 1), left(-1, 0), right(1, 0); private int incrx; private int incry; private direction(int incrx, int incry) { this.incrx = incrx; this.incry = incry; } public int getincrx() { return incrx; } public int getincry() { return incry; } } class square { private int x = 0; private int y = 0; private int w = 20; private int h = w; private int step = 1; private color color = color.red; private color fillcolor = new color(255, 150, 150); private stroke stroke = new basicstroke(3f, basicstroke.cap_round, basicstroke.join_round); public void display(graphics g) { graphics2d g2d = (graphics2d) g.create(); g2d.setcolor(fillcolor); g2d.fillrect(x, y, w, h); g2d.setstroke(stroke); g2d.setcolor(color); g2d.drawrect(x, y, w, h); g2d.dispose(); } public void setstep(int step) { this.step = step; } public void move(direction dir) { x += step * dir.getincrx(); y += step * dir.getincry(); } }
Comments
Post a Comment