Hola Joaquín,<div><br></div><div>He probado lo que me dijiste y justo era eso. Yo ya había implementado un botón de "Mostrar Resultados" que ya evitaba el problema, pero es mucho mejor después de implementar lo que me dijiste para que los muestre directamente.</div>
<div>¡Has dado en el clavo! </div><div><br></div><div>De ahora en adelante echaré un ojo a los hilos que voy abriendo en Swing. En este caso seguramente el error viniera por una barra de progreso que tenía implementada para mostrar el progreso.</div>
<div><br></div><div>Muchísimas gracias por el consejo,</div><div>Un saludo,</div><div><br></div><div>Alberto</div><div><br><br><div class="gmail_quote">2012/8/6 Joaquin del Cerro <span dir="ltr"><<a href="mailto:jjdelcerro.gvsig@gmail.com" target="_blank">jjdelcerro.gvsig@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">El 03/08/12 18:15, Alberto Calzada escribió:<br>
<div><div class="h5">> Hola a todos,<br>
><br>
> Estoy desarrollando una extensión para gvSIG 1.11 y llevo un bueno rato<br>
> intentando averiguar el porqué de este error. He mirado por Internet y<br>
> también antiguos mensajes en las listas de correo pero no he encontrado<br>
> nada al respecto, y para ser sincero, no sé a qué se debe.<br>
> Este es el error en tiempo de ejecución que me salta siempre:<br>
><br>
> Exception in thread "Thread-8" java.lang.RuntimeException: No Event<br>
> Dispatch Thr<br>
><br>
> ead<br>
><br>
> at<br>
> com.iver.andami.ui.mdiFrame.MDIFrame.enableControls(MDIFrame.java:897<br>
><br>
> )<br>
><br>
> at<br>
> com.iver.cit.gvsig.project.documents.table.gui.Table.updateSelection(<br>
><br>
> Table.java:340)<br>
><br>
> at<br>
> com.iver.cit.gvsig.project.documents.table.gui.Table.refreshControls(<br>
><br>
> Table.java:257)<br>
><br>
> at<br>
> com.iver.cit.gvsig.project.documents.table.gui.Table.setModel(Table.j<br>
><br>
> ava:293)<br>
><br>
> at<br>
> com.iver.cit.gvsig.project.documents.table.ProjectTable.createWindow(<br>
><br>
> ProjectTable.java:969)<br>
><br>
> at<br>
> model.spatial.GISOutputExporterCSV.closeFile(GISOutputExporterCSV.jav<br>
><br>
> a:337)<br>
><br>
> at model.core.Execution$ActualTask.<init>(Execution.java:243)<br>
><br>
> at model.core.Execution$2.construct(Execution.java:88)<br>
><br>
> at model.threadExec.SwingWorker$2.run(SwingWorker.java:60)<br>
><br>
> at java.lang.Thread.run(Unknown Source)<br>
><br>
> Mi código es el siguiente (en GISOutputExporterCSV.java):<br>
><br>
> ProjectExtension ext = (ProjectExtension)<br>
> PluginServices.getExtension(ProjectExtension.class);<br>
> try {<br>
> LayerFactory.getDataSourceFactory().addFileDataSource("csv string",<br>
> tableFile.getName(), tableFile.getAbsolutePath());<br>
> DataSource dataSource =<br>
> LayerFactory.getDataSourceFactory().createRandomDataSource(tableFile.getName(),<br>
> DataSourceFactory.AUTOMATIC_OPENING);<br>
><br>
> dataSource.setDataSourceFactory(LayerFactory.getDataSourceFactory());<br>
> SelectableDataSource sds = new SelectableDataSource(dataSource);<br>
> EditableAdapter auxea=new EditableAdapter();<br>
> auxea.setOriginalDataSource(sds);<br>
> String docName = "RIMER Results in: "+tableFile.getName();<br>
> projectTable = ProjectFactory.createTable(docName, auxea);<br>
> projectTable.setModel(auxea);<br>
> ext.getProject().addDocument(projectTable);<br>
><br>
> IWindow win = projectTable.createWindow();<br>
> PluginServices.getMDIManager().addWindow(win);<br>
><br>
> Donde tableFile es del tipo java.io.File.<br>
><br>
> El caso es que la tabla CSV se añade correctamente al proyecto, y además<br>
> puedo abrirla sin problema ninguno manualmente después de que este error<br>
> salte, pero quisiera que la tabla apareciera automáticamente después de que<br>
> se acabara la ejecución de mi extensión.<br>
><br>
> He intentado varias formas de evitar el "createWindow", que parece el<br>
> origen del problema (Como crear un Table "t" y hacer un<br>
> "t.setModel(projectTable)" pero entonces el error me salta en este método<br>
> (que como podéis ver está también en el stack del error en tiempo de<br>
> ejecución del "createWindow").<br>
><br>
<br>
<br>
</div></div>Hola Alberto,<br>
mirando el stack de ejecucion tiene pinta de ser un problema de sincronicacion<br>
entre hilos de ejecucion tuyos y el de swing.<br>
Este tipo de errores suelen ser errores bastante comunes. Solo hay que tratarlos<br>
con algo de cuidado. Estan relacionados con como se lleva swing y el multihilo.<br>
Swing no esta pensado para trabajar en un entorno multihilo asi sin mas. Todos<br>
los eventos de swing deben ejecutarse en el hilo de swing. Si tu creas tu propio<br>
hilo y quieres interactuar con el interface grafico debes protegerte de alguna<br>
manera para asegurarte que todas las acciones que hagas relacionadas con el GUI<br>
se ejecuten en el thread de swing.<br>
<br>
Mi primera recomendacion seria que separes la logica de tu proceso del acceso al<br>
GUI, pero a veces eso puede ser bastante complejo. La otra, asegurarte que las<br>
operaciones relacionadas con el GUI se realizan en el hilo de swing, que aunque<br>
parezca algo complejo es relativamente simple.<br>
<br>
En el API de swing tienes tres metodos muy utiles para todo esto:<br>
<br>
- SwingUtilities.isEventDispatchThread, que nos dice si ya estamos ejecutandonos<br>
en el hilo de swing<br>
<br>
- SwingUtilities.invokeLater(Runnable action) que se encarga de encolar la<br>
ejecucion de "action" en el hilo de swing para que se ejecute cuando este pueda.<br>
<br>
- SwingUtilities.invokeAndWait(Runnable action) que se encarga de encolar la peticion<br>
en el hilo de swing y esperar a que esta se ejecute.<br>
<br>
Con estos tres metodos es facil asegurarnos que las partes que tengan que ver con<br>
GUI de nuestros procesos se ejecuten siempre en el hilo de swing. Asi por ejemplo<br>
podriamos hacer algo como:<br>
<br>
final Project project = ext.getProject();<br>
final EditableAdapter auxea=new EditableAdapter();<br>
final String docName = "RIMER Results in: "+tableFile.getName();<br>
<br>
auxea.setOriginalDataSource(sds);<br>
if( !SwingUtilities.isEventDispatchThread() ) {<br>
SwingUtilities.invokeLater(new Runnable() {<br>
public void run() {<br>
<div class="im"> projectTable = ProjectFactory.createTable(docName, auxea);<br>
projectTable.setModel(auxea);<br>
</div> project.addDocument(projectTable);<br>
<div class="im"> IWindow win = projectTable.createWindow();<br>
PluginServices.getMDIManager().addWindow(win);<br>
}<br>
</div> });<br>
}<br>
<br>
He usado el InvokeLater para encolar la accion de actualizar el proyecto y crear<br>
la ventana de la tabla sin esperar a que esto se produzca. Si precisas esperar<br>
a que esto se produzca para seguir haciendo cosas puedes cambiar el<br>
InvokeLater por un InvokeAndWait.<br>
<br>
Lo he picado directamente en el mensaje de correo, asi que no se si he podido<br>
cometer algun error de sintaxis, si es asi disculpas por ello.<br>
<div class="im"><br>
<br>
> El caso es que no sé a qué se puede deber este error. Si al menos pudiera<br>
> encontrar el motivo por el que en el método "enableControls" de la clase<br>
> org.gvsig.andami.ui.mdiFrame salta el runtime error en este bloque:<br>
><br>
</div>> *public* *void* enableControls() {<br>
><br>
> *if* (!*SwingUtilities*.isEventDispatchThread()) {<br>
><br>
> * throw* *new* *RuntimeException*("No Event Dispatch Thread");<br>
<div class="im">><br>
> }<br>
><br>
><br>
> ¿Alguien tiene alguna idea de porqué me<br>
> !SwingUtilities.isEventDispatchThread() en este caso?<br>
><br>
> Cualquier opinión, consejo o ayuda es más que bienvenido, porque esto me<br>
> tiene un poco atascado!<br>
><br>
<br>
<br>
</div>Precisamente aqui, el metodo enableControls, lo que esta haciendo es protegerse<br>
contra que puedas invocar al metodo enableControls desde un hilo que no sea el<br>
de swing. En la version 2 de gvSIG se ha mejorado el soporte multihilo en gvSIG<br>
de forma que muchos metodos, este incluido, se ejecutan automaticamente<br>
en el hilo de swing, sincronizandose ellos mismos sin tener que hacerlo<br>
tu desde fuera. Supongo que aun quedaran muchos por tocar, pero estamos<br>
en ello.<br>
<br>
Espero que te sirva de algo el comentario.<br>
<br>
Por otro lado estoy terminando un pequeño post para el blog de gvSIG<br>
donde habla un poco de todo esto, a ver si lo termino en los proximos<br>
dias.<br>
<br>
Un saludo<br>
Joaquin<br>
<div class="im"><br>
<br>
> Muchísimas gracias de antemano a todos!<br>
><br>
> Un saludo<br>
><br>
> Alberto<br>
><br>
><br>
><br>
><br>
><br>
</div>> _______________________________________________<br>
> gvSIG_desarrolladores mailing list<br>
> <a href="mailto:gvSIG_desarrolladores@listserv.gva.es">gvSIG_desarrolladores@listserv.gva.es</a><br>
> Para ver histórico de mensajes, editar sus preferencias de usuario o darse de baja en esta lista, acuda a la siguiente dirección: <a href="http://listserv.gva.es/cgi-bin/mailman/listinfo/gvsig_desarrolladores" target="_blank">http://listserv.gva.es/cgi-bin/mailman/listinfo/gvsig_desarrolladores</a><br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
--<br>
--------------------------------------<br>
Joaquin Jose del Cerro<br>
Development and software arquitecture manager.<br>
<a href="mailto:jjdelcerro@gvsig.com">jjdelcerro@gvsig.com</a><br>
gvSIG Association<br>
<a href="http://www.gvsig.com" target="_blank">www.gvsig.com</a><br>
<a href="http://www.gvsig.org" target="_blank">www.gvsig.org</a><br>
_______________________________________________<br>
gvSIG_desarrolladores mailing list<br>
<a href="mailto:gvSIG_desarrolladores@listserv.gva.es">gvSIG_desarrolladores@listserv.gva.es</a><br>
Para ver histórico de mensajes, editar sus preferencias de usuario o darse de baja en esta lista, acuda a la siguiente dirección: <a href="http://listserv.gva.es/cgi-bin/mailman/listinfo/gvsig_desarrolladores" target="_blank">http://listserv.gva.es/cgi-bin/mailman/listinfo/gvsig_desarrolladores</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><i><font face="arial, helvetica, sans-serif" color="#666666">-- <br></font></i><div><p style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px">
<i><font face="arial, helvetica, sans-serif" color="#666666"><span style="background-image:initial;background-color:white">Mr Alberto Calzada<br>Full-time PhD Candidate</span><u></u><u></u></font></i></p><p style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px">
<i><font face="arial, helvetica, sans-serif" color="#666666"><span style="background-image:initial;background-color:white">Room 16J25</span> </font></i>
</p></div><div><p style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px"><i><font face="arial, helvetica, sans-serif" color="#666666"><span style="background-image:initial;background-color:white">School of Computing and Mathematics<br>
Faculty of Computing and Engineering</span></font></i></p></div><div><p style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px"><i><font face="arial, helvetica, sans-serif" color="#666666"><span style="background-image:initial;background-color:white">University of Ulster at Jordanstown Campus<br>
Northern Ireland, UK<br>Email: </span><span style="background-image:initial;background-color:white;background-repeat:initial initial"><a href="mailto:Calzada-A@email.ulster.ac.uk" target="_blank">Calzada-A@email.ulster.ac.uk</a></span></font></i></p>
<p style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px"><i><font face="arial, helvetica, sans-serif" color="#666666"><span style="background-image:initial;background-color:white">Tel: </span>
<span style="background-color:rgb(255,255,255)">+44 28 90361114</span> </font></i></p></div><br>
</div>