SwingContent.java 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package gnu.kawa.swingviews;
  2. import javax.swing.text.*;
  3. import javax.swing.undo.*;
  4. import gnu.lists.*;
  5. /** A wrapper around a CharBuffer that implements Swing's Content.
  6. * This allows us to use a CharBuffer for a Document's Content. */
  7. public class SwingContent
  8. implements javax.swing.text.AbstractDocument.Content
  9. {
  10. public final CharBuffer buffer;
  11. public SwingContent (CharBuffer buffer)
  12. {
  13. this.buffer = buffer;
  14. }
  15. public SwingContent (int initialSize)
  16. {
  17. CharBuffer b = new CharBuffer(initialSize);
  18. // Swing assumes that a Content object is initialized to contain
  19. // a single '\n'. This of course is not clearly documented ...
  20. b.append('\n');
  21. this.buffer = b;
  22. }
  23. public SwingContent ()
  24. {
  25. this(100);
  26. }
  27. public int length () { return buffer.length(); }
  28. public void getChars(int where, int len, Segment txt)
  29. throws BadLocationException
  30. {
  31. CharBuffer b = buffer;
  32. int start = b.getSegment(where, len);
  33. if (start < 0)
  34. throw new BadLocationException("invalid offset", where);
  35. txt.offset = start;
  36. txt.array = b.getArray();
  37. txt.count = len;
  38. }
  39. public String getString(int where, int len)
  40. throws BadLocationException
  41. {
  42. CharBuffer b = buffer;
  43. int start = b.getSegment(where, len);
  44. if (start < 0)
  45. throw new BadLocationException("invalid offset", where);
  46. return new String(b.getArray(), start, len);
  47. }
  48. public UndoableEdit remove(int where, int nitems)
  49. throws BadLocationException
  50. {
  51. CharBuffer b = buffer;
  52. int end = where + nitems;
  53. if (nitems < 0 || where < 0 || end > b.length())
  54. throw new BadLocationException("invalid remove", where);
  55. GapUndoableEdit undo = new GapUndoableEdit(where);
  56. undo.content = this;
  57. undo.data = b.substring(where, end);
  58. undo.nitems = nitems;
  59. undo.isInsertion = false;
  60. b.delete(where, end);
  61. return undo;
  62. }
  63. public UndoableEdit
  64. insertString(int where, String str, boolean beforeMarkers)
  65. throws BadLocationException
  66. {
  67. CharBuffer b = buffer;
  68. if (where < 0 || where > b.length())
  69. throw new BadLocationException("bad insert", where);
  70. b.insert(where, str, beforeMarkers);
  71. GapUndoableEdit undo = new GapUndoableEdit(where);
  72. undo.content = this;
  73. undo.data = str;
  74. undo.nitems = str.length();
  75. undo.isInsertion = true;
  76. return undo;
  77. }
  78. public UndoableEdit insertString(int where, String str)
  79. throws BadLocationException
  80. {
  81. return insertString(where, str, false);
  82. }
  83. public javax.swing.text.Position createPosition(int offset)
  84. throws BadLocationException
  85. {
  86. CharBuffer b = buffer;
  87. if (offset < 0 || offset > b.length())
  88. throw new BadLocationException("bad offset to createPosition", offset);
  89. return new GapPosition(b, offset);
  90. }
  91. }
  92. class GapPosition extends SeqPosition
  93. implements javax.swing.text.Position
  94. {
  95. public GapPosition(CharBuffer content, int offset)
  96. {
  97. // Swing Position objects have the 'isAfter' property,
  98. // except for the case when the offset is 0.
  99. super(content, offset, offset!=0);
  100. }
  101. public int getOffset() { return nextIndex(); }
  102. }
  103. class GapUndoableEdit extends AbstractUndoableEdit
  104. {
  105. // False if this is a remove (delete); true if an insertion.
  106. boolean isInsertion;
  107. SwingContent content;
  108. String data;
  109. int startOffset;
  110. int nitems;
  111. GapUndoableEdit(int offset)
  112. {
  113. startOffset = offset;
  114. }
  115. private void doit(boolean isInsertion)
  116. throws BadLocationException
  117. {
  118. //int startOffset = content.positions[content.indexes[startIndex]];
  119. if (isInsertion)
  120. {
  121. // FIXME returns useless Undo
  122. content.insertString(startOffset, data);
  123. }
  124. else
  125. {
  126. // FIXME returns useless Undo
  127. content.remove(startOffset, nitems);
  128. }
  129. }
  130. public void undo () throws CannotUndoException
  131. {
  132. super.undo();
  133. try
  134. {
  135. doit (! isInsertion);
  136. }
  137. catch (BadLocationException ex)
  138. {
  139. throw new CannotUndoException();
  140. }
  141. }
  142. public void redo () throws CannotUndoException
  143. {
  144. super.redo();
  145. try
  146. {
  147. doit (isInsertion);
  148. }
  149. catch (BadLocationException ex)
  150. {
  151. throw new CannotRedoException();
  152. }
  153. }
  154. }