lunedì 12 marzo 2012

Pratico JavaFX 2, Part 1: Architettura di una swing-based notepad


Con il rilascio di JavaFX 2.0 la domanda per molti sviluppatori Java è se è il momento di iniziare la transizione applicazioni Swing questo paradigma nuova interfaccia utente, e quale modo migliore per scoprire che da un hands-on esercizio? In questa tre parti tutorial, Jeff Friesen guida attraverso il processo di refactoring uno swing-based esempio di applicazione editor di notepad al suo JavaFX 2 equivalente.
JavaFX 2 è una libreria di interfaccia utente e piattaforma per la creazione e l'esecuzione di moderne interfacce utente delle applicazioni Java che dispongono di una ricca grafica, animazione, media, controlli e altro ancora. E 'anche un toolkit per l'implementazione di applicazioni JavaFX, il che significa qualsiasi applicazione Java che dispone di un'interfaccia utente JavaFX.Un'applicazione JavaFX può essere distribuita standalone, ha lanciato via Java Web Start, o incorporato in una pagina web.

Pratica JavaFX 2: Leggi tutte le tre parti

  • Parte 1: Architettura di una swing-based notepad
  • Parte 2: funzionalità dell'interfaccia utente di base swing JPad Refactoring per JavaFX
  • Parte 3: funzioni avanzate swing JPad Refactoring di interfaccia utente per JavaFX
Questo articolo serve come un'introduzione pratica alla JavaFX 2, e si rivolge agli sviluppatori con esperienza con Swing interfaccia utente (UI) di sviluppo. Con il refactoring di un'applicazione Swing, potrai familiarizzare con alcune delle caratteristiche più utili di JavaFX 2. Avrete la possibilità di provarlo su per le dimensioni. E avrai una certa pratica in apps swing refactoring per JavaFX - che potrebbe tornare utile se JavaFX 2 risulta essere la prossima generazione di piattaforma di sviluppo Java che Oracle chiaramente spera che lo farà.
Oracle sta spingendo JavaFX 2 come la prossima generazione della piattaforma per Java, ma vuol dire che è ora di passare dallo swing al JavaFX? Refactoring una applicazione demo Swing per JavaFX è un modo per scoprirlo.
Questa prima parte di questo articolo è una panoramica di un'applicazione demo Swing, un editor di testo chiamato JPad. Gli sviluppatori di Swing esperti possono probabilmente dare l'architettura uno sguardo, per poi passare al refactoring l'applicazione per JavaFX in parte 2 e parte 3 . Per quelli meno esperti con Swing, Part 1 offre informazioni preziose sul lato client lo sviluppo di applicazioni, che probabilmente avrete bisogno per seguire gli esempi di refactoring.

JavaFX due versione della storia

Oracle ha rilasciato JavaFX 2.0 beta maggio 2011 e lo ha dichiarato pronto per la produzione nel mese di ottobre dello stesso anno. La versione più recente, JavaFX 2.0.2, è stato rilasciato nel dicembre del 2011 con alcune correzioni di bug e aggiunto funzionalità minori. Gli esempi in questo articolo sono basate su JavaFX 2.0.2.
Cominciamo con una rassegna di nuove funzionalità in JavaFX 2, alcuni dei quali si incontrano nell'architettura JPad refactoring.

Grandi cambiamenti in JavaFX 2

JavaFX 2 differisce notevolmente dalle versioni precedenti, e uno dei maggiori cambiamenti è la disapprovazione di JavaFX Script. JavaFX sviluppatori sono liberi di programma in codice Java, e possono anche sperimentare JVM linguaggi di scripting come Groovy o Scala. Codice Java è più dettagliato rispetto a JavaFX Script, ma c'è speranza che Java 8 di supporto per le espressioni lambda nella lingua Java porterà miglioramenti.
Le seguenti caratteristiche del linguaggio JavaFX Script sono stati sostituiti da equivalenti Java API:

  • Java costruttori sostituire JavaFX Script di blocchi di script di inizializzazione . Un costruttore è una classe Java i cui metodi sono progettati in modo che sia possibile concatenare le chiamate di metodo.
  • Cambia ascoltatori sostituire sostituire trigger.
  • Liste osservabili sostituire sequenze.
  • Unico metodo astratto (SAM) i tipi di sostituire i tipi di funzione. Un tipo di SAM è un singolo metodo di interfaccia o classe astratta - il metodo della classe astratta è astratta. Quando Java 8 arriva, saremo in grado di utilizzare espressioni lambda per lavorare in modo più conciso con i tipi di SAM.
  • Proprietà basati su una versione estesa e migliorata del modello JavaBeans sono state introdotte per supportare vincolante. Mentre JavaFX Script permesso vincolante per qualsiasi variabile, JavaFX 2.0 consente vincolanti solo alle proprietà.
Ulteriori modifiche JavaFX 2 sono i seguenti:
  • Menu Sperimentale, barra degli strumenti, e l'albero controlli UI introdotta in JavaFX 1.3.1 sono ora di serie. JavaFX 2 dispone anche di nuova tabella e editor HTML controlla insieme a finestre di dialogo standard. Tutti i controlli possono essere scuoiati tramite CSS3 +.
  • Un nuovo web-view componente basato su WebKit consente di incorporare un browser web (con supporto JavaScript e Document Object Model) in applicazioni Java.
  • JavaFX 2 supporta FXML , uno script, basato su XML linguaggio di markup per la costruzione di interfacce utente. FXML sostituisce la precedente JavaFX Script-oriented FXD (JavaFX dati) formato.
  • JavaFX distribuzione delle applicazioni è stata migliorata. È ora possibile creare personalizzati preloader (specializzata applicazioni JavaFX estendono il javafx.application.Preloader classe) per migliorare il caricamento delle applicazioni e di avvio.
  • L'architettura delle applicazioni JavaFX 2 è stata migliorata per semplificare l'organizzazione delle applicazioni che verranno eseguite in contesti di implementazione multiple. Nuove API consentono alle applicazioni di individuare e interagire con i loro ambienti di distribuzione.
  • Un'architettura nuova piattaforma basata su un hardware accelerata pipeline grafica (Prism) e toolkit a finestre (vetro) migliora le prestazioni delle applicazioni JavaFX 2. Se combinato con Java ME, dovrebbe aiutare nella migrazione applicazioni JavaFX ai dispositivi mobili e tablet.

E 'JavaFX 2 pronto per la produzione?

Mentre leggete questo articolo, considerare le seguenti domande:
  • E 'JavaFX 2 a production-ready piattaforma, come sostiene Oracle?
  • Ci sono notevoli vantaggi alla programmazione in JavaFX rispetto Swing?
Io condividere le mie risposte a queste domande alla fine della parte 3 . Potrai anche essere invitati a condividere il tuo punto di vista nel forum di discussione dell'articolo.

Introduzione JPad

JPad ​​è una applicazione basata su Java editor di testo che è molto simile al programma Blocco note di Windows XP. Come con il blocco note, JPad consente di aprire un file di documento, apportare modifiche al suo testo, e salvare le modifiche al file aperto o un file nuovo documento. È inoltre possibile annullare le modifiche, interagire con la clipboard con taglia / copia / incolla, ed eseguire altre attività. Figura 1 è uno screenshot dell'interfaccia utente di JPad.

Figura 1. Una schermata di JPad Swing (clicca per ingrandire)

La figura 1 mostra una semplice interfaccia utente che consiste in una barra dei menu, un'area di testo scorrevole, una barra di stato. La barra dei menu visualizza File, Modifica, Formato, e menu Guida, l'area di testo visualizza il documento corrente e consente di apportare modifiche, e la barra di stato viene visualizzato un messaggio di default o il testo di aiuto che è associato con il menu attualmente selezionata. Si noti che il taglio e le funzioni di copia sono disabilitate fino a quando il testo viene selezionato.

File offre le seguenti voci:
  • New crea un nuovo documento vuoto e richiede agli utenti di salvare il documento corrente se ha modifiche non salvate.
  • Apri apre un file esistente. Agli utenti viene richiesto di salvare il documento corrente se ci sono modifiche non salvate.
  • Salva salva il documento corrente al suo file associato o un file diverso.
  • Salva con nome salva il documento corrente in un file diverso.
  • Uscire chiude l'applicazione. Agli utenti viene richiesto di salvare il documento corrente se ci sono modifiche non salvate.
Edit offre le seguenti voci:
  • Annulla Annulla l'ultima modifica; disabilitata quando non ci sono nuove modifiche.
  • Taglia taglia il testo selezionato nella clipboard; disattivato quando è selezionato alcun testo.
  • Copia copia il testo selezionato nella clipboard; disattivato quando è selezionato alcun testo.
  • Paste incolla il testo negli appunti sul testo selezionato o nella posizione di cursore; disabilitato quando la clipboard non contiene testo.
  • Seleziona tutto seleziona tutto il testo dell'area di testo.
Inoltre:
  • A capo automatico può essere attivata o disattivata selezionando o deselezionando la voce di menu Formato.
  • A proposito di JPad è una voce di menu Guida in linea che consente agli utenti di ottenere informazioni sull'applicazione.
JPad ​​L'applicazione permette agli utenti di specificare un file da aprire come un argomento della riga di comando. Se un utente rilascia un file trascinato sulla sua area di testo, JPad si aprirà il file dopo aver lasciato l'utente salvare le modifiche recenti.

Impostazione di un ambiente di sviluppo JavaFX 2

Oracle sito JavaFX documenta ampiamente l' architettura JavaFX . Questo è anche il luogo dove si trova lo sviluppo del software JavaFX per la 32-bit o 64-bit piattaforma Windows o Mac OS X. Ho usato il JDK 7u2 con JavaFX SDK pacchetto software integrato (che comprende il JavaFX SDK 2.0.2) su una piattaforma Windows XP per sviluppare la mia applicazione JavaFX 2 JPad.

Compilazione ed esecuzione JPad

Per esplorare JPad nel vostro ambiente di sviluppo, scaricare il suo codice sorgente e file di risorse: JPad.java e icon.png .Dopo aver estratto i file nella directory corrente, eseguire i seguenti comandi per compilare JPad.java ed eseguirlo. Si noti che il terzo comando indica JPad per aprire e visualizzare il contenuto di JPad.java :
javac JPad.java
java JPad
java JPad JPad.java

Architettura di JPad

JPad ​​è implementato come un singolo JPad classe di primo livello. Come per molte applicazioni Swing, JPad estende lajavax.swing.JFrame classe, che lo rende una sorta di finestra cornice. Potete vedere questo nel Listato 1.

Listing 1. La classe JPad incapsula l'applicazione JPad

/ / ...
JPad ​​public class estende JFrame
{
   / / ...
   pubblica JPad (String [] args)
   {
      / / ...
      if (args.Length! = 0)
         doOpen (new File (args [0]));
   }
   vuoto doExit private ()
   {
      / / ...
   }
   vuoto doNew private ()
   {
      / / ...
   }
   vuoto doOpen private ()
   {
      doOpen (null);
   }
   vuoto doOpen privato (del file)
   {
      / / ...
   }
   private boolean doSave ()
   {
      / / ...
   }
   private boolean doSaveAs ()
   {
      / / ...
   }
   private String read (File f) throws IOException
   {
      / / ...
   }
   private void write (File f, String text) throws IOException
   {
      / / ...
   }
   public static void (principali final String [] args)
   {
      Runnable r = new Runnable ()
      {
         @ Override
         public void run ()
         {
            nuova JPad (args);
         }
      };
      EventQueue.invokeLater (r);
   }
}
Listato 1 mostra JPad struttura scheletrica 's, che consiste di un costruttore, diversi metodi di privati, e il main () entry-point metodo. (Ho commentato tutto il resto, perché non è rilevante a questo punto.)
Il main () metodo crea un'istanza di JPad e passa al costruttore la serie di argomenti della riga di comando per l'evento-spedizione thread. Dopo la creazione di UI JPad, il costruttore apre il file identificato dal primo argomento della riga di comando quando almeno un argomento è specificato.

Interfacce utente di Swing e l'evento-spedizione filo

Nell'articolo "JavaWorld swing threading e l'evento-spedizione filo "autore John Zukowski spiega perché è importante creare interfacce utente di Swing per l'evento-spedizione thread.

Creare l'interfaccia utente

JPad ​​costruttore 's crea l'interfaccia utente JPad sfruttando lajavax.swing pacchetto JCheckBoxMenuItem , JLabel , JMenu ,JMenuBar , JMenuItem , JScrollPane e JTextArea classi, come mostrato nel Listato 2.

Listing 2. Altalena organizza UI di JPad in una barra dei menu e un riquadro dei contenuti

/ / ...
private JTextArea ta;
/ / ...
private JLabel LBL;
/ / ...
pubblica JPad (String [] args)
{
   / / ...
   JMenuBar mb = new JMenuBar ();
   JMenu Mfile = new JMenu ("File");
   JMenuItem miNew = new JMenuItem ("Nuovo");
   miNew.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_N,
                                               KeyEvent.CTRL_MASK));
   / / ...
   mFile.add (miNew);
   / / ...
   mb.add (Mfile);
   / / ...
   JMenu mFormat = new JMenu ("Format");
   finale JCheckBoxMenuItem cbmiWordWrap = new JCheckBoxMenuItem ("Word Wrap");
   / / ...
   mFormat.add (cbmiWordWrap);
   / / ...
   mb.add (mFormat);
   / / ...
   setJMenuBar (mb);
   . getContentPane () aggiungere (nuovo JScrollPane (ta = new JTextArea ()));
   / / ...
   getContentPane () aggiungere (lbl = new JLabel ("JPad 1.0"), BorderLayout.SOUTH).;
   setSize (400, 400);
   setTitle (DEFAULT_TITLE);
   / / ...
   setVisible (true);
   / / ...
}
Il costruttore inizializza il primo JFrame superclasse e crea / installa il sistema di menu (anche se ho omesso la maggior parte di questo codice per brevità). Quindi, crea l'area di testo scorrevole e barra di stato, e li aggiunge al riquadro del contenuto della finestra cornice. Infine, inizializza e visualizza la finestra.

Perché usare setTitle (DEFAULT_TITLE);?

Gli sviluppatori esperti battente può notare che ho usatosetTitle (DEFAULT_TITLE), al posto di super (DEFAULT_TITLE), per inizializzare il testo di default della barra del titolo della finestra cornice nel Listato 2. Ho scritto il codice in questo modo perché il JavaFX 2 applicazione richiederàsetTitle () . Per motivi di esempio, volevo JPad essere coerente con JPadFX possibile.

Gestione degli eventi

Gestione degli eventi è uno degli aspetti più coinvolte di sviluppo Swing, che rende refactoring un app Swing di gestione degli eventi infrastruttura JavaFX sia stimolante e gratificante. Qui, vedremo come JPad gestisce gli eventi notepad tipici attivati ​​dall'utente, vale a dire: azione, documento, menu, accento circonflesso, e gli eventi delle finestre.

Azione eventi

Un evento-azione viene generato quando l'utente seleziona una voce di menu. Ad esempio, quando l'utente seleziona Nuovo dal menu File, un evento-azione viene inviato a New action listener registrato, come mostrato nel Listato 3.

Listing 3. JPad ​​risponde a un evento Nuova azione

ActionListener al;
al = new ActionListener ()
{
   @ Override
   public void actionPerformed (ActionEvent ae)
   {
      se (fDirty)
         switch (JOptionPane.showConfirmDialog (JPad.this, SAVE_CHNGS,
                                               TITLE_AYS,
                                               JOptionPane.YES_NO_OPTION))
         {
            JOptionPane.YES_OPTION caso: if (doSave ()) doNew (); break;
            caso JOptionPane.NO_OPTION: doNew ();
         }
      altro
         doNew ();
   }
};
miNew.addActionListener (al);
Action listener La voce di menu Nuovo esamina anzitutto fDirty di sapere se o meno il documento corrente è stato modificato. Se questa variabile campo booleano è vero (nel senso che il documento è stato modificato), l'utente viene richiesto di salvare le modifiche prima di un nuovo documento sostituisce quello corrente.
Un evento documento viene generato quando l'utente effettua una modifica al documento il text-area componente. Listener documento registrato Questo componente risponde impostando fDirty (che è inizialmente falsa ) a true , come mostrato nel Listato 4.

Listato 4. changedUpdate () non è applicabile alle modifiche del documento

DocumentListener dl;
dl = new DocumentListener ()
{
   @ Override
   public void changedUpdate (DocumentEvent de)
   {
      / / Non necessaria - chiamato solo quando vengono modificati gli attributi
   }
   @ Override
   public void insertUpdate (DocumentEvent de)
   {
      fDirty = true;
   }
   @ Override
   public void removeUpdate (DocumentEvent de)
   {
      fDirty = true;
   }
};
. ta.getDocument () addDocumentListener (dl);
L'ascoltatore documento dichiara insertUpdate () e removeUpdate () metodi che vengono chiamati ogni volta che i contenuti vengono inseriti o rimossi dal documento oggetto.

Menu eventi

Un evento di menù viene generato quando l'utente seleziona un menu. Listener registrato menù Il menu risponde aggiornando la barra di stato con menu specifico testo di aiuto. Quando l'utente deseleziona il menu, il contenuto della barra di stato viene ripristinato il testo di default. Listato 5 dimostra entrambe le attività.

Listing 5. menuSelected () viene chiamato ogni volta che viene selezionato un menu

MenuListener ml;
ml = new menuListener ()
{
   @ Override
   public void menuCanceled (MenuEvent me)
   {
   }
   @ Override
   public void menuDeselected (MenuEvent me)
   {
      lbl.setText (DEFAULT_STATUS);
   }
   @ Override
   public void menuSelected (MenuEvent me)
   {
      lbl.setText ("New doc | aprire gli attuali doc | Salva modifiche | Esci");
   }
};
mFile.addMenuListener (ml);
L'ascoltatore menu è menuCanceled () metodo viene lasciato vuoto perché questo metodo non viene mai chiamato. Sembra essere un artefatto storico.

Caret eventi

Un accento circonflesso evento viene generato quando l'utente sposta il cursore (text-inserimento indicatore) all'interno del componente di testo. Listener caret registrato il componente determina o meno il testo è selezionato e abilita o disabilita il taglio e le voci di menu Copia in modo appropriato, come mostrato nel Listato 6.

Listato 6. caretUpdate () viene chiamato ogni volta che il cursore si sposta

Cl CaretListener;
cl = new CaretListener ()
{
   @ Override
   public void caretUpdate (CaretEvent ce)
   {
      if (ta.getSelectedText ()! = null)
      {
         miCut.setEnabled (true);
         miCopy.setEnabled (true);
      }
      altro
      {
         miCut.setEnabled (false);
         miCopy.setEnabled (false);
      }
   }
};
ta.addCaretListener (cl);
L'ascoltatore di accento circonflesso caretUpdate () metodo chiama JTextArea 's String getSelectedText () metodo per determinare se il testo è stato selezionato, quindi aggiorna Tagliare e copiare di conseguenza.

Finestra degli eventi

Infine, veniamo alla manifestazione finestra , che viene licenziato quando l'utente tenta di chiudere la finestra o eseguire un'altra operazione finestra. Listener registrato finestra della finestra cornice richiama doExit () , come mostrato nel Listato 7. (Questo listener richiede setDefaultCloseOperation () di essere chiamata con DO_NOTHING_ON_CLOSE come argomento, altrimenti l'ascoltatore finestra verrà ignorato.)

Listing 7. doExit () chiude la finestra cornice

setDefaultCloseOperation (DO_NOTHING_ON_CLOSE);
addWindowListener (nuovo WindowAdapter ()
{
   @ Override
   vuoto windowClosing pubblico (WindowEvent noi)
   {
      doExit ();
   }
});
doExit () richiede all'utente di salvare le modifiche quando fDirty è vero . O meno le modifiche vengono salvate, invoca infine dispose () per distruggere la finestra cornice e terminare l'applicazione. Listing 8 mostra questa sequenza di codice.

vuoto doExit private ()
{
   se (fDirty)
      switch (JOptionPane.showConfirmDialog (JPad.this, SAVE_CHNGS,
                                            TITLE_AYS,
                                            JOptionPane.YES_NO_OPTION))
      {
         JOptionPane.YES_OPTION caso: if (doSave ()) dispose (); break;
         caso JOptionPane.NO_OPTION: dispose ();
      }
   altro
      dispose ();
}

Finestre di dialogo

JPad ​​presenta finestre di dialogo per la selezione di un file dal filesystem, mostrando Chi informazioni, la visualizzazione di messaggi di errore, e la richiesta di risposte si / no. Come mostra il Listato 9 spettacoli, costruttore di un'istanza di JPadjavax.swing.JFileChooser di gestire file-selezione.fc.setAcceptAllFileFilterUsed (false) rimuove il valore predefinito "Tutti i file" filtro.

Listing 9. Un'istanza di selezione dei file e la configurazione di JPad

fc = new JFileChooser (".");
fc.setAcceptAllFileFilterUsed (false);
FileFilter ff = new FileNameExtensionFilter ("TXT documenti (*. Txt)",
                                            "* Txt.");
fc.addChoosableFileFilter (ff);
ff = new FileNameExtensionFilter ("Tutti i file", "* *.");
fc.addChoosableFileFilter (ff);
Il costruttore richiama il primo (String currentDirectoryPath) JFileChooser costruttore con un punto (.) come argomento. Il punto indica che la directory corrente è di servire come il selettore di file viene visualizzato inizialmente directory.
Il costruttore di default quindi rimuove il selettore di file filtro "Tutti i file" file. Si registra poi una coppia di filtri con il selettore di file, l'istruzione di accettare solo i file con estensione txt. estensioni di file, seguiti da tutti i file (nel senso che la proroga verrà ignorato).
Un filtro di file è convenientemente descritta da un javax.swing.filechooser.FileNameExtensionFilter esempio, che è registrato con il selettore di file, richiamando JFileChooser 's vuoto addChoosableFileFilter (FileFilter filtro) metodo.
Il selettore di file viene successivamente utilizzato per visualizzare o salvare aperta la finestra di dialogo nel vuoto doOpen (del file) o boolean doSaveAs () metodo. Listato 10 dimostra il selettore di file utilizzato nel metodo precedente.

Listing 10. Visualizzazione di un selettore di file aperto

if (file == null)
   if (fc.showOpenDialog (JPad.this) == JFileChooser.APPROVE_OPTION)
      file = fc.getSelectedFile ();
if (file == null)
   ritorno;
fc.setCurrentDirectory (file.getParentFile ());
fc.setCurrentDirectory (file.getParentFile ()) assicura che il successivo file-chooser attivazione impostare la directory iniziale a quello attuale.

A proposito di JPad

JPad ​​presenta la sua finestra di dialogo Informazioni in risposta all'utente selezionando "Informazioni su JPad" dal menu Aiuto. Questa finestra di dialogo viene creato e visualizzato richiamando uno dei JOptionPane 's showMessageDialog () i metodi, come mostrato nel Listato 11. (Si noti che l'icona è un javax.swing.ImageIcon un'istanza precedentemente inizializzato tramite icon = new ImageIcon ("icon.png"); .)

Listing 11. Informa l'utente circa JPad

JOptionPane.showMessageDialog (JPad.this,
                              "JPad 1.0 \ NBY Jeff Friesen \ n",
                              "JPad",
                              JOptionPane.PLAIN_MESSAGE,
                              icona);
Figura 2 è uno screenshot di JPad della finestra di dialogo Informazioni.

Figura 2. JPad ​​è finestra di dialogo Informazioni

Il carattere di nuova riga ( \ n ) viene utilizzato per suddividere il messaggio in più righe e di lasciare una riga vuota per il riempimento. showMessageDialog () viene utilizzato anche per visualizzare le finestre di dialogo di avviso in risposta a I / O e altri errori. Si noti, inoltre, che uno dei JOptionPane 's showConfirmDialog () metodi sia utilizzato per la richiesta di risposte si / no (anche rinviano al Listing 3 e 8 Listing ).

Accesso alla clipboard

Gli utenti di JPad possibile accedere alla clipboard via Taglia, Copia e Incolla. Gran parte di questo sostegno viene gestito automaticamente da un swing JTextArea , che accede al clipboard di sistema ed esegue un taglio, copia, incolla o il funzionamento quando viene rilevata una specifica combinazione di tasti (per esempio, Ctrl + C).
JTextArea dichiara anche metodi come copia void () , che di programmazione accedere alla clipboard di sistema. Menù JPad gli ascoltatori di elementi per Cut dal menu Modifica, copia, e le voci di menu Incolla eseguire questi metodi quando viene selezionato un elemento, come nel caso di ta.copy (); .
JPad ​​ha anche bisogno di accedere direttamente negli appunti di sistema per determinare quando il testo è disponibile per essere incollato. Quando il testo non è disponibile, dal menu Modifica la voce Incolla deve essere disabilitato, altrimenti, questa voce di menu è abilitata.
Il costruttore esegue il codice mostrato nel Listato 12 per accedere alla clipboard di sistema e salvare il suo riferimento in una java.awt.datatransfer.Clipboard campo variabile.

Listing 12. getSystemClipboard () fornisce l'accesso al clipboard di sistema

cb = Toolkit.getDefaultToolkit () getSystemClipboard ().;
Ascoltatore menù Edit esegue il codice mostrato nel Listato 13 nella sua menuSelected () metodo.

Listing 13. isDataFlavorAvailable () restituisce true quando una stringa è negli appunti

boolean b = cb.isDataFlavorAvailable (DataFlavor.stringFlavor);
miPaste.setEnabled (b);
Ogni volta che si seleziona dal menu Modifica, Appunti 's boolean isDataFlavorAvailable (DataFlavor) metodo viene eseguito nella clipboard sistema con DataFlavor.stringFlavor , che descrive il tipo di contenuto del testo, noto anche come tipo MIME. Se il sistema contiene appunti di testo, i veri rendimenti e la voce di menu Incolla è attivata. In caso contrario, non esiste alcun testo nella clipboard del sistema e Incolla è disabilitata.

Drag and drop

JPad ​​consente di trascinare i file e rilasciarli sulla superficie del testo. Anche se più file possono essere trascinati e rilasciati su questo componente UI, solo il primo di questi file viene aperto e il suo contenuto visualizzato, gli altri file vengono ignorati.Listato 14 mostra come JPad supporta il drag and drop.

Listing 14. JPad ​​risponde al trascinamento di destinazione and drop eventi

DropTargetAdapter dta;
dta = new DropTargetAdapter ()
{
   @ Override
   public void dragOver (DropTargetDragEvent dtde)
   {
      Trasferibile tr = dtde.getTransferable ();
      DataFlavor [] = sapori tr.getTransferDataFlavors ();
      for (DataFlavor gusto: i sapori)
         se (flavor.isFlavorJavaFileListType ())
         {
            dtde.acceptDrag (DnDConstants.ACTION_COPY);
            ritorno;
         }
   }
   @ Override
   vuoto goccia pubblico (DropTargetDropEvent dtde)
   {
      prova
      {
         Trasferibile tr = dtde.getTransferable ();
         DataFlavor [] = sapori tr.getTransferDataFlavors ();
         for (DataFlavor gusto: i sapori)
            se (flavor.isFlavorJavaFileListType ())
            {
               dtde.acceptDrop (DnDConstants.ACTION_COPY);
               @ SuppressWarnings ("unchecked")
               Elenco dei file <File> = (List <File>) tr.getTransferData (gusto);
               se (fDirty)
                  switch (JOptionPane.showConfirmDialog (JPad.this,
                                                        SAVE_CHNGS,
                                                        TITLE_AYS,
                                                        JOptionPane.YES_NO_OPTION))
                  {
                     JOptionPane.YES_OPTION caso: if (doSave ())
                                                     doOpen (files.get (0));
                                                  break;
                     caso JOptionPane.NO_OPTION: doOpen (files.get (0));
                  }
               altro
                  doOpen (files.get (0));
               dtde.dropComplete (true);
               um.discardAllEdits ();
               ritorno;
            }
         dtde.rejectDrop ();
      }
      catch (Exception e)
      {
         JOptionPane.showMessageDialog (JPad.this,
                                       "Errore Drop:" + e.getMessage (),
                                       "Alert",
                                       JOptionPane.ERROR_MESSAGE);
      }
   }
};
dt = new DropTarget (ta, dta);
JPad ​​'s primo costruttore sottoclassi java.awt.dnd.DropTargetAdapter , sovrapponendosi la sua dragOver void (DropTargetDragEvent dtde) e la caduta di void (DropTargetDropEvent dtde) metodi al fine di rispondere alle DropTargetdrag and drop eventi.
Un DropTarget evento di trascinamento si pone quando un elemento viene trascinato su una destinazione di rilascio (un ente associato con un componente che rappresenta la destinazione di una drag-and-drop). JPad ignora dragOver () per assicurarsi che il cursore del mouse indica sempre una copia funzionamento.

Copia rispetto a muoversi

I file che vengono trascinati in un editor di testo sono sempre copiati e non si mosse - semplicemente non ha senso cancellare il file originale. Se l'utente avvia una resistenza come un'operazione di spostamento, JPad garantisce che l'utente riceve feedback visivo che è interpretare il trascinamento come un'operazione di copia, in modo che l'utente conosce il file non vengono cancellati.
Un DropTarget evento drop si verifica quando l'elemento viene rilasciato sulla destinazione di rilascio. JPad ignora drop ()per ottenere il primo della lista dei file che vengono scartati e aprirlo nell'area di testo, dopo che richiede all'utente di salvare le modifiche (quando necessario) .
Infine, JPad istanzia java.awt.dnd.DropTarget , che definisce una destinazione di trascinamento che collega la zona testo-componente con il drop-bersaglio istanza adattatore. L'area di testo è ora pronto ad accettare i file eliminati.

Implementazione l'essenziale: Annulla

Maggior parte degli editor di testo offrono un annullamento caratteristica, che consente agli utenti di ripristinare le modifiche recenti. JPad ​​supporta l'annullamento creando un'istanza della javax.swing.undo pacchetto UndoManager classe e la registrazione di un annullabile-edit ascoltatore con l'area di testo, come mostrato nel Listato 15.

Listing 15. Il annullabile-edit ascoltatore passa annullabile modifiche per annullare il gestore

um = new UndoManager ();
UndoableEditListener uel;
uel UndoableEditListener = new ()
{
   @ Override
   public void undoableEditHappened (UndoableEditEvent UEE)
   {
      um.addEdit (uee.getEdit ());
   }
};
. ta.getDocument () addUndoableEditListener (UEL);
Quando il documento di testo viene modificato, la sede legale javax.swing.event.UndoableEditListener 'sundoableEditHappened () viene richiamato il metodo con un javax.swing.event.UndoableEditEvent esempio, che descrive la modifica. Questa istanza di UndoableEdit getEdit () viene richiamato il metodo per restituire la modifica comejavax.swing.undo.UndoableEdit esempio, che viene poi aggiunto al UndoManager invocando il suo boolean AggiuntoOra (UndoableEdit anEdit) metodo.
L'action listener registrata presso il menu Modifica della voce di menu Annulla esegue um.undo (); quando selezionato.Perché UndoManager 's vuoto annulla () metodo genera javax.swing.undo.CannotUndoException quando non ci sono modifiche per essere annullata, questa voce di menu deve essere attivata solo quando ci sono modifiche. I compiere questa restrizione eseguendo miUndo.setEnabled (um.canUndo ()); nel menuSelected () il metodo del listener menu che viene registrato con il menu Modifica.
Infine, JPad esegue um.discardAllEdits (); dire al gestore di undo per annullare tutti i annullabile modifiche in risposta a determinati eventi: la creazione di un nuovo documento vuoto, aprendo un file esistente documento, salvare il documento corrente al file del documento corrente o una nuova file, o l'eliminazione di un file trascinato nell'area di testo. La capacità di annullare le modifiche vecchio non avrebbe senso in nessuno di questi nuovi contesti.

Conclusione alla Parte 1

Nella seconda parte di questo articolo faremo mappare l'architettura di base dell'interfaccia utente (riquadro dei contenuti, sistema di menu e la gestione degli eventi) della nostra applicazione swing notepad per un equivalente JavaFX: JPadFX.

Circa l'autore

Jeff Friesen è un insegnante freelance e sviluppatore di software con particolare attenzione per Java e Android. Oltre a scrivere libri su Java e Android per Apress , Jeff ha scritto numerosi articoli su Java e altre tecnologie per JavaWorld,informIT , Java.net , e DevSource . Jeff può essere contattato tramite il suo sito web all'indirizzo TutorTutor.ca .
Per saperne di più Core Java nella sezione JavaWorld Core Java.


Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.