001: package ob.text;
002:
003: /*
004: * Stingray Software Objective Blend
005: * Copyright (C) 1997 Stingray Software, Inc.
006: * All Rights Reserved
007: *
008: * This source code is only intended as a supplement to
009: * the Stingray Objective Blend product. See the Objective
010: * Blend html help documentation for detailed information regarding
011: * using OB classes.
012: *
013: * Author : Jason W. Purdy
014: * Description : MultiText.java - implements the Text class
015: *
016: */
017:
018: /**
019: MultiText
020:
021: implements the text control. MultiText is the third of three in a
022: heirarchy and serves as a multi-line edit control. It also supports
023: vertical scrolling.
024: */
025:
026: import java.awt.*;
027: import com.sun.portal.log.common.PortalLogger;
028: import java.awt.event.*;
029: import java.util.*;
030:
031: public class MultiText extends Text {
032: Hashtable m_htUpDownPositions;
033: boolean m_bAllowEnter = true;
034: boolean m_bAllowVScroll = true;
035:
036: int m_nLastXPosition = -1;
037:
038: /**
039: * Null constructor that forwards to the other constructor with a blank string.
040: */
041: public MultiText() {
042: this ("");
043: }
044:
045: /**
046: * This is the preferred constructor of the MultiText class, which sets
047: * up the up/down arrow positions.
048: */
049: public MultiText(String s) {
050: super (s);
051: m_htUpDownPositions = new Hashtable();
052: }
053:
054: /**
055: * This returns whether or not to allow space.
056: * This method is not functional in the MultiText class.
057: * @return false
058: */
059: public boolean getAllowSpace() {
060: return false;
061: }
062:
063: /**
064: * This returns whether or not vertical scrolling is allowed in the
065: * text control.
066: * @return vertical scrolling behavior flag
067: */
068: public boolean getAllowVScroll() {
069: return m_bAllowVScroll;
070: }
071:
072: /**
073: * This gets the cursor's position.
074: * @return the cursor's position.
075: */
076: public int getCursorPos() {
077:
078: int pos = 0;
079: for (int i = 0; i < cursorPoint.y; i++) {
080: Paragraph p = (Paragraph) m_vParagraphs.elementAt(i);
081: pos += p.getText().length() + 1;
082: }
083:
084: return pos
085: + ((Paragraph) m_vParagraphs.elementAt(cursorPoint.y))
086: .getCursorPos();
087: }
088:
089: /**
090: * This is called whenever the user hits a character to be entered into the text
091: * control.
092: * @param c - character to be inserted
093: */
094: protected boolean insertChar(char c) {
095:
096: if (c == java.awt.event.KeyEvent.CHAR_UNDEFINED)
097: return false;
098:
099: if (m_vParagraphs == null || cursorPoint.y < 0
100: || cursorPoint.y > m_vParagraphs.size() - 1)
101: return false;
102:
103: m_htUpDownPositions.clear();
104: m_nLastXPosition = -1;
105: if (isSelected()) {
106: cut(false);
107: if (textListener != null)
108: textListener.textValueChanged(textEvent);
109: if (m_bAllowVScroll)
110: onVerticalScroll();
111: start();
112: }
113: Paragraph p = (Paragraph) m_vParagraphs
114: .elementAt(cursorPoint.y);
115:
116: if (p.insertChar(c, !isAutoWrap() && !m_bAllowHScroll)) {
117: if (textListener != null)
118: textListener.textValueChanged(textEvent);
119: if (m_bAllowVScroll)
120: onVerticalScroll();
121: update();
122: return true;
123: } else
124: return false;
125: }
126:
127: /**
128: * This returns whether or not the 'Enter' key is allowed.
129: * @return whether or not the 'Enter' key is allowed
130: */
131: public boolean isAllowEnter() {
132: return m_bAllowEnter && getVAlign() == TOP;
133: }
134:
135: /**
136: * This returns whether or not the cursor is at the end.
137: * @return whether or not the cursor is at the end
138: */
139: public boolean isCursorOnEndPos() {
140: if (m_vParagraphs.size() <= cursorPoint.y)
141: return true;
142:
143: if (m_vParagraphs.size() - 1 == cursorPoint.y) {
144: Paragraph p = (Paragraph) m_vParagraphs
145: .elementAt(cursorPoint.y);
146: if (super .getCursorPos() >= p.getText().length())
147: return true;
148: }
149:
150: return false;
151: }
152:
153: /**
154: * This returns the next cursor position within the
155: * HashTable of up/down arrow positions.
156: * @param ParaNum - the index of the Paragraph
157: * @param pos - the cursor position to compare
158: * @see #prevCursorPos
159: */
160: protected int nextCursorPos(int ParaNum, int pos) {
161: if (m_htUpDownPositions.size() == 0)
162: return -1;
163: if (m_htUpDownPositions.containsKey("" + ParaNum)) {
164: int prev = -1;
165: Vector v = (Vector) m_htUpDownPositions.get("" + ParaNum);
166: for (int i = 0; i < v.size(); i++) {
167: Integer n = (Integer) v.elementAt(i);
168: int compare = n.intValue();
169: if (compare > pos)
170: prev = (prev == -1) ? compare : Math.min(prev,
171: compare);
172: }
173: return prev;
174: }
175: return -1;
176: }
177:
178: /**
179: * This is called whenever the user hits the 'Backspace' key.
180: */
181: protected void onBackspaceKey() {
182: m_htUpDownPositions.clear();
183: if (isSelected()) {
184: cut(false);
185: if (textListener != null)
186: textListener.textValueChanged(textEvent);
187: start();
188: } else {
189:
190: Paragraph p = (Paragraph) m_vParagraphs
191: .elementAt(cursorPoint.y);
192:
193: if (!isAutoWrap() && p.getCursorPos() == 0) {
194: if (p.getXOffset() > 0) {
195: setXOffset(0);
196: repaint();
197: return;
198: }
199: if (cursorPoint.y == 0)
200: return;
201: } else {
202: if (cursorPoint.y == 0 && p.getCursorPos() == 0)
203: return;
204: }
205:
206: stop();
207: if (p.getCursorPos() == 0) {
208: String addThis = p.getText();
209: Paragraph pb4 = (Paragraph) m_vParagraphs
210: .elementAt(cursorPoint.y - 1);
211: pb4.setCursorPos((pb4.getText()).length());
212: pb4.setText(pb4.getText() + addThis);
213: m_vParagraphs.removeElement(p);
214: cursorPoint.y--;
215: } else
216: p.onBackspaceKey();
217: if (textListener != null)
218: textListener.textValueChanged(textEvent);
219: start();
220: }
221: if (m_bAllowVScroll)
222: onVerticalScroll();
223: repaint();
224: }
225:
226: /**
227: * This is called whenever the user hits the 'Delete' key.
228: */
229: protected void onDeleteKey() {
230: m_htUpDownPositions.clear();
231: if (isSelected()) {
232: cut(false);
233: if (textListener != null)
234: textListener.textValueChanged(textEvent);
235: start();
236: } else {
237: Paragraph p = (Paragraph) m_vParagraphs
238: .elementAt(cursorPoint.y);
239: if (p.isCursorAtEnd()
240: && (cursorPoint.y >= (m_vParagraphs.size() - 1)))
241: return;
242: if (p.isCursorAtEnd()) {
243: String str = p.getText();
244: Paragraph p2 = (Paragraph) m_vParagraphs
245: .elementAt(cursorPoint.y + 1);
246: str += p2.getText();
247: m_vParagraphs.removeElement(p2);
248: p.setText(str);
249: } else {
250: p.onDeleteKey();
251: }
252: if (textListener != null)
253: textListener.textValueChanged(textEvent);
254: }
255: if (m_bAllowVScroll)
256: onVerticalScroll();
257: repaint();
258: }
259:
260: /**
261: * This is called whenever the user hits the down arrow key.
262: * @param mod - any modifiers used when hitting the key
263: */
264: protected void onDownKey(int mod) {
265: Paragraph p = (Paragraph) m_vParagraphs
266: .elementAt(cursorPoint.y);
267: if (p.isCursorOnLastLine()
268: && cursorPoint.y == (m_vParagraphs.size() - 1)) {
269: onEndKey(mod);
270: return;
271: }
272: stop();
273:
274: if (p.isCursorOnLastLine()) {
275: storePosition(cursorPoint.y, p.getCursorPos());
276: int w = 0;
277: if (m_nLastXPosition == -1) {
278: w = (p.getCursorPoint()).x;
279: m_nLastXPosition = w;
280: } else
281: w = m_nLastXPosition;
282: cursorPoint.y++;
283: Paragraph pp = (Paragraph) m_vParagraphs
284: .elementAt(cursorPoint.y);
285: int testPos = nextCursorPos(cursorPoint.y, 0);
286: if (testPos == -1) {
287: pp.moveSpecial(false, w, KeyEvent.VK_DOWN);
288: } else
289: pp.setCursorPos(testPos);
290:
291: if (mod == java.awt.Event.SHIFT_MASK) {
292: if (p.getSelectionState() == Paragraph.NONE) {
293: p.setSelectionState(Paragraph.PARTIAL);
294: p.setSelectionStart(p.getCursorPos());
295: selectionStart.x = p.getCursorPos();
296: selectionStart.y = cursorPoint.y - 1;
297: if (m_bAllowVScroll)
298: prevYOffset = y_offset;
299: }
300: p.setSelectionEnd((p.getText()).length());
301: if (pp.getSelectionState() == Paragraph.NONE) {
302: pp.setSelectionState(Paragraph.PARTIAL);
303: pp.setSelectionStart(0);
304: }
305: selectionEnd.x = pp.getCursorPos();
306: selectionEnd.y = cursorPoint.y;
307: pp.setSelectionEnd(pp.getCursorPos());
308: } else {
309: if (p.getSelectionState() != Paragraph.NONE)
310: unselectAll();
311: start();
312: }
313: } else {
314: int oldPos = p.getCursorPos();
315: storePosition(cursorPoint.y, oldPos);
316: int testPos = nextCursorPos(cursorPoint.y, oldPos);
317: if (testPos == -1)
318: p.onDownKey();
319: else
320: p.setCursorPos(testPos);
321: int newPos = p.getCursorPos();
322: if (mod == java.awt.Event.SHIFT_MASK) {
323: if (p.getSelectionState() == Paragraph.NONE) {
324: p.setSelectionState(Paragraph.PARTIAL);
325: p.setSelectionStart(oldPos);
326: selectionStart.x = oldPos;
327: selectionStart.y = cursorPoint.y;
328: if (m_bAllowVScroll)
329: prevYOffset = y_offset;
330: }
331: selectionEnd.x = newPos;
332: selectionEnd.y = cursorPoint.y;
333: p.setSelectionEnd(newPos);
334: } else {
335: if (p.getSelectionState() != Paragraph.NONE)
336: unselectAll();
337: start();
338: }
339: }
340: if (m_bAllowVScroll)
341: onVerticalScroll();
342: repaint();
343: }
344:
345: /**
346: * This is called whenever the user hits the 'End' key.
347: * @param mod - any modifiers used while hitting the key
348: */
349: protected void onEndKey(int mod) {
350: Paragraph p = (Paragraph) m_vParagraphs
351: .elementAt(cursorPoint.y);
352: m_htUpDownPositions.clear();
353: m_nLastXPosition = -1;
354: stop();
355: int oldPos = p.getCursorPos();
356: p.onEndKey();
357: int newPos = p.getCursorPos();
358: if (mod == java.awt.Event.SHIFT_MASK) {
359: if (p.getSelectionState() == Paragraph.NONE) {
360: p.setSelectionState(Paragraph.PARTIAL);
361: p.setSelectionStart(oldPos);
362: selectionStart.x = oldPos;
363: selectionStart.y = cursorPoint.y;
364: }
365: selectionEnd.x = newPos;
366: selectionEnd.y = cursorPoint.y;
367: p.setSelectionEnd(newPos);
368: } else {
369: if (p.getSelectionState() != Paragraph.NONE)
370: unselectAll();
371: start();
372: }
373: repaint();
374: }
375:
376: /**
377: * This is called whenever the 'Enter' key is hit.
378: */
379: protected void onEnterKey() {
380: if (!isAllowEnter()) {
381: super .onEnterKey();
382: return;
383: }
384:
385: if (isSelected()) {
386: cut(false);
387: if (textListener != null)
388: textListener.textValueChanged(textEvent);
389: start();
390: }
391:
392: Paragraph p;
393: Paragraph current = (Paragraph) m_vParagraphs
394: .elementAt(cursorPoint.y);
395: String str = current.onEnterKey();
396: m_htUpDownPositions.clear();
397: if (str == null || str.length() < 1)
398: p = new Paragraph(this , "");
399: else
400: p = new Paragraph(this , str);
401: p.setFont(getFont());
402: p.setFontMetrics(getFontMetrics(getFont()));
403: p.setWidth(getSize().width - m_inTextInsets.left
404: - m_inTextInsets.right);
405: p.setForeground(getForeground());
406: p.setBackground(getBackground());
407: p.setInsets(m_inTextInsets);
408: p.setHAlign(m_nHAlign);
409: p.setAllowScroll(getAllowHScroll());
410: p.setAutoWrap(isAutoWrap());
411: m_vParagraphs.insertElementAt(p, cursorPoint.y + 1);
412: cursorPoint.y++;
413: p.setCursorPos(0);
414: if (m_bAllowVScroll)
415: onVerticalScroll();
416: setXOffset(0);
417: if (textListener != null)
418: textListener.textValueChanged(textEvent);
419: repaint();
420: }
421:
422: /**
423: * This is called whenever the user hits the 'Home' key.
424: * @param mod - any modifiers used while hitting the key
425: */
426: protected void onHomeKey(int mod) {
427: Paragraph p = (Paragraph) m_vParagraphs
428: .elementAt(cursorPoint.y);
429: m_htUpDownPositions.clear();
430: m_nLastXPosition = -1;
431: stop();
432: int oldPos = p.getCursorPos();
433: p.onHomeKey();
434:
435: int newPos = p.getCursorPos();
436: if (mod == java.awt.Event.SHIFT_MASK) {
437: if (p.getSelectionState() == Paragraph.NONE) {
438: p.setSelectionState(Paragraph.PARTIAL);
439: p.setSelectionStart(oldPos);
440: selectionStart.x = oldPos;
441: selectionStart.y = cursorPoint.y;
442: }
443: selectionEnd.x = newPos;
444: selectionEnd.y = cursorPoint.y;
445: p.setSelectionEnd(newPos);
446: } else {
447: if (p.getSelectionState() != Paragraph.NONE)
448: unselectAll();
449: start();
450: }
451: repaint();
452: }
453:
454: /**
455: * This is called whenever the left arrow key is hit.
456: * @param mod - any modifiers used when hitting the key
457: */
458: protected void onLeftKey(int mod) {
459: //System.out.println("cursor pos= "+getCursorPos());
460: Paragraph p = (Paragraph) m_vParagraphs
461: .elementAt(cursorPoint.y);
462: int pos = p.getCursorPos();
463: if (pos == 0) {
464: if (p.getXOffset() > 0) {
465: setXOffset(0);
466: repaint();
467: return;
468: }
469: if (cursorPoint.y == 0)
470: return;
471: }
472: m_htUpDownPositions.clear();
473: m_nLastXPosition = -1;
474: stop();
475: Point start = selectionStart;
476: Point end = selectionEnd;
477: if (end.y < start.y || (end.y == start.y && end.x < start.x)) {
478: Point temp = end;
479: end = start;
480: start = temp;
481: }
482: if (pos == 0) {
483: cursorPoint.y--;
484: Paragraph pp = (Paragraph) m_vParagraphs
485: .elementAt(cursorPoint.y);
486: pp.moveSpecial(true, (getSize().width), KeyEvent.VK_LEFT);
487: if (mod == java.awt.Event.SHIFT_MASK) {
488: if (p.getSelectionState() == Paragraph.NONE) {
489: p.setSelectionState(Paragraph.PARTIAL);
490: p.setSelectionStart(0);
491: selectionStart.y = cursorPoint.y + 1;
492: selectionStart.x = 0;
493: }
494: if (pp.getSelectionState() == Paragraph.NONE) {
495: pp.setSelectionState(Paragraph.PARTIAL);
496: pp.setSelectionStart(pp.getCursorPos());
497: }
498: int pos2 = ((pp.getText()).length() > 0) ? pp
499: .getCursorPos() - 1 : pp.getCursorPos();
500: pp.setCursorPos(pos2);
501: selectionEnd.x = pos2;
502: selectionEnd.y = cursorPoint.y;
503: pp.setSelectionEnd(pos2);
504: } else {
505: if (isSelected()) {
506: cursorPoint.y = start.y;
507: cursorPoint.x = start.x;
508: ((Paragraph) m_vParagraphs.elementAt(cursorPoint.y))
509: .setCursorPos(start.x);
510: unselectAll();
511: }
512: start();
513: }
514: } else {
515: p.setCursorPos(--pos);
516: if (mod == java.awt.Event.SHIFT_MASK) {
517: if (p.getSelectionState() == Paragraph.NONE) {
518: p.setSelectionState(Paragraph.PARTIAL);
519: p.setSelectionStart(pos + 1);
520: selectionStart.y = cursorPoint.y;
521: selectionStart.x = pos + 1;
522: }
523: selectionEnd.x = pos;
524: selectionEnd.y = cursorPoint.y; // lwang
525: p.setSelectionEnd(pos);
526: } else {
527: if (isSelected()) {
528: cursorPoint.y = start.y;
529: cursorPoint.x = start.x;
530: ((Paragraph) m_vParagraphs.elementAt(cursorPoint.y))
531: .setCursorPos(start.x);
532: unselectAll();
533: }
534: start();
535: }
536:
537: if (!isAutoWrap()
538: && p.getCursorPoint().x < m_inTextInsets.left + 2) {
539: int offset = p.getXOffset() - getSize().width / 2;
540: if (offset < 0)
541: offset = 0;
542: setXOffset(offset);
543: }
544: }
545: if (m_bAllowVScroll)
546: onVerticalScroll();
547:
548: repaint();
549: }
550:
551: /**
552: * This is called whenever the right key is hit.
553: * @param mod - any modifiers used when hitting the key
554: */
555: protected void onRightKey(int mod) {
556: Paragraph p = (Paragraph) m_vParagraphs
557: .elementAt(cursorPoint.y);
558: int pos = p.getCursorPos();
559: if (cursorPoint.y == (m_vParagraphs.size() - 1)
560: && pos == (p.getText()).length())
561: return;
562: m_htUpDownPositions.clear();
563: m_nLastXPosition = -1;
564: stop();
565: Point start = selectionStart;
566: Point end = selectionEnd;
567: if (end.y < start.y || (end.y == start.y && end.x < start.x)) {
568: Point temp = end;
569: end = start;
570: start = temp;
571: }
572: if (pos == (p.getText()).length()) {
573: cursorPoint.y++;
574: Paragraph pp = (Paragraph) m_vParagraphs
575: .elementAt(cursorPoint.y);
576: pp.moveSpecial(false, 0, KeyEvent.VK_RIGHT);
577: if (mod == java.awt.Event.SHIFT_MASK) {
578: if (p.getSelectionState() == Paragraph.NONE) {
579: p.setSelectionState(Paragraph.PARTIAL);
580: p.setSelectionStart(pos);
581: selectionStart.x = pos;
582: selectionStart.y = cursorPoint.y - 1;
583: }
584: if (pp.getSelectionState() == Paragraph.NONE) {
585: pp.setSelectionState(Paragraph.PARTIAL);
586: pp.setSelectionStart(0);
587: }
588: int pos2 = ((pp.getText()).length() > 0) ? 1 : 0;
589: selectionEnd.x = pos2;
590: selectionEnd.y = cursorPoint.y;
591: pp.setCursorPos(pos2);
592: pp.setSelectionEnd(pos2);
593: } else {
594: if (isSelected()) {
595: cursorPoint.y = end.y;
596: cursorPoint.x = end.x;
597: ((Paragraph) m_vParagraphs.elementAt(cursorPoint.y))
598: .setCursorPos(end.x);
599: unselectAll();
600: }
601: start();
602: }
603: } else {
604: p.setCursorPos(++pos);
605: if (mod == java.awt.Event.SHIFT_MASK) {
606: if (p.getSelectionState() == Paragraph.NONE) {
607: p.setSelectionState(Paragraph.PARTIAL);
608: p.setSelectionStart(pos - 1);
609: selectionStart.x = pos - 1;
610: selectionStart.y = cursorPoint.y;
611: }
612: selectionEnd.x = pos;
613: selectionEnd.y = cursorPoint.y;
614: p.setSelectionEnd(pos);
615: } else {
616: if (isSelected()) {
617: cursorPoint.y = end.y;
618: cursorPoint.x = end.x;
619: ((Paragraph) m_vParagraphs.elementAt(cursorPoint.y))
620: .setCursorPos(end.x);
621: unselectAll();
622: }
623: start();
624: }
625: }
626: if (m_bAllowVScroll)
627: onVerticalScroll();
628: repaint();
629: }
630:
631: /**
632: * This is called whenever the user hits the up arrow key.
633: * @param mod - any modifiers used while hitting the key
634: */
635: protected void onUpKey(int mod) {
636: Paragraph p = (Paragraph) m_vParagraphs
637: .elementAt(cursorPoint.y);
638: if (p.isCursorOnFirstLine() && cursorPoint.y == 0) {
639: onHomeKey(mod);
640: return;
641: }
642: stop();
643: if (p.isCursorOnFirstLine()) {
644: int w = 0;
645: if (m_nLastXPosition == -1) {
646: w = (p.getCursorPoint()).x;
647: m_nLastXPosition = w;
648: } else
649: w = m_nLastXPosition;
650: storePosition(cursorPoint.y, p.getCursorPos());
651: cursorPoint.y--;
652: Paragraph pp = (Paragraph) m_vParagraphs
653: .elementAt(cursorPoint.y);
654: int testPos = prevCursorPos(cursorPoint.y, ((pp.getText())
655: .length()));
656: if (testPos == -1) {
657: pp.moveSpecial(true, w, KeyEvent.VK_UP);
658: } else {
659: pp.setCursorPos(testPos);
660: }
661:
662: if (mod == java.awt.Event.SHIFT_MASK) {
663: if (p.getSelectionState() == Paragraph.NONE) {
664: p.setSelectionState(Paragraph.PARTIAL);
665: p.setSelectionStart(p.getCursorPos());
666: selectionStart.x = p.getCursorPos();
667: selectionStart.y = cursorPoint.y + 1;
668: }
669: p.setSelectionEnd(0);
670: if (pp.getSelectionState() == Paragraph.NONE) {
671: pp.setSelectionState(Paragraph.PARTIAL);
672: pp.setSelectionStart((pp.getText()).length());
673: }
674: selectionEnd.x = pp.getCursorPos();
675: selectionEnd.y = cursorPoint.y;
676: pp.setSelectionEnd(pp.getCursorPos());
677: } else {
678: if (p.getSelectionState() != Paragraph.NONE)
679: unselectAll();
680: start();
681: }
682: } else {
683: int oldPos = p.getCursorPos();
684: storePosition(cursorPoint.y, oldPos);
685: int testPos = prevCursorPos(cursorPoint.y, oldPos);
686: if (testPos == -1)
687: p.onUpKey();
688: else
689: p.setCursorPos(testPos);
690:
691: int newPos = p.getCursorPos();
692: if (mod == java.awt.Event.SHIFT_MASK) {
693: if (p.getSelectionState() == Paragraph.NONE) {
694: p.setSelectionState(Paragraph.PARTIAL);
695: p.setSelectionStart(oldPos);
696: selectionStart.x = oldPos;
697: selectionStart.y = cursorPoint.y;
698: }
699: selectionEnd.x = newPos;
700: selectionEnd.y = cursorPoint.y;
701: p.setSelectionEnd(newPos);
702: } else {
703: if (p.getSelectionState() != Paragraph.NONE)
704: unselectAll();
705: start();
706: }
707: }
708: if (m_bAllowVScroll) {
709: onVerticalScroll();
710: prevYOffset = y_offset;
711: }
712: repaint();
713: }
714:
715: /**
716: * This method is called from text modifications, cursor relocations, etc
717: * whenever the vertical scroll has to be recalculated.
718: */
719: protected void onVerticalScroll() {
720: int marker = 0;
721: int y = 0;
722: for (int i = 0; i <= cursorPoint.y; i++) {
723: marker += ((Paragraph) m_vParagraphs.elementAt(i))
724: .getYSpan();
725: if (marker > y_offset) {
726: y = marker - y_offset;
727: }
728: }
729: Paragraph p = (Paragraph) m_vParagraphs
730: .elementAt(cursorPoint.y);
731: y = y - p.getYSpan() + p.getCursorPoint().y;
732:
733: int nBoardWidth = 2;
734: if (m_nBorderStyle == NONE)
735: nBoardWidth = 0;
736: else if (m_nBorderStyle == NORMAL)
737: nBoardWidth = 1;
738:
739: if ((y + p.getFontMetrics().getHeight() + m_inTextInsets.top
740: + m_inTextInsets.bottom + 2 * nBoardWidth) > (getSize().height)) {
741: //if ((y+(p.getFontMetrics().getHeight()))>(getSize().height-2)) {
742: y_offset += (p.getFontMetrics().getHeight());
743: } else if (y < 0 && y_offset > 0) { // lwang
744: y_offset -= (p.getFontMetrics().getHeight());
745: }
746: }
747:
748: /**
749: * This returns the previous cursor position, given the Paragraph
750: * and comparative cursor position.
751: * This is used for up/down arrow keys to keep from zig-zagging.
752: * @param ParaNum - index of the Paragraph
753: * @param pos - comparative cursor position
754: * @see #nextCursorPos
755: */
756: protected int prevCursorPos(int ParaNum, int pos) {
757: if (m_htUpDownPositions.size() == 0)
758: return -1;
759: if (m_htUpDownPositions.containsKey("" + ParaNum)) {
760: int prev = -1;
761: Vector v = (Vector) m_htUpDownPositions.get("" + ParaNum);
762: for (int i = 0; i < v.size(); i++) {
763: Integer n = (Integer) v.elementAt(i);
764: int compare = n.intValue();
765: if (compare < pos)
766: prev = Math.max(prev, compare);
767: }
768: return prev;
769: }
770: return -1;
771: }
772:
773: /**
774: * This is called whenever a MouseEvent is fired. Overridden
775: * to reset the up/down hashtable & last x position.
776: * @param e - the MouseEvent
777: */
778: protected void processMouseEvent(MouseEvent e) {
779: super .processMouseEvent(e);
780: if (e.getID() == Event.MOUSE_DOWN) {
781: m_htUpDownPositions.clear();
782: m_nLastXPosition = -1;
783: }
784: }
785:
786: /**
787: * This is called whenever a MouseEvent w/ motion is fired. This is
788: * overridden to call onVerticalScroll.
789: * @param e - the MouseEvent
790: */
791: protected void processMouseMotionEvent(MouseEvent e) {
792: Point pt = e.getPoint();
793: if (e.getID() == Event.MOUSE_DRAG) {
794: super .processMouseMotionEvent(e);
795: onVerticalScroll();
796: } else
797: super .processMouseMotionEvent(e);
798: }
799:
800: /**
801: * This sets whether or not the 'Enter' key is allowed.
802: * @param b - allow enter behavior flag
803: */
804: public void setAllowEnter(boolean b) {
805: m_bAllowEnter = b;
806: }
807:
808: /**
809: * This sets whether or not to allow horizontal scrolling in the text
810: * control
811: * @param b - horizontal scrolling behavior flag
812: */
813: public void setAllowHScroll(boolean b) {
814: m_bAllowHScroll = b && getHAlign() == LEFT
815: && getVAlign() == TOP && !isAutoWrap();
816:
817: for (int i = 0; i < m_vParagraphs.size(); i++) {
818: Paragraph p = (Paragraph) m_vParagraphs.elementAt(i);
819: p.setAllowScroll(m_bAllowHScroll);
820: }
821: }
822:
823: /**
824: * This sets whether or not to allow vertical scrolling within the text
825: * control.
826: * @param b - vertical scrolling behavior flag
827: */
828: public void setAllowVScroll(boolean b) {
829: m_bAllowVScroll = b;
830: }
831:
832: /**
833: * This sets the text of the control. This overrides Text's setText to
834: * re-implement newlines.
835: * @param t - new text
836: * @param repaint - whether or not to repaint the text control
837: * @see ob.text.OBLabel#setText
838: * @see ob.text.Text#setText
839: */
840: public void setText(String t, boolean repaint) {
841: if (t == null)
842: t = "";
843: if (m_vParagraphs.size() > 0)
844: m_vParagraphs.removeAllElements();
845: if (t.equals("")) {
846: Paragraph p = new Paragraph(this , t);
847: p.setFont(getFont());
848: p.setFontMetrics(getFontMetrics(getFont()));
849: p.setBackground(getBackground());
850: p.setForeground(getForeground());
851: p.setWidth(getSize().width - m_nWidthOffset);
852: p.setInsets(m_inTextInsets);
853: p.setHAlign(getHAlign());
854: p.setAllowScroll(getAllowHScroll());
855: p.setAutoWrap(isAutoWrap());
856: m_vParagraphs.addElement(p);
857:
858: // lwang
859: cursorPoint = new Point(0, 0);
860: selectionStart = new Point(0, 0);
861: selectionEnd = new Point(0, 0);
862: } else {
863: StringTokenizer st = new StringTokenizer(t, "\n", false);
864: while (st.hasMoreTokens()) {
865: String s = st.nextToken();
866: Paragraph p = new Paragraph(this , s);
867: p.setFont(getFont());
868: p.setFontMetrics(getFontMetrics(getFont()));
869: p.setBackground(getBackground());
870: p.setForeground(getForeground());
871: p.setWidth(getSize().width - m_nWidthOffset);
872: p.setInsets(m_inTextInsets);
873: p.setHAlign(getHAlign());
874: p.setAllowScroll(getAllowHScroll());
875: p.setAutoWrap(isAutoWrap());
876: m_vParagraphs.addElement(p);
877: }
878: }
879:
880: // lwang
881: y_offset = 0;
882: cursorPoint = new Point(0, 0);
883: selectionStart = new Point(0, 0);
884: selectionEnd = new Point(0, 0);
885:
886: if (repaint)
887: repaint();
888: }
889:
890: /**
891: * This sets the vertical alignment of the text control. Overridden
892: * to ensure horizontal scrolling is set correctly.
893: * @param align - vertical alignment (OBLabel.TOP||OBLabel.CENTER||OBLabel.BOTTOM)
894: * @see ob.text.OBLabel#setVAlign
895: */
896: public void setVAlign(int align) {
897: if (align != TOP) {
898: setAllowHScroll(false);
899: }
900:
901: super .setVAlign(align);
902: }
903:
904: /**
905: * This sets the x offset of the text control.
906: * @param n - x offset
907: */
908: public void setXOffset(int n) {
909: int nSize = m_vParagraphs.size();
910:
911: for (int i = 0; i < nSize; i++) {
912: Paragraph p = (Paragraph) m_vParagraphs.elementAt(i);
913: p.setXOffset(n);
914: }
915: }
916:
917: /**
918: * This stores the cursor position of the given Paragraph
919: * into the Hashtable for use with up/down arrow keys.
920: * @param ParaNum - index of the Paragraph
921: * @param pos - cursor position
922: */
923: protected void storePosition(int ParaNum, int pos) {
924: Vector v;
925: if (m_htUpDownPositions.containsKey("" + ParaNum))
926: v = (Vector) m_htUpDownPositions.get("" + ParaNum);
927: else
928: v = new Vector();
929: v.addElement(new Integer(pos));
930: m_htUpDownPositions.put("" + ParaNum, v);
931: }
932: }
|