2015-07-28 2 views
3

Je voudrais savoir comment compter le nombre d'espaces sur une ligne donnée avant que le texte commence réellement. Par ex. si j'ai ceci dans mon JTextPane:Nombre d'espaces avant le texte sur une ligne dans un JTextPane

public static void main(String[] args) { 
    int x = 1; 

} 

après avoir tapé 'x = 1;' et appuyez sur Entrée, je voudrais avoir le signe d'insertion sur la même indentation que l'int x = 1; commence, donc je ne dois pas continuer à appuyer sur Tab ou entrer des espaces manuellement. Aucune suggestion?

+0

Si vous tentez d'implémenter un éditeur de code source, vous pouvez consulter le JEditorPane [https://docs.oracle.com/javase/tutorial/uiswing/components/editorpane.html](https://fr docs.oracle.com/javase/tutorial/uiswing/components/editorpane.html) et le StyledEditorKit [https://docs.oracle.com/javase/8/docs/api/javax/swing/text/StyledEditorKit.html] (https://docs.oracle.com/javase/8/docs/api/javax/swing/text/StyledEditorKit.html). – VirtualMichael

+0

Si l'une de nos solutions a résolu votre problème, veuillez sélectionner la meilleure réponse. Si vous avez encore des problèmes, n'hésitez pas à nous le faire savoir. – Sharcoux

Répondre

0

de Split le texte de la JTextPane par '\n' et rechercher chaque ligne jusqu'à ce que vous trouviez la String que vous recherchez.

Si la ligne que vous êtes ne pas le String vous recherchez vous ajoutez la longueur de cette ligne + 1 (pour inclure la '\n') à une somme.

Si la ligne sur laquelle vous vous trouvez porte le String, commencez par le début de la ligne et comptez le nombre d'espaces jusqu'à ce que vous atteigniez le 1er caractère non-espace et ajoutez ce nombre à la somme.

Avec la somme, vous devez simplement le fournir au JTextPane.setCaretPosition(). Quelque chose comme:

int caretPosition = 0; 
String[] lines = jTextPane1.getText().split("\n"); 
for (String line : lines) { 
    if (line.contains(search)) { 
     for (int i = 0; i < line.length(); i++) { 
      if (line.charAt(i) != ' ') { 
       break; 
      } 
      caretPosition++; 
     } 
     break; 
    } else { 
     // +1 to include the '\n' character 
     caretPosition += line.length() + 1; 
    } 
} 

jTextPane1.setCaretPosition(caretPosition); 
1

Si vous voulez que votre nouvelle ligne d'avoir la même empreinte que le précédent, vous pouvez le faire en vérifiant simplement les premiers caractères de la ligne précédente. Regardez cela:

public class Test { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame mainFrame = new JFrame("test"); 
       mainFrame.setSize(300, 100); 
       mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       Container pane = mainFrame.getContentPane(); 
       pane.setLayout(new BorderLayout()); 

       JTextPane jtp = new JTP(); 
       pane.add(jtp); 

       mainFrame.setVisible(true); 
      } 
     }); 
    } 

    static class JTP extends JTextPane { 
     JTP() { 
      ((AbstractDocument)getDocument()).setDocumentFilter(new Filter()); 
     } 
    } 

    static class Filter extends DocumentFilter { 
     @Override 
     public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { 
      StringBuilder indentatedString = new StringBuilder(string); 
      if(string.equals("\n")) { 
       AbstractDocument doc = ((AbstractDocument)fb.getDocument()); 
       Element line = doc.getParagraphElement(offset); 
       int lineStart = line.getStartOffset(), lineEnd = line.getEndOffset(); 
       String content = doc.getText(lineStart, lineEnd - lineStart); 
       int start = 0; 
       while(content.charAt(start)==' ') { 
        indentatedString.insert(0," "); 
        start++; 
       } 
      } 
      fb.insertString(offset, indentatedString.toString(), attr); 
     } 
     @Override 
     public void replace(FilterBypass fb, int offset, int length, String text, 
          AttributeSet attrs) throws BadLocationException { 
      if(text.==0) {insertString(fb, offset, text, attrs);} 
      else if(text.length()>0) {remove(fb, offset, length);insertString(fb, offset, text, attrs);} 
      else {fb.replace(offset, length, text, attrs);} 
     } 
    } 
} 

La partie importante ici est seulement le DocumentFilter qui fait le travail.

+0

Dans le filtre pas besoin de passer l'instance de document. FilterBypass fournit getDocument() que vous pouvez utiliser pour obtenir le texte. Pas besoin d'étendre JTextPane et d'installer StyledEditorKit. Le DocumentFilter fonctionnera pour n'importe quel EditorKit, tout ce dont vous avez besoin est de trouver le plus proche \ n après le décalage dans le texte. Pas besoin d'indentation + = ""; dans la boucle. Il est préférable d'utiliser StringBuilder. Remplacer pour une longueur> 0 devrait également traiter ceci. Par exemple. quand je sélectionne un caractère et appuyez sur ENTER. Mais 1+ de toute façon :) – StanislavL

+0

Vous avez 100% raison. Ça fait un moment que je joue avec tout ça et j'ai oublié les détails. J'ai édité ma réponse en conséquence. Dites-moi si j'ai oublié quelque chose. Merci. – Sharcoux