Programmēšana

Šūpoles vītne un notikuma-nosūtīšanas vītne

Iepriekšējais 1 2 3 4 5 5. lpp 5. lapa no 5

Saglabājiet Swing diegu drošībā

Pēdējais solis Swing GUI izveidē ir tā palaišana. Pareizais Swing GUI palaišanas veids šodien atšķiras no Sun sākotnēji noteiktās pieejas. Atkal ir citāts no Sun dokumentācijas:

Kad Swing komponents ir realizēts, viss kods, kas var ietekmēt vai būt atkarīgs no šī komponenta stāvokļa, ir jāizpilda notikumu nosūtīšanas pavedienā.

Tagad izmetiet šīs instrukcijas pa logu, jo ap JSE 1.5 izlaišanu visi Sun vietnes piemēri mainījās. Kopš tā laika jums ir maz zināms fakts vienmēr piekļuve Šūpojiet komponentus notikuma-nosūtīšanas vītnē, lai nodrošinātu to vītnes drošību / piekļuvi ar vienu vītni. Izmaiņu iemesls ir vienkāršs: lai gan jūsu programma var piekļūt Swing komponentam no notikuma-nosūtīšanas pavediena pirms komponenta realizācijas, Swing lietotāja saskarnes inicializēšana var izraisīt kaut ko palaist notikuma-nosūtīšanas pavedienā pēc tam, jo komponents / lietotāja saskarne sagaida, ka viss tiks palaists notikuma-nosūtīšanas pavedienā. GUI komponentu palaišana ar dažādiem pavedieniem pārtrauc Swing vienvītņoto programmēšanas modeli.

Programma, kas iekļauta 5. sarakstā, nav gluži reāla, bet kalpo tam, lai paustu savu viedokli.

Saraksts 5. Piekļuve Swing komponenta stāvoklim no vairākiem pavedieniem

importēt java.awt. *; importēt java.awt.event. *; importēt javax.swing. *; public class BadSwingButton {public static void main (String args []) {JFrame frame = new JFrame ("Nosaukums"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JButton button = new JButton ("Nospiediet šeit"); 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 ("Par notikuma pavedienu?:" + EventQueue.isDispatchThread ()); JButton button = (JButton) e.getChild (); Virknes etiķete = button.getText (); button.setText (etiķete + "0"); }}; darbinieks.izpilda (); }}; frame.getContentPane (). addContainerListener (konteiners); frame.add (poga, BorderLayout.CENTER); frame.setSize (200, 200); izmēģiniet {Thread.sleep (500); } catch (InterruptedException e) {} System.out.println ("Es tikšu realizēts:" + EventQueue.isDispatchThread ()); frame.setVisible (true); }}

Ievērojiet, ka izejā tiek parādīts kods, kas darbojas galvenajā pavedienā pirms lietotāja saskarnes realizēšanas. Tas nozīmē, ka inicializācijas kods darbojas vienā pavedienā, kamēr cits lietotāja saskarnes kods darbojas notikuma-nosūtīšanas pavedienā, kas pārtrauc Swing vienvītnes piekļuves modeli:

> java BadSwingButton Par notikuma pavedienu? : taisnība Mani drīz sapratīs: nepatiesu

5. saraksta programma atjauninās pogas etiķeti no konteineru klausītāja, kad poga tiks pievienota konteineram. Lai scenārijs būtu reālistiskāks, iedomājieties lietotāja interfeisu, kas tajā "saskaita" etiķetes un izmanto skaitli kā tekstu apmales nosaukumā. Protams, tam būtu jāatjaunina apmales virsraksta teksts notikuma-nosūtīšanas pavedienā. Lai viss būtu vienkārši, programma vienkārši atjaunina vienas pogas etiķeti. Kaut arī funkcija nav reāla, šī programma parāda problēmu ar katrs Šūpoles programma, kas ir rakstīta kopš Swing laika sākuma. (Vai vismaz visi tie, kas sekoja ieteiktajam pavedienu modelim, kas atrodams javadocs un Sun Microsystems tiešsaistes apmācībās un pat manos pašos agrīnajos Swing programmēšanas grāmatu izdevumos.)

Šūpoles vītnes izdarītas pareizi

Veids, kā pareizi iegūt Swing vītni, ir aizmirst Sun sākotnējo dictum. Neuztraucieties par to, vai komponents tiek realizēts vai nē. Neuztraucieties, mēģinot noteikt, vai ir droši piekļūt kaut kam ārpus notikuma-nosūtīšanas pavediena. Tā nekad nav. Tā vietā izveidojiet visu lietotāja saskarni notikuma-nosūtīšanas pavedienā. Ja visu lietotāja saskarnes izveides zvanu ievietojat EventQueue.invokeLater () visas piekļuves inicializācijas laikā tiek garantētas notikuma-nosūtīšanas pavedienā. Tas ir tik vienkārši.

Uzskaitījums 6. Viss savās vietās

importēt java.awt. *; importēt java.awt.event. *; importēt javax.swing. *; public class GoodSwingButton {public static void main (String args []) {Runnable runner = new Runnable () {public void run () {JFrame frame = new JFrame ("Nosaukums"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JButton button = new JButton ("Nospiediet šeit"); 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 ("Par notikuma pavedienu?:" + EventQueue.isDispatchThread ()); JButton button = (JButton) e.getChild (); Virknes etiķete = button.getText (); button.setText (etiķete + "0"); }}; darbinieks.izpilda (); }}; frame.getContentPane (). addContainerListener (konteiners); frame.add (poga, BorderLayout.CENTER); frame.setSize (200, 200); System.out.println ("Es tikšu realizēts:" + EventQueue.isDispatchThread ()); frame.setVisible (true); }}; EventQueue.invokeLater (skrējējs); }}

Palaidiet to tūlīt, un iepriekš minētā programma parādīs, ka notikuma-nosūtīšanas pavedienā darbojas gan inicializācija, gan konteinera kods:

> java GoodSwingButton Mani drīz sapratīs: taisnība Vai uz notikuma pavedienu? : taisnība

Noslēgumā

Sākotnēji papildu darbs, lai izveidotu lietotāja saskarni notikuma-nosūtīšanas pavedienā, varētu šķist nevajadzīgs. Galu galā visi to ir darījuši citādi. Kāpēc jāuztraucas mainīt tagad? Lieta ir tāda, ka mēs vienmēr to darījām nepareizi. Lai nodrošinātu pareizu piekļuvi jūsu Swing komponentiem, jums vienmēr jāizveido viss lietotāja interfeiss notikuma-nosūtīšanas pavedienā, kā parādīts šeit:

Runnable runner = jauns Runnable () {public void run () {// ... izveidojiet šeit lietotāja interfeisu ...}} EventQueue.invokeLater (runner);

Inicializācijas koda pārvietošana uz notikuma-nosūtīšanas pavedienu ir vienīgais veids, kā nodrošināt, lai jūsu Swing GUI būtu diegu drošs. Jā, sākumā tas jutīsies neērti, bet progress parasti notiek.

Džons Zukovskis ir spēlējis Java jau krietni vairāk nekā 12 gadus, jau sen pametis savu C un X-Windows domāšanas veidu. Ar 10 grāmatām par tēmām no Swing līdz kolekcijām līdz Java SE 6, Džons tagad veic stratēģisko tehnoloģiju konsultācijas, izmantojot savu biznesu JZ Ventures, Inc.

Uzziniet vairāk par šo tēmu

  • Uzziniet vairāk par Swing programmēšanu un notikumu nosūtīšanas pavedienu no viena no Java darbvirsmas izstrādes meistariem: Chet Haase par Swing un Java 2D maksimizēšanu (JavaWorld Java Technology Insider podcast, 2007. gada augusts).
  • "SwingWorker pielāgošana, lai uzlabotu Swing GUI" (Yexin Chen, JavaWorld, 2003. gada jūnijs) iedziļinās dažos šajā rakstā apskatītajos Swing pavedienu izaicinājumos un paskaidro, kā pielāgot SwingWorker var nodrošināt muskuļus ap tiem.
  • "Java un notikumu apstrāde" (Todd Sundsted, JavaWorld, 1996. gada augusts) ir pamats notikumu apstrādei ap AWT.
  • "Paātrināt klausītāja paziņošanu" (Roberts Heistings, JavaWorld, 2000. gada februāris) ievieš JavaBeans 1.0 specifikāciju notikumu reģistrēšanai un paziņošanai.
  • "Sasniedziet spēcīgu veiktspēju ar pavedieniem, 1. daļa" (Jeff Friesen, JavaWorld, 2002. gada maijs) iepazīstina ar Java pavedieniem. Skatiet 2. daļu, lai saņemtu atbildi uz jautājumu: Kāpēc mums nepieciešama sinhronizācija?
  • "Uzdevumu izpilde pavedienos" ir JavaWorld fragments no Java vienlaicīgums praksē (Brian Goetz et al., Addison Wesley Professional, 2006. gada maijs), kas veicina uz uzdevumiem balstītu pavedienu programmēšanu un ievieš izpildes sistēmu uzdevumu pārvaldībai.
  • "Vītnes un šūpoles" (Hans Muller un Kathy Walrath, 1998. gada aprīlis) ir viena no agrākajām oficiālajām atsaucēm uz Swing vītņu izveidi. Tas ietver tagad slaveno (un kļūdaino) "viena pavediena kārtulu".
  • GUI izveide ar JFC / Swing ir visaptveroša Java apmācības lapa Swing GUI programmēšanai.
  • "Vienlaicīgums šūpolēs" ir Swing takas apmācība, kas ietver ievadu SwingWorker klasē.
  • JSR 296: Swing Application Framework pašlaik ir izstrādāta specifikācija. Skatiet arī sadaļu "Swing lietojumprogrammu ietvara izmantošana" (John O'Conner, Sun Developer Network, 2007. gada jūlijs), lai uzzinātu vairāk par šo nākamo soli Swing GUI programmēšanas attīstībā.
  • Visa Java AWT uzziņa (John Zukowski, O'Reilly, 1997. gada marts) ir pieejama bez maksas no O'Reilly tiešsaistes kataloga.
  • Jāņa galīgais ceļvedis Java Swing, trešais izdevums (Apress, 2005. gada jūnijs) ir pilnībā atjaunināts Java Standard Edition versijai 5.0. Šeit lasiet grāmatas priekšskatījuma nodaļu JavaWorld!
  • Apmeklējiet JavaWorld Swing / GUI pētījumu centru, lai iegūtu vairāk rakstu par Swing programmēšanu un Java darbvirsmas izstrādi.
  • Apskatiet arī JavaWorld izstrādātāju forumus diskusijām un jautājumiem un jautājumiem saistībā ar Swing un Java darbvirsmas programmēšanu.

Šo stāstu "Swing threading and the event-dispatch thread" sākotnēji publicēja JavaWorld.

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