Programavimas

Sūpynės sriegimas ir renginio siuntimo siūlas

Ankstesnis 1 2 3 4 5 5 puslapis 5 puslapis iš 5

Saugokite sūpynės siūlus

Paskutinis žingsnis kuriant „Swing“ GUI yra jo paleidimas. Teisingas būdas pradėti „Swing“ GUI šiandien skiriasi nuo „Sun“ iš pradžių nustatyto požiūrio. Čia dar kartą pateikiama citata iš „Sun“ dokumentų:

Suvokus „Swing“ komponentą, visas kodas, kuris gali turėti įtakos ar priklausyti nuo to komponento būsenos, turėtų būti vykdomas įvykių siuntimo gijoje.

Dabar išmeskite šias instrukcijas pro langą, nes maždaug tada, kai buvo išleista JSE 1.5, visi „Sun“ svetainės pavyzdžiai pasikeitė. Nuo to laiko tai yra mažai žinomas faktas, kurį jūs manote visada prieiga Pasukite komponentus ant įvykio-siuntimo sriegio, kad užtikrintumėte jų sriegio saugumą / prieigą prie vieno sriegio. Pakeitimo priežastis yra paprasta: nors jūsų programa gali pasiekti „Swing“ komponentą iš įvykio-siuntimo gijos, kol dar nėra realizuotas, „Swing“ vartotojo sąsajos inicijavimas gali paskatinti kažką paleisti įvykio-siuntimo gijoje vėliau, nes komponentas / vartotojo sąsaja tikisi viską paleisti įvykio-siuntimo gijoje. Jei GUI komponentai veikia skirtingomis gijomis, sulaužomas „Swing“ vieno sriegio programavimo modelis.

5 sąraše esanti programa nėra gana tikroviška, tačiau ji man tinka.

Sąrašas 5. Prieiga prie „Swing“ komponento būsenos iš kelių gijų

importuoti java.awt. *; importuoti java.awt.event. *; importuoti javax.swing. *; public class BadSwingButton {public static void main (String args []) {JFrame frame = new JFrame ("Title"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JButton mygtukas = naujas JButton („Paspauskite čia“); ContainerListener container = new ContainerAdapter () {public void componentAdded (final ContainerEvent e) {SwingWorker worker = new SwingWorker () {protected String doInBackground () throws InterruptedException {Thread.sleep (250); return null; } protected void done () {System.out.println ("Ant įvykio gijos?:" + EventQueue.isDispatchThread ()); JButton mygtukas = (JButton) e.getChild (); Eilutės etiketė = button.getText (); button.setText (etiketė + "0"); }}; darbuotojas.vykdyti (); }}; frame.getContentPane (). addContainerListener (sudėtinis rodinys); frame.add (mygtukas, BorderLayout.CENTER); frame.setSize (200, 200); pabandykite {Thread.sleep (500); } catch (InterruptedException e) {} System.out.println ("Aš tuoj suprantu:" + EventQueue.isDispatchThread ()); frame.setVisible (true); }}

Atkreipkite dėmesį, kad išvestis rodo tam tikrą kodą, veikiantį pagrindinėje gijoje, prieš pradedant realizuoti vartotojo sąsają. Tai reiškia, kad inicijavimo kodas veikia vienoje gijoje, o kitas vartotojo sąsajos kodas veikia įvykio-siuntimo gijoje, o tai sulaužo „Swing“ vienos gijos prieigos modelį:

> java BadSwingButton Įvykio gijoje? : tiesa Aš tuoj suprasiu: melas

5 sąraše esanti programa atnaujins mygtuko etiketę iš talpyklų klausytojo, kai mygtukas bus pridėtas prie sudėtinio rodinio. Kad scenarijus būtų realistiškesnis, įsivaizduokite vartotojo sąsają, kuri joje „skaičiuoja“ etiketes ir skaičiavimą naudoja kaip tekstą krašto pavadinime. Natūralu, kad reikės atnaujinti sienos pavadinimo tekstą įvykio-išsiuntimo gijoje. Kad viskas būtų paprasta, programa tiesiog atnaujina vieno mygtuko etiketę. Nors ši programa nėra reali, ši programa parodo problemą kiekvienas „Swing“ programa, parašyta nuo „Swing“ laiko pradžios. (Arba bent jau visi tie, kurie laikėsi rekomenduojamo siūlų modelio, esančio „javadocs“ ir internetinėse „Sun Microsystems“ pamokose, ir net mano paties ankstyvajame „Swing“ programavimo knygų leidime.)

Sūpynės sriegis atliktas teisingai

Tinkamas „Swing“ sriegimas yra pamiršti originalų „Sun“ diktumą. Nesijaudinkite, ar komponentas realizuotas, ar ne. Nesivarginkite bandydami išsiaiškinti, ar saugu prieiti prie įvykio-siuntimo gijos. Niekada nėra. Vietoj to, sukurkite visą vartotojo sąsają įvykio-siuntimo gijoje. Jei visą vartotojo sąsajos kūrimo skambutį įdėsite į EventQueue.invokeLater () visos prieigos per inicializavimą garantuojamos įvykio-siuntimo gijoje. Tai taip paprasta.

Išvardinimas 6. Viskas savo vietose

importuoti java.awt. *; importuoti java.awt.event. *; importuoti javax.swing. *; public class „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); JButton mygtukas = naujas JButton („Paspauskite čia“); ContainerListener container = new ContainerAdapter () {public void componentAdded (final ContainerEvent e) {SwingWorker worker = new SwingWorker () {protected String doInBackground () throws InterruptedException {return null; } protected void done () {System.out.println ("Ant įvykio gijos?:" + EventQueue.isDispatchThread ()); JButton mygtukas = (JButton) e.getChild (); Eilutės etiketė = button.getText (); button.setText (etiketė + "0"); }}; darbuotojas.vykdyti (); }}; frame.getContentPane (). addContainerListener (sudėtinis rodinys); frame.add (mygtukas, BorderLayout.CENTER); frame.setSize (200, 200); System.out.println ("Aš jau suprantu:" + EventQueue.isDispatchThread ()); frame.setVisible (true); }}; EventQueue.invokeLater (bėgikas); }}

Paleiskite jį dabar ir pirmiau nurodyta programa parodys, kad tiek inicijavimas, tiek sudėtinio rodinio kodas veikia įvykio-siuntimo gijoje:

> java GoodSwingButton Mane jau supras: tiesa Apie renginio giją? : tiesa

Apibendrinant

Iš pradžių gali atrodyti, kad nereikalingas papildomas darbas, skirtas sukurti vartotojo sąsają renginio siuntimo gijoje. Visi nuo pat pradžių vis dėlto tai darė kitaip. Kam vargti keistis dabar? Reikalas tas, kad mes visada tai darėme neteisingai. Norėdami užtikrinti, kad prie jūsų „Swing“ komponentų būtų prieinama teisingai, visada turėtumėte sukurti visą vartotojo sąsają įvykio-išsiuntimo gijoje, kaip parodyta čia:

Runnable runner = naujas Runnable () {public void run () {// ... čia sukurkite vartotojo sąsają ...}} EventQueue.invokeLater (runner);

Inicializavimo kodo perkėlimas į įvykio-siuntimo giją yra vienintelis būdas užtikrinti, kad jūsų „Swing“ GUI būtų saugūs. Taip, iš pradžių tai jausis nepatogiai, tačiau pažanga dažniausiai būna.

Johnas Zukowskis jau daug daugiau nei 12 metų žaidžia su „Java“, jau seniai atsisakęs savo „C“ ir „X-Windows“ mąstysenos. Turėdamas 10 knygų temomis nuo „Swing“ iki kolekcijų iki „Java SE 6“, Jonas savo versle „JZ Ventures, Inc.“ konsultuoja strategines technologijas.

Sužinokite daugiau apie šią temą

  • Sužinokite daugiau apie „Swing“ programavimą ir įvykių siuntimo gijas iš vieno iš „Java“ darbalaukio kūrimo meistrų: Chet Haase apie „Swing“ ir „Java 2D“ maksimalizavimą („JavaWorld Java Technology Insider“ tinklalaidė, 2007 m. Rugpjūtis).
  • „Tinkinkite„ SwingWorker “, kad patobulintumėte„ Swing GUI “(Yexin Chen, JavaWorld, 2003 m. Birželio mėn.) Gilinamasi į kai kuriuos šiame straipsnyje aptartus„ Swing “siūlų iššūkius ir paaiškinama, kaip pritaikyti „SwingWorker“ gali suteikti raumeniui apeiti juos.
  • „Java ir įvykių tvarkymas“ (Toddas Sundstedas, „JavaWorld“, 1996 m. Rugpjūtis) yra įvykių tvarkymo apie AWT pradžia.
  • „Spartinkite klausytojų pranešimus“ (Robertas Hastingsas, „JavaWorld“, 2000 m. Vasaris) pristato „JavaBeans 1.0“ specifikaciją renginių registravimui ir pranešimams.
  • „Pasiekite gerą našumą naudodami gijas, 1 dalis“ (Jeffas Friesenas, „JavaWorld“, 2002 m. Gegužė) pristato „Java“ gijas. 2 dalyje rasite atsakymą į klausimą: Kodėl mums reikia sinchronizavimo?
  • „Užduočių vykdymas gijomis“ yra „JavaWorld“ ištrauka iš „Java“ lygiagretumas praktikoje (Brian Goetz ir kt., Addison Wesley Professional, 2006 m. Gegužė), kuris skatina užduotimis pagrįstą gijų programavimą ir įveda užduočių valdymo vykdymo sistemą.
  • „Siūlai ir sūpynės“ (Hansas Mulleris ir Kathy Walrathas, 1998 m. Balandžio mėn.) Yra viena iš ankstyviausių oficialių „Swing“ sriegimo nuorodų. Ji apima dabar žinomą (ir klaidingą) „vienos gijos taisyklę“.
  • GUI sukūrimas naudojant JFC / Swing yra išsamus „Java Tutorial“ puslapis, skirtas „Swing GUI“ programavimui.
  • „Lygiagretumas sūpynėse“ yra „Sūpynių tako“ pamoka, apimanti įvadą į „SwingWorker“ klasė.
  • JSR 296: „Swing Application Framework“ šiuo metu vykdoma specifikacija. Taip pat žr. „Swing Application Framework naudojimas“ (John O'Conner, „Sun Developer Network“, 2007 m. Liepos mėn.), Kad sužinotumėte daugiau apie šį kitą „Swing“ GUI programavimo evoliucijos žingsnį.
  • Visą „Java AWT Reference“ (John Zukowski, O'Reilly, 1997 m. Kovo mėn.) Galima nemokamai rasti „O'Reilly Online“ kataloge.
  • „John's Definitive Guide to Java Swing, Third Edition“ („Apress“, 2005 m. Birželio mėn.) Yra visiškai atnaujintas „Java Standard Edition“ 5.0 versijai. Skaitykite knygos peržiūros skyrių čia „JavaWorld“!
  • Apsilankykite „JavaWorld Swing“ / GUI tyrimų centre, kur rasite daugiau straipsnių apie „Swing“ programavimą ir „Java“ darbalaukio kūrimą.
  • Taip pat peržiūrėkite „JavaWorld“ kūrėjų forumus, kuriuose rasite diskusijas ir klausimus bei atsakymus, susijusius su „Swing“ ir „Java“ darbalaukio programavimu.

Šią istoriją „Swing threading and the event-dispatch thread“ iš pradžių paskelbė „JavaWorld“.