Drawing lines in GUI with arrow keys using keylistener in Java -
i working on keylistener exercise java class, have been stuck past week. appreciate helpful suggestions. exercise is:
"write program draws line segments using arrow keys. line starts center of frame , draws toward east, north, west, or south when right-arrow key, up-arrow key, left-arrow key, or down-arrow key clicked."
through debugging figured out keylistener works point of getting drawcomponent(graphics g), draws when press down or right , works first couple times. here code:
import java.awt.*; import java.awt.event.*; import javax.swing.*; @suppresswarnings("serial") public class eventprogrammingexercise8 extends jframe { jpanel contentpane; linepanel lines; public static final int size_of_frame = 500; public static void main(string[] args) { eventqueue.invokelater(new runnable() { public void run() { try { eventprogrammingexercise8 frame = new eventprogrammingexercise8(); frame.setvisible(true); } catch (exception e) { e.printstacktrace(); } } }); } public eventprogrammingexercise8() { settitle("eventexercise8"); setdefaultcloseoperation(jframe.exit_on_close); setsize(size_of_frame, size_of_frame); contentpane = new jpanel(); lines = new linepanel(); contentpane.add(lines); setcontentpane(contentpane); contentpane.setopaque(true); lines.setopaque(true); lines.setfocusable(true); lines.addkeylistener(new arrowlistener()); } private class linepanel extends jpanel { private int x; private int y; private int x2; private int y2; public linepanel() { x = getwidth() / 2; y = getheight() / 2; x2 = x; y2 = y; } protected void paintcomponent(graphics g) { g.drawline(x, y, x2, y2); x = x2; y = y2; } public void draweast() { x2 += 5; repaint(); } public void drawwest() { x2 -= 5; repaint(); } public void drawnorth() { y2 -= 5; repaint(); } public void drawsouth() { y2 += 5; repaint(); } } private class arrowlistener extends keyadapter { public void keypressed(keyevent e) { int key = e.getkeycode(); if (key == keyevent.vk_right) { lines.draweast(); } else if (key == keyevent.vk_left) { lines.drawwest(); } else if (key == keyevent.vk_up) { lines.drawnorth(); } else { lines.drawsouth(); } } } }
thanks.
a few things jump out @ me...
public linepanel() { x = getwidth() / 2; y = getheight() / 2;
this issue, because @ time construct class, it's size 0x0
apart fact haven't called super.paintcomponent
breaks paint chain, seem think painting accumaltive...
protected void paintcomponent(graphics g) { g.drawline(x, y, x2, y2); x = x2; y = y2; }
painting in swing destructive. is, expected erase graphics
context , rebuild output scratch. job paintcomponent
clear graphics
context ready painting, you've not called super.paintcomponent
, breaking paint chain , opening number of ugly paint artifacts
calling setsize(size_of_frame, size_of_frame);
on frame dangerous, makes no guarantee frames border insets, reduce viewable area available you.
this....
contentpane = new jpanel(); lines = new linepanel(); contentpane.add(lines); setcontentpane(contentpane);
is not required, adds clutter code. it's hint going wrong code.
jpanel
uses flowlayout
default. flowlayout
uses component's preferred size determine how best layout components. default preferred size of component 0x0
you use...
lines = new linepanel(); add(lines);
instead or set contentpane
use borderlayout
help...
try adding lines.setborder(new lineborder(color.red));
add see get...
oddly, during testing, keylistener
worked fine...
basically...
- override
getpreferredsize
method oflinepanel
, return size of panel use. - use
java.util.list
maintain list ofpoint
s need painted. - in
paintcomponent
method, usepoint
list
render lines. bit tricky, need 2 points ,list
may contain odd number of points, but's doable. - calculate start
point
either using preferred size or other means (like usingcomponentlistener
, monitoringcomponentresized
method. becomes tricky component may resized number of times when first created , released screen , want ignore future events once have first point)
Comments
Post a Comment