Editor PHP Strawberry memperkenalkan kepada anda Soal Jawab Java tentang isu penyegerakan antara GraphStream's View dan JTextField dalam artikel ini. Apabila menggunakan pustaka GraphStream, anda kadangkala menghadapi cabaran dengan penyegerakan data antara View dan JTextField. Melalui artikel ini, anda akan belajar bagaimana untuk menyelesaikan masalah ini dan menjadikan program Java anda lebih lancar dan lebih cekap.
Saya telah menyiarkan isu saya di https://github.com/graphstream/gs-ui-swing/issues/19#issue-2109865450. Tetapi memandangkan jawapan terakhir pada repositori ini telah disiarkan pada 10 Jun 2021, dan soalan lain telah disiarkan tanpa sebarang balasan, saya tidak pasti sama ada sesiapa masih memberi perhatian kepada soalan di sana. Itulah sebabnya saya bertanya semula soalan saya di sini.
Saya mencipta jframe yang terdiri daripada paparan dan dua medan jtext:
Paparan menunjukkan lima nod: empat hanyalah tanda tempat dan tidak dijangka dialihkan oleh pengguna ("fixed_*"), dan satu akan dialihkan oleh pengguna ("unfixed"). Dua jtextfields memaparkan koordinat nod "tidak disematkan". Kedua-dua paparan dan jtextfield mesti selari antara satu sama lain. Malah, apabila pengguna mengalihkan nod "tidak disematkan" dalam paparan, kedua-dua medan jtext mesti dikemas kini dengan sewajarnya:
Sebaliknya, apabila pengguna mengubah suai koordinat dalam salah satu medan jtext, paparan juga mesti dikemas kini dengan sewajarnya:
Berikut adalah empat kes ujian:
Kes ujian 1, 2 dan 3 berfungsi dengan baik tetapi kes ujian 4 tidak berfungsi. Malah, dalam kes ujian 4, sebaik sahaja pengguna mengalihkan nod "tidak disematkan" dalam paparan, pengubahsuaian pada koordinat dalam salah satu medan jtext tidak mengemas kini paparan.
Saya cuba menganalisis perbezaan antara pelaksanaan kes ujian 3 dan 4. Untuk melakukan ini, saya mencetak nama benang semasa di pelbagai tempat dalam kod. Saya melihat bahawa pengubahsuaian melalui jtextfield dijalankan pada utas "awt-eventqueue-0" (benang penghantar acara swing, bukan?), manakala pengubahsuaian melalui paparan dijalankan pada utas "thread-0". Dalam pelaksanaan saya, "benang-0" ialah utas yang saya jalankan gelung pam graphstream, menunggu peristiwa yang berlaku dalam utas pemapar graphstream dan menyalinnya kembali dalam "benang-0". Daripada pemahaman saya tentang dokumentasi aliran graf:
Adakah saya memahami sepenuhnya dokumentasi?
Dalam pelaksanaan saya, saya memilih untuk mengakses graf aliran graf daripada utas lain di luar utas ayunan. Jadi, saya simpulkan daripada kes ujian 3 dan 4 yang dijalankan sebelum ini:
Saya mendapat tanggapan bahawa saya melakukan perkara yang salah dengan semua rangkaian ini. Boleh kamu bantu saya?
Saya cuba membuat contoh kerja minimum (mwe) untuk menghasilkan semula masalah saya. Berikut ialah kandungan fail sumber java nodesynctest.java:
package mwe; import java.awt.borderlayout; import java.awt.component; import java.awt.gridlayout; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.util.map; import javax.swing.borderfactory; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.jpanel; import javax.swing.jtextfield; import javax.swing.swingconstants; import org.apache.commons.lang3.math.numberutils; import org.graphstream.graph.graph; import org.graphstream.graph.node; import org.graphstream.graph.implementations.multigraph; import org.graphstream.ui.graphicgraph.graphicgraph; import org.graphstream.ui.graphicgraph.graphicnode; import org.graphstream.ui.swing_viewer.swingviewer; import org.graphstream.ui.view.view; import org.graphstream.ui.view.viewer; import org.graphstream.ui.view.viewerlistener; import org.graphstream.ui.view.viewerpipe; class nodesynctest { public static void main(string[] args) { system.out.println("nodesynctest.main : " + thread.currentthread().getname()); javax.swing.swingutilities.invokelater(new runnable() { @override public void run() { system.out.println("swingutilities.invokelater.runnable.run : " + thread.currentthread().getname()); new nodesynctest(); } }); } nodesynctest() { map<string, mynode> mynodes = map.of( "fixed_top_left", new mynode(-2, 2), "fixed_top_right", new mynode(2, 2), "fixed_bottom_left", new mynode(-2, -2), "fixed_bottom_right", new mynode(2, -2), "unfixed", new mynode(0, 0) ); graphstreamcontrol graphstreamcontrol = new graphstreamcontrol(mynodes); jtextfieldscontrol jtextfieldscontrol = new jtextfieldscontrol(mynodes); graphstreamcontrol.jtextfieldscontrol = jtextfieldscontrol; jtextfieldscontrol.graphstreamcontrol = graphstreamcontrol; graphstreamcontrol.fillgraphstreamgraph(); jframe maindialog = new jframe(); maindialog.setdefaultcloseoperation(jframe.exit_on_close); maindialog.setsize(300, 300); maindialog.getcontentpane().add((component) graphstreamcontrol.view, borderlayout.center); maindialog.getcontentpane().add(jtextfieldscontrol.panel, borderlayout.south); maindialog.setlocationrelativeto(null); maindialog.setvisible(true); graphstreamcontrol.startpumploop(); } class graphstreamcontrol { map<string, mynode> mynodes; mynode myunfixednode; graph graphstreamgraph; viewer viewer; view view; viewerpipe viewerpipe; jtextfieldscontrol jtextfieldscontrol; graphstreamcontrol(map<string, mynode> mynodes) { this.mynodes = mynodes; myunfixednode = mynodes.get("unfixed"); system.setproperty("org.graphstream.ui", "swing"); graphstreamgraph = new multigraph(""); viewer = new swingviewer(graphstreamgraph, viewer.threadingmodel.graph_in_another_thread); viewer.disableautolayout(); view = viewer.adddefaultview(false); viewerpipe = viewer.newviewerpipe(); viewerpipe.addsink(graphstreamgraph); viewerpipe.addviewerlistener(new viewerlistener() { @override public void viewclosed(string viewname) {} @override public void buttonpushed(string id) {} @override public void buttonreleased(string id) { system.out.println("viewerlistener.buttonreleased : " + thread.currentthread().getname()); if ("unfixed".equals(id)) { graphicgraph graphicgraph = viewer.getgraphicgraph(); graphicnode unfixedgraphstreamnode = (graphicnode) graphicgraph.getnode("unfixed"); myunfixednode.x = unfixedgraphstreamnode.getx(); myunfixednode.y = unfixedgraphstreamnode.gety(); jtextfieldscontrol.update(); } } @override public void mouseover(string id) {} @override public void mouseleft(string id) {} }); } public void fillgraphstreamgraph() { for (var entry : mynodes.entryset()) { string nodeid = entry.getkey(); mynode mynode = entry.getvalue(); node graphstreamnode = graphstreamgraph.addnode(nodeid); graphstreamnode.setattribute("xy", mynode.x, mynode.y); graphstreamnode.setattribute("ui.label", nodeid); graphstreamnode.setattribute("ui.style", "text-alignment: under;"); } } void startpumploop() { new thread(() -> { system.out.println("graphstreamcontrol.startpumploop : " + thread.currentthread().getname()); while (true) { try { viewerpipe.blockingpump(); } catch (interruptedexception e) { e.printstacktrace(); } } }).start(); } void update() { graphicgraph graphicgraph = viewer.getgraphicgraph(); graphicnode unfixedgraphstreamnode = (graphicnode) graphicgraph.getnode("unfixed"); unfixedgraphstreamnode.setattribute("xy", myunfixednode.x, myunfixednode.y); } } class jtextfieldscontrol { map<string, mynode> mynodes; mynode myunfixednode; jpanel panel; jtextfield xtextfield; jtextfield ytextfield; graphstreamcontrol graphstreamcontrol; jtextfieldscontrol(map<string, mynode> mynodes) { this.mynodes = mynodes; myunfixednode = mynodes.get("unfixed"); panel = new jpanel(new gridlayout(1, 4)); jlabel xlabel = new jlabel("x:", swingconstants.right); xlabel.setborder(borderfactory.createemptyborder(5, 5, 5, 5)); panel.add(xlabel); xtextfield = new jtextfield(3); xtextfield.sethorizontalalignment(swingconstants.right); xtextfield.settext(double.tostring(myunfixednode.x)); xtextfield.getcaret().setdot(0); xtextfield.addactionlistener(new actionlistener() { public void actionperformed(actionevent event) { system.out.println("jtextfieldscontrol - actionperformed on xtextfield : " + thread.currentthread().getname()); string xnodestring = xtextfield.gettext(); double xnodedouble = numberutils.todouble(xnodestring); myunfixednode.x = xnodedouble; graphstreamcontrol.update(); } }); panel.add(xtextfield); jlabel ylabel = new jlabel("y:", swingconstants.right); ylabel.setborder(borderfactory.createemptyborder(5, 5, 5, 5)); panel.add(ylabel); ytextfield = new jtextfield(3); ytextfield.sethorizontalalignment(swingconstants.right); ytextfield.settext(double.tostring(myunfixednode.y)); ytextfield.getcaret().setdot(0); ytextfield.addactionlistener(new actionlistener() { public void actionperformed(actionevent event) { system.out.println("jtextfieldscontrol - actionperformed on ytextfield : " + thread.currentthread().getname()); string ynodestring = ytextfield.gettext(); double ynodedouble = numberutils.todouble(ynodestring); myunfixednode.y = ynodedouble; graphstreamcontrol.update(); } }); panel.add(ytextfield); } void update() { string xnodestring = double.tostring(myunfixednode.x); xtextfield.settext(xnodestring); xtextfield.getcaret().setdot(0); string ynodestring = double.tostring(myunfixednode.y); ytextfield.settext(ynodestring); ytextfield.getcaret().setdot(0); } } class mynode { double x; double y; mynode(double x, double y) { this.x = x; this.y = y; } } }
Ini ialah fail pom maven pom.xml yang digunakan untuk membina balang boleh laku dengan semua kebergantungan:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>mwe</groupId> <artifactId>mwe</artifactId> <version>0.0.1-SNAPSHOT</version> <name>MWE</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.14.0</version> </dependency> <dependency> <groupId>org.graphstream</groupId> <artifactId>gs-core</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>org.graphstream</groupId> <artifactId>gs-ui-swing</artifactId> <version>2.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <!-- Build an executable JAR --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.1.0</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <!-- here we specify that we want to use the main method within the App class --> <mainClass>mwe.NodeSyncTest</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>mwe.NodeSyncTest</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> </build> </project>
Untuk menggunakan kedua-dua fail ini, cuma buat folder mwe/, masukkan nodesynctest.java ke dalam mwe/src/main/java/mwe/ dan pom.xml ke dalam mwe/, kemudian jalankan dalam mwe/
mvn 编译程序集:single
dan
java -jar 目标/mwe-0.0.1-snapshot-jar-with-dependency.jar
Ini ialah folder projek lengkap: mwe.zip
Selepas beberapa nyahpepijat, akhirnya saya menemui masalahnya. Saya cuma perlu tukar talian :
unfixedgraphstreamnode.setattribute("xy", myunfixednode.x, myunfixednode.y);
Dengan dua baris:
unfixedgraphstreamnode.setattribute("x", myunfixednode.x); unfixedgraphstreamnode.setattribute("y", myunfixednode.y);
Semuanya berfungsi dengan baik.
Kenapa
unfixedgraphstreamnode.setattribute("xy", myunfixednode.x, myunfixednode.y);
Tidak bekerja masih menjadi misteri bagi saya. Malah, dokumentasi untuk https://www.php.cn/link/c305a250710e95cf6bad18c18a1c02f4 dan https://www.php.cn/link/7c097a5ed40a8d91afd49026 boleh digunakan. Jadi saya cuba menukar kod kepada: xy
属性来设置节点的坐标。但也鼓励使用属性 xyz
unfixedGraphStreamNode.setAttribute("xyz", myUnfixedNode.x, myUnfixedNode.y, 0.0);
并且它有效!我将在项目的 github 存储库上发布问题。
Atas ialah kandungan terperinci Isu penyegerakan antara GraphStream's View dan JTextField. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!