Programiranje

Navojni navoj in nit za pošiljanje dogodkov

Prejšnja 1 2 3 4 5 Stran 5 Stran 5 od 5

Varnost Swing sukanca

Zadnji korak pri ustvarjanju Swing GUI je zagon. Današnji pravilen zagon Swing GUI se razlikuje od prvotno predpisanega pristopa Sun. Tu je spet citat iz dokumentacije Sun:

Ko je komponenta Swing realizirana, je treba v niti za odpošiljanje dogodkov izvršiti vso kodo, ki bi lahko vplivala na stanje te komponente ali je odvisna od nje.

Zdaj vrzite ta navodila skozi okno, saj so se ob izdaji JSE 1.5 vsi primeri na spletnem mestu Sun spremenili. Od takrat je bilo malo znano dejstvo, da bi morali nenehno dostop Swing komponente na nitki za odpošiljanje dogodkov, da se zagotovi njihova varnost niti / enonitni dostop. Razlog za spremembo je preprost: medtem ko lahko vaš program dostopa do komponente Swing iz niti za odpošiljanje dogodkov, preden je komponenta realizirana, lahko inicializacija uporabniškega vmesnika Swing sproži nekaj, kar bi se zagnalo v niti za odpošiljanje dogodkov, ker komponenta / uporabniški vmesnik pričakuje, da se bo vse zagnalo v niti pošiljanja dogodkov. Delovanje komponent grafičnega uporabniškega vmesnika na različnih nitih prekine Swingov enonitni programski model.

Program iz seznama 5 ni povsem realen, vendar služi kot moja ugotovitev.

Seznam 5. Dostop do stanja komponente Swing iz več niti

uvoz java.awt. *; uvoz java.awt.event. *; uvoz javax.swing. *; javni razred BadSwingButton {public static void main (String args []) {JFrame frame = new JFrame ("Title"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); Gumb JButton = nov JButton ("Pritisnite tukaj"); ContainerListener container = new ContainerAdapter () {public void componentAdded (final ContainerEvent e) {SwingWorker worker = new SwingWorker () {protected String doInBackground () vrže InterruptedException {Thread.sleep (250); vrni null; } zaščitena void storjena () {System.out.println ("Na niti dogodka?:" + EventQueue.isDispatchThread ()); Gumb JButton = (JButton) e.getChild (); Oznaka niza = button.getText (); button.setText (oznaka + "0"); }}; worker.execute (); }}; frame.getContentPane (). addContainerListener (vsebnik); frame.add (gumb, BorderLayout.CENTER); frame.setSize (200, 200); poskusite {Thread.sleep (500); } catch (InterruptedException e) {} System.out.println ("Kmalu bom realiziran:" + EventQueue.isDispatchThread ()); frame.setVisible (true); }}

Upoštevajte, da izhod prikazuje neko kodo, ki se izvaja v glavni niti pred realizacijo uporabniškega vmesnika. To pomeni, da se koda za inicializacijo izvaja v eni niti, medtem ko se druga koda uporabniškega vmesnika izvaja v niti za pošiljanje dogodkov, kar prekine Swingov enonitni model dostopa:

> java BadSwingButton V niti dogodka? : true Kmalu bom realiziran: false

Program iz seznama 5 bo posodobil oznako gumba iz poslušalca vsebnika, ko bo gumb dodan v vsebnik. Če želite narediti scenarij bolj realističen, si predstavljajte uporabniški vmesnik, ki v njem "šteje" oznake in štetje uporablja kot besedilo v naslovu obrobe. Seveda bi moral posodobiti besedilo naslova obrobe v niti za pošiljanje dogodkov. Da bo stvar preprosta, program samo posodobi oznako enega gumba. Čeprav program ni realističen, prikazuje težavo z vsak Swing program, ki je bil napisan od začetka Swingovega časa. (Ali vsaj vsi, ki so sledili priporočenemu modelu navojev, ki ga najdemo v javadocs in spletnih vadnicah podjetja Sun Microsystems in celo v mojih zgodnjih izdajah programskih knjig Swing.)

Gugalni navoj narejen pravilno

Pot do pravilnega navoja Swinga je pozabiti prvotni Sun-ov izrek. Ne skrbite, ali je komponenta realizirana ali ne. Ne trudite se ugotoviti, ali je varno dostopati do nečesa iz niti za odpošiljanje dogodkov. Nikoli ni. Namesto tega ustvarite celoten uporabniški vmesnik v niti pošiljanja dogodkov. Če postavite celoten klic za ustvarjanje uporabniškega vmesnika v EventQueue.invokeLater () vsi dostopi med inicializacijo bodo zagotovljeni v niti za pošiljanje dogodkov. Tako preprosto je.

Seznam 6. Vse na svojem mestu

uvoz java.awt. *; uvoz java.awt.event. *; uvoz javax.swing. *; javni razred GoodSwingButton {public static void main (String args []) {Runnable runner = new Runnable () {public void run () {JFrame frame = new JFrame ("Title"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); Gumb JButton = nov JButton ("Pritisnite tukaj"); ContainerListener container = new ContainerAdapter () {public void componentAdded (final ContainerEvent e) {SwingWorker worker = new SwingWorker () {protected String doInBackground () vrže InterruptedException {return null; } zaščitena void done () {System.out.println ("Na niti dogodka?:" + EventQueue.isDispatchThread ()); Gumb JButton = (JButton) e.getChild (); Oznaka niza = button.getText (); button.setText (oznaka + "0"); }}; worker.execute (); }}; frame.getContentPane (). addContainerListener (vsebnik); frame.add (gumb, BorderLayout.CENTER); frame.setSize (200, 200); System.out.println ("Kmalu bom realiziran:" + EventQueue.isDispatchThread ()); frame.setVisible (true); }}; EventQueue.invokeLater (tekač); }}

Zaženite ga zdaj in zgornji program bo pokazal, da se v niti za pošiljanje dogodkov izvajata tako inicializacija kot koda vsebnika:

> java GoodSwingButton Kmalu bom realiziran: true V niti dogodka? : prav

V zaključku

Dodatno delo za ustvarjanje uporabniškega vmesnika v niti za odpošiljanje dogodkov se sprva zdi nepotrebno. Navsezadnje vsi to počnejo drugače. Zakaj bi se zdaj trudil spremeniti? Stvar je v tem, da smo to vedno delali narobe. Za zagotovitev pravilnega dostopa do komponent Swing morate vedno ustvariti celoten uporabniški vmesnik v niti za pošiljanje dogodkov, kot je prikazano tukaj:

Runnable runner = new Runnable () {public void run () {// ... ustvari uporabniški vmesnik tukaj ...}} EventQueue.invokeLater (runner);

Premikanje vaše inicializacijske kode v nit za odpošiljanje dogodkov je edini način, da zagotovite, da so vaši grafični vmesniki Swing varni za nit. Da, sprva se bo počutil neprijetno, a napredek se običajno.

John Zukowski se že več kot 12 let igra z Javo, saj je svojo miselnost C in X-Windows že zdavnaj opustil. Z 10 knjigami o temah od Swinga do zbirk do Jave SE 6 John zdaj s svojim podjetjem JZ Ventures, Inc.

Preberite več o tej temi

  • Več o programiranju Swing in niti za pošiljanje dogodkov najdete pri enem od mojstrov razvoja namizja Java: Chet Haase o maksimiziranju Swinga in Java 2D (podcast JavaWorld Java Technology Insider, avgust 2007).
  • "Prilagodi SwingWorker za izboljšanje grafičnih uporabniških vmesnikov Swing" (Yexin Chen, JavaWorld, junij 2003) se poglobi v nekatere izzive Swing navojev, obravnavane v tem članku, in razloži, kako prilagojena SwingWorker lahko mišicam omogoči, da jih obidejo.
  • "Java in obdelava dogodkov" (Todd Sundsted, JavaWorld, avgust 1996) je temeljna beseda o ravnanju z dogodki okoli AWT.
  • "Pospeši obveščanje poslušalcev" (Robert Hastings, JavaWorld, februar 2000) uvaja specifikacijo JavaBeans 1.0 za registracijo dogodkov in obveščanje.
  • "Dosezite močno zmogljivost z nitmi, 1. del" (Jeff Friesen, JavaWorld, maj 2002) uvaja niti Java. Za odgovor na vprašanje glejte 2. del: Zakaj potrebujemo sinhronizacijo?
  • "Izvajanje nalog v nitih" je izvleček JavaWorlda iz Java sočasnost v praksi (Brian Goetz in sod., Addison Wesley Professional, maj 2006), ki spodbuja programiranje niti, ki temelji na opravilih, in uvaja izvedbeni okvir za upravljanje nalog.
  • "Threads and Swing" (Hans Muller in Kathy Walrath, april 1998) je ena prvih uradnih referenc za Swing navoja. Vključuje zdaj znano (in zmotno) "pravilo z eno nitjo".
  • Ustvarjanje grafičnega uporabniškega vmesnika z JFC / Swing je obsežna stran Java Vadnica za programiranje grafičnega vmesnika Swing.
  • "Concurrency in Swing" je vadnica o Swing poti, ki vključuje uvod v SwingWorker razred.
  • JSR 296: Swing Application Framework je trenutno v teku specifikacija. Glejte tudi "Uporaba okvira aplikacij Swing" (John O'Conner, Sun Developer Network, julij 2007), če želite izvedeti več o naslednjem koraku v razvoju programiranja Swing GUI.
  • Celotna referenca Java AWT (John Zukowski, O'Reilly, marec 1997) je na voljo brezplačno v spletnem katalogu O'Reilly.
  • John's Definitive Guide to Java Swing, Third Edition (Apress, junij 2005) je popolnoma posodobljen za različico Java Standard Edition 5.0. Preberite poglavje predogleda iz knjige tukaj JavaWorld!
  • Za več člankov o programiranju Swing in razvoju namizja Java obiščite raziskovalno središče JavaWorld Swing / GUI.
  • Oglejte si tudi forume razvijalcev JavaWorld, kjer najdete razprave in vprašanja o Swingu in namiznem programiranju Java.

To zgodbo, "Swing Threading in nit za pošiljanje dogodkov", je prvotno objavil JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found