Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4256931

Element.getEndOffset() returns one greater than the length of the document

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 1.4.0
    • 1.2.2
    • client-libs
    • beta
    • generic
    • generic



      Name: rlT66838 Date: 07/25/99



      synopsis : Last javax.swing.text.Element within doc may have unexpected count
      description : If you have a DefaultStyledDocument and you are calculating character runs if the last line
      of the document does NOT contain a <CR> then Element.getEndOffset() returns a length one greater than the
      length of the document.

      Suppose your document contains 1 character "a"

      DefaultStyledDoc doc = (DefaultStyledDoc)textPane.getDocument();
      len = doc.getLength();
      (len will equal 1)
      Element run = doc.getCharacterElement(0);
      end = run.getEndOffset();
      (end will equal 2)

      If the document contains 2 characters a<CR>
      then len = end = 2 which is correct
      workaround : int offset = 0;
      int len = doc.getLength();
      int lastLen = Integer.MAX_VALUE;
      int pos
      for (pos = offset; pos < (offset + len); pos = lastLength)
      {
          Element run = doc.getCharacterElement(pos);
          lastEnd = run.getEndOffset();
          // workaround start
          if (lastEnd > len)
          {
              lastEnd = len;
          }
          // End of Workaround
          // chars in run = lastEnd - pos
          // do whatever
      }


      ________TestCase________________________

      Source To Reproduce Problem

      import javax.swing.JButton;
      import javax.swing.JFrame;
      import javax.swing.JTextPane;

      import javax.swing.text.DefaultStyledDocument;
      import javax.swing.text.Element;

      import java.awt.BorderLayout;
      import java.awt.Dimension;

      import java.awt.event.ActionListener;
      import java.awt.event.ActionEvent;
      import java.awt.event.WindowAdapter;
      import java.awt.event.WindowEvent;


      public class TextTest implements ActionListener
      {
          JTextPane textPane;

          public TextTest(JTextPane tp)
          {
              textPane = tp;
          }

          public void actionPerformed(ActionEvent e)
          {
      // System.out.println("TextPane:" + textPane);

              DefaultStyledDocument doc;

              doc = (DefaultStyledDocument)textPane.getDocument();
              int offset = 0;
              int len = doc.getLength();
              System.out.println("Document Length:" + len);
              int lastEnd = Integer.MAX_VALUE;

              int pos;
              for (pos = offset; pos < (offset + len); pos = lastEnd) {
                  Element run = doc.getCharacterElement(pos);
                  lastEnd = run.getEndOffset();
                  //
                  // If last line of text does not contain a CR then lastLen
                  // is 1 more than it should be so we cater for this by making
                  // lastLen equal to doc's length
                  //
       
                  if (lastEnd > len)
                  {
                      System.out.println("Last end is greater than documnet length");
                      System.out.println("lastEnd:" + lastEnd + " doc len:" + len);
                  }
              }
          }


          public static void main(String [] argv) {
              JFrame frame = new JFrame("Text Test");
              frame.addWindowListener(new WindowAdapter() {
                  public void windowClosing(WindowEvent e) {
                      System.exit(0);
                  }
              });
              frame.getContentPane().setLayout(new BorderLayout());
              JTextPane tp = new JTextPane();
              tp.setPreferredSize(new Dimension(300,200));
              frame.getContentPane().add(tp, BorderLayout.CENTER);
              
              JButton button = new JButton("Display Results");
              button.addActionListener(new TextTest(tp));
              frame.getContentPane().add(button, BorderLayout.SOUTH);
              
              frame.pack();
              frame.setVisible(true);
          }
      }

      How to reproduce problem...

      JDK 1.2.2

      1. Run app type xxx then press button "Display Results" this will
      show outputs of run and doc calculations on standard output and
      show that the calcs are incorrect

      2. Add a CR to first line and press button again,
       you will get the correct answer

      JDK 1.2.1

      1. run app and type xxxx and press button you will get correct
      results
      2. delete one character and press button is will show incorrect result


      Hope the above helps you solve the problem

      Regards
      Ewen A Cattanach
      Gentia Software plc.
      (Review ID: 88239)
      ======================================================================

            tprinzing Tim Prinzing (Inactive)
            rlewis Roger Lewis (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: