java - JGraph AWT EventQueue exception on paint (with multithreading) -



java - JGraph AWT EventQueue exception on paint (with multithreading) -

situation

i have visualisation using jgraph. graph updated different thread instantiates visualisation.

expected behaviour

the graph should updated various worker threads. function threads phone call update graph syncronized, worker threads not causes concurrency issues between themselves.

actual behaviour

there (ocassionally) exception thrown in awt-eventqueue thread when painting. it's null pointer, it's index out of bounds. here's stack trace:

exception in thread "awt-eventqueue-0" java.lang.nullpointerexception @ com.mxgraph.shape.mxconnectorshape.translatepoint(unknown source) @ com.mxgraph.shape.mxconnectorshape.paintshape(unknown source) @ com.mxgraph.canvas.mxgraphics2dcanvas.drawcell(unknown source) @ com.mxgraph.view.mxgraph.drawstate(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.drawcell(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.drawchildren(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.drawcell(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.drawchildren(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.drawcell(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.drawchildren(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.drawcell(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.drawfromrootcell(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.drawgraph(unknown source) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.paintcomponent(unknown source) @ javax.swing.jcomponent.paint(jcomponent.java:1029) @ com.mxgraph.swing.mxgraphcomponent$mxgraphcontrol.paint(unknown source) @ javax.swing.jcomponent.paintchildren(jcomponent.java:866) @ javax.swing.jcomponent.paint(jcomponent.java:1038) @ javax.swing.jviewport.paint(jviewport.java:764) @ javax.swing.jcomponent.painttooffscreen(jcomponent.java:5138) @ javax.swing.bufferstrategypaintmanager.paint(bufferstrategypaintmanager.java:302) @ javax.swing.repaintmanager.paint(repaintmanager.java:1188) @ javax.swing.jcomponent._paintimmediately(jcomponent.java:5086) @ javax.swing.jcomponent.paintimmediately(jcomponent.java:4896) @ javax.swing.repaintmanager.paintdirtyregions(repaintmanager.java:783) @ javax.swing.repaintmanager.paintdirtyregions(repaintmanager.java:735) @ javax.swing.repaintmanager.prepaintdirtyregions(repaintmanager.java:677) @ javax.swing.repaintmanager.access$700(repaintmanager.java:58) @ javax.swing.repaintmanager$processingrunnable.run(repaintmanager.java:1593) @ java.awt.event.invocationevent.dispatch(invocationevent.java:226) @ java.awt.eventqueue.dispatcheventimpl(eventqueue.java:647) @ java.awt.eventqueue.access$000(eventqueue.java:96) @ java.awt.eventqueue$1.run(eventqueue.java:608) @ java.awt.eventqueue$1.run(eventqueue.java:606) @ java.security.accesscontroller.doprivileged(native method) @ java.security.accesscontrolcontext$1.dointersectionprivilege(accesscontrolcontext.java:105) @ java.awt.eventqueue.dispatchevent(eventqueue.java:617) @ java.awt.eventdispatchthread.pumponeeventforfilters(eventdispatchthread.java:275) @ java.awt.eventdispatchthread.pumpeventsforfilter(eventdispatchthread.java:200) @ java.awt.eventdispatchthread.pumpeventsforhierarchy(eventdispatchthread.java:190) @ java.awt.eventdispatchthread.pumpevents(eventdispatchthread.java:185) @ java.awt.eventdispatchthread.pumpevents(eventdispatchthread.java:177) @ java.awt.eventdispatchthread.run(eventdispatchthread.java:138)

it doesn't seem adversely impact running of application. new awt-eventqueue spawns, @ stage inevitably encounter same problem.

cause

i think must caused updating graph in separate thread 1 jframe instantiated in. things need drawn beingness changed whilst paint method trying draw them.

question

how go working around problem? can somehow synchronize paint method method updates graph?

visualisation code package ui; import javax.swing.jframe; import com.mxgraph.layout.mxorganiclayout; import com.mxgraph.layout.mxstacklayout; import com.mxgraph.model.mxcell; import com.mxgraph.model.mxgraphmodel; import com.mxgraph.swing.mxgraphcomponent; import com.mxgraph.view.mxgraph; import core.container; import core.node; import core.warehousegraph; public class visualisation extends jframe{ private static final long serialversionuid = 8356615097419123193l; private mxgraph graph = new mxgraph(); object parent = graph.getdefaultparent(); mxorganiclayout graphlayout = new mxorganiclayout(graph); mxstacklayout containerlayout = new mxstacklayout(graph, true, 10); public visualisation(warehousegraph model){ super("warehouse simulator"); this.setdefaultcloseoperation(jframe.exit_on_close); this.setsize(800, 600); graph.getmodel().beginupdate(); try{ for(node node : model.getnodes().values()){ mxcell cell = (mxcell)graph.insertvertex(parent, node.getid(), node.getid(), 0, 0, 60, 30); object prev = null; for(container container : node.getcontainers()){ object newcont = graph.insertvertex(cell, container.getid(), container.getid(), 0, 0, 60, 20); if(prev != null) graph.insertedge(cell, null, null, prev, newcont); prev = newcont; } } for(node node : model.getnodes().values()){ for(node tonode : node.getdownstreamnodes()){ object fromcell = ((mxgraphmodel)graph.getmodel()).getcell(node.getid()); object tocell = ((mxgraphmodel)graph.getmodel()).getcell(tonode.getid()); graph.insertedge(parent, null, null, fromcell, tocell); } } }catch(exception e){ e.printstacktrace(); }finally{ graph.getmodel().endupdate(); } graphlayout.execute(parent); object[] nodes = mxgraphmodel.getchildvertices(graph.getmodel(), parent); for(object cell : nodes){ containerlayout.execute(cell); graph.updatecellsize(cell); } mxgraphcomponent graphcomponent = new mxgraphcomponent(graph); getcontentpane().add(graphcomponent); this.setvisible(true); } //called synchronized function public void movecontainer(container container, node to){ graph.getmodel().beginupdate(); mxcell tocell = (mxcell)((mxgraphmodel)graph.getmodel()).getcell(to.getid()); mxcell containercell = (mxcell)((mxgraphmodel)graph.getmodel()).getcell(container.getid()); mxcell fromcell = (mxcell)containercell.getparent(); try{ object[] edges = mxgraphmodel.getedges(graph.getmodel(), containercell); graph.removecells(edges); containercell.removefromparent(); graph.addcell(containercell, tocell); object[] containers = mxgraphmodel.getchildvertices(graph.getmodel(), tocell); if(containers.length >= 2) graph.insertedge(tocell, null, null, containercell, containers[containers.length-2]); containerlayout.execute(tocell); containerlayout.execute(fromcell); }catch(exception e){ e.printstacktrace(); }finally{ graph.getmodel().endupdate(); } } } controller code package core; import serialisation.jsonutil; import ui.visualisation; public class controller{ private warehousegraph graph; visualisation viz; public static void main(string[] args){ controller.getinstance(); } private controller(){ graph = jsonutil.initfromjson(); //graph has many worker threads running can phone call containermoved viz = new visualisation(graph); } private static class singletonholder{ private static final controller instance = new controller(); } public static controller getinstance(){ homecoming singletonholder.instance; } public synchronized void containermoved(container container, node from, node to){ viz.movecontainer(container, to); } }

not reply question, notice concept.

can show public static void main(string[] args) {...} methods? hoping there looks like:

public static void main(string[] args) { swingutilities.invokelater(new runnable() {

public void run() { visualisation vis = new visualisation(); } }); }

this.setsize(800, 600); should this.setpreferredsize(new dimension(800, 600));

then add together this.pack(); before lastly line (this.setvisible(true);)

edit:

what type of components returns mxgraphcomponent graphcomponent = new mxgraphcomponent(graph); because if custom components based on jpanel

getcontentpane().add(graphcomponent); should add(graphcomponent);

all input background thread/task must wrapped invokelater(). if flickering or freezing, have invokeandwait(). hate invokeandwait() exists there, method can't give right suggestions. or:

if you'll run task on periodical bases, have runnable (output must wrapped invokelater) or swingworker.

java swing concurrency awt paint

Comments

Popular posts from this blog

iphone - Dismissing a UIAlertView -

c# - Can ProtoBuf-Net deserialize to a flat class? -

javascript - Change element in each JQuery tab to dynamically generated colors -