2016-08-07 11 views
1

Ich habe vor kurzem experimentiert mit dem Benutzer von JTextPanes für ein bevorstehendes Projekt, an dem ich arbeiten werde, gab es verschiedene Beiträge online detailliert, wie man über die Anzahl der Zeilen innerhalb der zu zählen Textbereich, aber die Lösungen, die ich gefunden habe, scheinen alle zu versagen, wenn Icons oder Komponenten in das Dokument des Textfensters eingefügt werden.JTextPane Line Count einschließlich Icons und Komponenten

Die Lösung fand ich, dass für Klartext wurde dieser arbeitet man (mit der Lösung natürlich implementiert): BadLocationException when using Utilities.getRowStart On hit of Enter key

Doch sobald ich versuche, was das betrifft eine Komponente (JLabel) oder ein einfaches Symbol einzufügen, die Die Methode getRowStart() von Utilities löst eine Nullzeigerausnahme aus. Was ich an dieser Stelle als ungewöhnlich empfinde, ist das Java-Dokument, das besagt: "... Dies wird im verknüpften Dokument als Attribut eines Inhaltszeichens dargestellt.", Also nahm ich an, es würde es wie jedes andere Zeichen behandeln, aber es scheint so zu sein nicht der Fall.

Ich habe ein Codebeispiel hinzugefügt, um das Problem zu replizieren, wenn es jemand ausprobieren möchte. Ich habe das Gefühl, dass es einfach nicht möglich ist, was schade wäre.

import java.awt.Dimension; 
import java.awt.Image; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JTextPane; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.Utilities; 

public class Test{ 

    private JFrame frame; 
    private JTextPane textPane; 

    private Image img; 
    private URL imgURL; 

    public Test(){ 
     frame = new JFrame(); 
     frame.setSize(new Dimension(500,300)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     textPane = new JTextPane(); 

     try { 
      imgURL = new URL("http://www.freeiconspng.com/uploads/floppy-save-icon--23.png"); 
      img = ImageIO.read(imgURL); 
      JLabel label = new JLabel(new ImageIcon(img.getScaledInstance(10, 10, Image.SCALE_SMOOTH))); 

      textPane.insertComponent(label); 
     } catch (MalformedURLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     frame.getContentPane().add(textPane); 
     frame.setVisible(true); 

    } 
    public JTextPane getTextPane(){ 
     return this.textPane; 
    } 
    public int getLineCount(){ 
     int totalCharacters = textPane.getDocument().getLength(); 
     int lineCount = (totalCharacters == 0) ? 1 : 0; 

     try { 
      int offset = totalCharacters; 
      while (offset > 0) { 
       offset = Utilities.getRowStart(textPane, offset) - 1; 
       lineCount++; 
      } 
     } catch (BadLocationException e) { 
      e.printStackTrace(); 
     } 

     return lineCount; 
    } 
    public static void main(String[] args){ 
     Test t = new Test(); 
     t.getLineCount(); 
    } 
} 
+2

Es keine Ausnahme für mich nicht werfen, wenn ich den Inhalt in Ihrem Hauptverfahren in einem wrap [ 'EventQueue.invokeLater()'] (http://docs.oracle.com/ javase/7/docs/api/java/awt/EreignisQueue.html # invokeLater (java.lang.Runnable)) aufrufen. Ie: 'EventQueue.invokeLater (neues Runnable() {@Override public void run() {Test t = neuer Test(); t.getLineCount();}});' –

+0

Ah ja, das schien das Problem zu lösen, viel geschätzt! – samcp20

+2

@ samcp20 möchten Sie vielleicht die [Text Utilities] (https://tips4java.wordpress.com/2008/10/26/text-utilities/) auschecken. Es enthält eine Methode 'getLines()', die die Textkomponenten-API verwendet, um die Anzahl der Zeilen zu erhalten. Muss zugeben, ich habe es noch nie mit eingefügten Komponenten versucht, aber der Code ist viel einfacher. – camickr

Antwort

3

Das Problem wurde nach dem folgenden Kommentar gelöst:

Es wirft keine Ausnahme für mich, wenn ich den Inhalt innerhalb Ihrer Hauptmethode in einem EventQueue.invokeLater() Anruf wickeln. Dh:

EventQueue.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     Test t = new Test(); 
     t.getLineCount(); 
    } 
});