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
getpreferredsizemethod oflinepanel, return size of panel use. - use
java.util.listmaintain list ofpoints need painted. - in
paintcomponentmethod, usepointlistrender lines. bit tricky, need 2 points ,listmay contain odd number of points, but's doable. - calculate start
pointeither using preferred size or other means (like usingcomponentlistener, monitoringcomponentresizedmethod. 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