2009-09-28 9 views
5

Ho un'idea di scrivere un'app per appunti in Java che faccia una semplice sostituzione di testo durante la digitazione; probabilmente un piccolo sottoinsieme della sintassi Markdown. Così, per esempio, se hai inserito una linea che era #sometext, si otterrebbe reso:Implementazione di stili di testo al volo in un JEditorPane

someText

Wikidpad fa parte di quello che sto cercando di fare (non sto appena ri-attuazione di tale, solo parti della sintassi/funzionalità di visualizzazione).

Quindi, in sostanza, sto cercando un modo per scrivere una sorta di componente che, quando l'utente preme "return", guarderà la riga inserita e farà qualsiasi magia che debba fare per ottenere i tag html destra.

Ho battuto la mia testa contro Document e DocumentFilters e DocumentListeners e HTMLReader e così senza molta fortuna, qualcuno può mettermi sulla strada giusta?

risposta

3

Quello che ti interessa è un java text editor kit. Questo tutorial è stato eccezionale e mi ha aiutato a implementare un wiki-editor che somiglia al tuo problema. Il kit di oscillazione dell'editor (che ci crediate o no) è specificamente progettato per gestire il tuo problema. Ho scritto un wiki dinamico come un sistema di collegamento usando questa tecnica, anche se non senza molta fatica.Ecco cosa dovevo fare:

  1. fare un documento Il primo compito è quello di creare un modello di documento che il modello di tag quando si identifica il testo. Se si analizza JavaDocument nell'esempio collegato, è presente una chiamata insertUpdate. Nel documento puoi trovare il modello che stai cercando e sostituirlo con uno stile personalizzato appropriato. In sostanza, devi solo creare uno stile e applicarlo al documento in cui il modello è abbinato. Un'alternativa al metodo di aggiornamento consiste nel fare in modo che questo utilizzi un thread worker privato per eseguire periodicamente la scansione di nuovi contenuti wiki.

  2. Creazione di un contesto di rendering Dopo aver completato il modello è possibile implementare un contesto che costruisce una vista appropriata per il rendering del nuovo testo. Nell'esempio collegato estendono uno StyleContext. Questo è ciò che viene usato per rendere il testo alla vista. Qui puoi impostare regole di rendering che troveranno il tuo tag specifico e fare qualcosa come evidenziarlo e rimuovere le parentesi quadre.

  3. Creazione di un kit di editor Ciò consente di unire tutti i componenti e identificare un tipo di contenuto per il documento.

La cosa buona di mantenere il documento e visualizza come contesti separati è che si può allegare il documento a due punti di vista, uno in testo normale, l'altra nel nuovo contesto personalizzato. Poiché lo stile di default non riconosce il tuo tag, dovrebbe visualizzarlo nel modulo di codice wiki originale. La nuova vista trasformerà la vista nel collegamento appropriato.

Spero che questo aiuti. Una parola di cautela, questa roba è purtroppo complessa, anche per lo swing. In bocca al lupo!

+0

Sì, è lì che mi sono diretto - ma non avevo ancora incontrato quel tutorial. È stato complesso frustrante, ma penso che la pagina aiuterà molto. – decitrig

+0

Capisco la tua frustrazione. L'editor di testo potrebbe utilizzare alcuni refactoring dell'usabilità del codice – reccles

+0

Come quasi tutto Oracle, quel collegamento è rotto. Qualche indizio su dove trovare questo tutorial ora? –

1

Sembra che ciò che è necessario sia implementare una specie di listener di chiavi nel componente dell'editor che esamina i tratti chiave prima che entrino nel campo di testo. Può quindi cercare di nuovo nel buffer, trovare i caratteri di controllo e fare ciò che è necessario fare.

Non ho molta esperienza con JEditorPanes e simili. Ma penso che tu possa aggiungere key ascolter a loro come qualsiasi altro componente swing.

Fondamentalmente non penso che esista un componente come questo, quindi sarà necessario implementare il proprio.

Tuttavia, potrei sbagliarmi.

+0

Sì, ho giocato con keylisteners, ma non sembrano consumare l'evento chiave, quindi non posso "fare ciò che devo fare" prima che il riquadro abbia già bloccato il carattere nel suo contenuto. – decitrig

0

Deve accadere quando viene premuto Invio o solo quando inviano i dati?

Se è presente, attendere che premano un pulsante per il salvataggio dei dati, quindi premere JEditorPane.getText(), "correggere" il testo e fare JEditorPane.setText (testo);

OK, se dovesse essere al volo, provare ad aggiungere un listener del metodo di input. InputMethodEvent dovrebbe essere in grado di chiamare "getText()" e dovresti essere in grado di analizzarlo dopo ogni pressione di un tasto. Se vuoi farlo dopo ogni volta che l'utente preme Invio, recupera il testo su ogni tasto premuto e verifica se la posizione corrente nel testo è di un carattere dopo un \ n o simile.

+0

Mi piacerebbe farlo al volo. – decitrig

0

All'inizio consiglio di utilizzare JTextPane, poiché è più adatto per applicare gli stili al testo. Quindi, è molto facile aggiungere un tasto Evento stampato:

jTextPane1.addKeyListener(new java.awt.event.KeyAdapter() { 
    public void keyPressed(java.awt.event.KeyEvent evt) { 
     jTextPane1KeyPressed(evt); 
    } 
}); 

private void jTextPane1KeyPressed(java.awt.event.KeyEvent evt) { 
    // TODO add your handling code here: 
    String txt = jTextPane1.getText(); 

} 

Il codice precedente è stato facilmente generato con Netbeans.

È quindi possibile applicare stili fare qualcosa di simile:

StyledDocument doc = jTextPane1.getStyledDocument(); 
Style style = jTextPane1.addStyle("Bold", null); 
StyleConstants.setBold(style, true); 

int pos, endpos; 
// Find pos of word to be displayed in bold 
... 

// Set style 
doc.setCharacterAttributes(pos, endpos, style, true); 
+0

Ho pensato anche a questo; la mia preoccupazione è che non si ridimensionerà con documenti di grandi dimensioni, poiché sta leggendo l'intero testo e riformattando ogni volta che viene premuto un tasto. – decitrig

+0

È possibile utilizzare evt.getKeyChar() e leggere l'intero testo, solo quando è necessario. Imposta un flag quando viene premuto il tasto '#', quindi leggi il testo e applica il formato quando viene premuto lo spazio/nuova riga. Dovresti anche considerare il caso in cui un utente incolla il testo nel controllo. È possibile monitorare i meta caratteri per tali eventi. – kgiannakakis

0

Usa RSyntaxTextArea, fa ciò che è necessario ed è possibile aggiungere le proprie lexer/regole.

+0

Lo controllerò sicuramente. – decitrig