java - Class Cast Exception - Mouse event -
a bit of context - creating rudimentary implementation of scrabble , gui relies on java swing , awt. code excerpt below contains constructor cell class (individual space on scrabble board). in proof of concept phase , testing addition , removal of hard-coded letter icon individual cell. each cell individual jpanel jlabel (which, contains imageicon of letter). code looks though works without error, every 5-6 additions/removals (via mouse click) causes class cast exception. specific exception is:
exception in thread "awt-eventqueue-0" java.lang.classcastexception: cell cannot cast javax.swing.jlabel
i can't see exception caused, more why occurs after multiple successful additions , removals. insight appreciated; beginner java gui.
public class cell extends jpanel { /*tile colors*/ public static color twcolor = new color(255, 0, 0); public static color dwcolor = new color(255, 153, 255); public static color tlcolor = new color(0, 51, 255); public static color dlcolor = new color(102, 204, 255); public static color defaultcolor = new color(255, 255, 255); private jlabel selected = null; private jlabel clicked = null; private jlabel lettericon; private imageicon defaulticon; private imageicon testimg; public cell(int xpos, int ypos, int premiumstatus) { defaulticon = new imageicon ("img/transparent.png"); testimg = new imageicon ("img/test.jpg"); // letter image hard-coded testing lettericon = new jlabel("", defaulticon, jlabel.center); add(lettericon); lettericon.addmouselistener(new mouseadapter() { public void mouseclicked(mouseevent e) { jlabel clicked = (jlabel) getcomponentat(e.getpoint()); system.out.println(clicked); if (clicked == null) { return; } if (selected != null) { selected.removeall(); selected.revalidate(); selected.seticon(defaulticon); selected.repaint(); system.out.println("test"); selected = null; return; } if (selected == null) { selected = clicked; selected.seticon(testimg); selected.revalidate(); selected.repaint(); } } }); }
the problem being cause calling getcomponentat(e.getpoint());
on cell
, when mouse coordinates have been converted coordinate space of lettericon
.
when component clicked, mouseevent
's point automatically converted coordinate space of component listener registered to.
in case, lettericon
. means point @ 0x0 top/left corner of lettericon
(despite might physically positioned).
so, calling getcomponentat(e.getpoint())
ask cell
return component corresponds position relative lettericon
, (in cases) return cell
itself.
instead, should using mouseevent#getcomponent
return component triggered event, lettericon
update simple example
this simple example sets jlabel
mouse target. when mouse clicked, both label , it's parent container paint small dot based on coordinates of mouse click.
there added benefit parent container translate click point it's coordinate space , paint second dot, should in same click labels.
import java.awt.borderlayout; import java.awt.color; import java.awt.dimension; import java.awt.eventqueue; import java.awt.graphics; import java.awt.gridbaglayout; import java.awt.point; import java.awt.event.mouseadapter; import java.awt.event.mouseevent; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.jpanel; import javax.swing.swingutilities; import javax.swing.uimanager; import javax.swing.unsupportedlookandfeelexception; public class testmouseclicked { public static void main(string[] args) { new testmouseclicked(); } public testmouseclicked() { eventqueue.invokelater(new runnable() { @override public void run() { try { uimanager.setlookandfeel(uimanager.getsystemlookandfeelclassname()); } catch (classnotfoundexception | instantiationexception | illegalaccessexception | unsupportedlookandfeelexception ex) { } jframe frame = new jframe("testing"); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.setlayout(new borderlayout()); frame.add(new testpane()); frame.pack(); frame.setlocationrelativeto(null); frame.setvisible(true); } }); } public class testpane extends jpanel { private jlabel clickme; private point clickpoint; public testpane() { setlayout(new gridbaglayout()); clickme = new jlabel("click me") { @override protected void paintcomponent(graphics g) { super.paintcomponent(g); g.setcolor(color.magenta); // paintpoint(g, clickpoint); } }; add(clickme); clickme.addmouselistener(new mouseadapter() { @override public void mouseclicked(mouseevent e) { clickpoint = e.getpoint(); repaint(); } }); } @override public dimension getpreferredsize() { return new dimension(200, 200); } @override protected void paintcomponent(graphics g) { super.paintcomponent(g); g.setcolor(color.red); paintpoint(g, clickpoint); if (clickpoint != null) { g.setcolor(color.blue); // convert point clickme coordinate space local coordinate space paintpoint(g, swingutilities.convertpoint(clickme, clickpoint, this)); } } protected void paintpoint(graphics g, point clickpoint) { if (clickpoint != null) { int size = 4; g.filloval(clickpoint.x - size, clickpoint.y - size, size * 2, size * 2); } } } }
Comments
Post a Comment