1 6 7 package com.quikj.client.beans; 8 9 import java.awt.*; 10 import java.awt.event.*; 11 import java.util.*; 12 13 17 public class RichTextCanvas extends java.awt.Canvas 18 { 19 20 public RichTextCanvas(Scrollbar bar, int rows, int cols) 21 { 22 super(); 23 24 this.bar = bar; 25 26 setBackgroundColor(DEFAULT_BACKGROUND_COLOR); 27 28 setForegroundColor(DEFAULT_FOREGROUND_COLOR); 29 30 defaultRows = rows; 31 defaultColumns = cols; 32 33 font = DEFAULT_FONT; 34 super.setFont(font); 35 36 displayList.addElement(new Vector()); 37 38 addComponentListener(new CanvasComponentListener()); 39 bar.addAdjustmentListener(new BarListener()); 40 } 41 42 public RichTextCanvas(Scrollbar bar) 43 { 44 this(bar, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLUMNS); 45 } 46 47 51 public java.awt.Font getFont() 52 { 53 return font; 54 } 55 56 60 public void setFont(java.awt.Font font) 61 { 62 this.font = font; 63 super.setFont(font); 64 65 componentResized(); 66 } 67 68 72 public java.awt.Color getForegroundColor() 73 { 74 return foregroundColor; 75 } 76 77 81 public void setForegroundColor(java.awt.Color foregroundColor) 82 { 83 this.foregroundColor = foregroundColor; 84 85 } 86 87 91 public java.awt.Color getBackgroundColor() 92 { 93 return backgroundColor; 94 } 95 96 100 public void setBackgroundColor(java.awt.Color backgroundColor) 101 { 102 this.backgroundColor = backgroundColor; 103 setBackground(backgroundColor); 104 } 105 106 public Dimension getMinimumSize() 107 { 108 return new Dimension(0, 0); 109 } 110 111 public Dimension getMaximumSize() 112 { 113 return new Dimension(1000000, 1000000); 114 } 115 116 public Dimension getPreferredSize() 117 { 118 Graphics g = getGraphics(); 119 if (g == null) 120 { 121 return new Dimension(0, 0); 122 } 123 124 FontMetrics fm = g.getFontMetrics(); 125 int font_height = fm.getHeight(); 126 int font_width = fm.charWidth('w'); 127 128 return new Dimension(0, 129 font_height * defaultRows); 130 } 131 132 public void paint(Graphics g) 133 { 134 if (barInitialized == false) 135 { 136 initializeBar(); 137 } 138 139 FontMetrics fm = g.getFontMetrics(); 141 int font_height = fm.getHeight(); 142 int x; int y = font_height; 145 int size = displayList.size(); 146 int starting_line = bar.getValue(); 147 int ending_line = starting_line + bar.getVisibleAmount(); 148 if (ending_line > size) ending_line = size; 149 150 Rectangle r = getBounds(); 151 152 try 153 { 154 Image img = createImage(r.width, r.height); 155 Graphics og = img.getGraphics(); 156 og.setClip(0, 0, r.width, r.height); 157 158 for (int i = starting_line; i < ending_line; i++, y+=font_height) 159 { 160 Vector line = (Vector)displayList.elementAt(i); 161 int num_elements = line.size(); 162 163 x = 0; int error_count = 0; 165 for (int j = 0; j < num_elements; j++) 166 { 167 try 168 { 169 TextAttribute element = (TextAttribute)line.elementAt(j); 170 171 Font my_font = getTextAttributeFont(element); 173 og.setFont(my_font); 174 175 og.setColor(getTextAttributeColor(element)); 177 178 FontMetrics my_fm = og.getFontMetrics(my_font); 179 180 og.drawString(element.getText(), x, y); 182 x += my_fm.stringWidth(element.getText()); 183 error_count = 0; 184 } 185 catch (ArrayIndexOutOfBoundsException ex1) 186 { 187 error_count++; 189 190 if (error_count < 3) 191 { 192 try 195 { 196 Thread.sleep(50); 197 } 198 catch (InterruptedException ex2) 199 { 200 } 201 202 j--; 203 continue; 204 } 205 else { 207 error_count = 0; 208 continue; 209 } 210 } 211 } 212 } 213 214 g.drawImage(img, 0, 0, null); 215 } 216 catch (Exception ex) 217 { 218 } 220 } 221 222 private Font getTextAttributeFont(TextAttribute element) 223 { 224 Font my_font = null; 225 if (element.getStyle() != -1) 226 { 227 my_font = new Font(font.getName(), 229 element.getStyle(), font.getSize()); 230 } 231 else 232 { 233 my_font = font; 234 } 235 236 return my_font; 237 } 238 239 private Color getTextAttributeColor(TextAttribute element) 240 { 241 Color my_color = null; 242 if (element.getColor() != null) 243 { 244 my_color = element.getColor(); 245 } 246 else 247 { 248 my_color = foregroundColor; 249 } 250 251 return my_color; 252 } 253 254 private void addTextToDisplayList(String text, 255 Color color, int style, 256 boolean new_line) 257 { 258 Vector line = null; 259 if (new_line == true) 260 { 261 line = new Vector(); 263 displayList.addElement(line); 264 } 265 else 266 { 267 line = (Vector)displayList.elementAt(displayList.size() - 1); 269 } 270 271 TextAttribute element = new TextAttribute(style, color, text); 272 line.addElement(element); 273 } 274 275 private void addNewLineToTextSegment() 276 { 277 displayList.addElement(new Vector()); 278 } 279 280 private void addTextSegment(String text, Color color, int style) 281 { 282 Vector last_line = (Vector)displayList.elementAt(displayList.size() - 1); 283 284 int x = 0; 286 int num_elements = last_line.size(); 287 for (int i = 0; i < num_elements; i++) 288 { 289 TextAttribute attr = (TextAttribute)last_line.elementAt(i); 290 Font f = getTextAttributeFont(attr); 291 FontMetrics fm = getGraphics().getFontMetrics(f); 292 x += fm.stringWidth(attr.getText()); 293 } 294 295 int screen_width = getBounds().width; 297 if (screen_width == 0) 298 { 299 return; 300 } 301 302 int cont_char_width = getGraphics().getFontMetrics(font).charWidth('-'); 303 304 Vector lines = preProcessText(text); 306 int num_lines = lines.size(); 307 308 boolean new_line = false; 309 for (int i = 0; i < num_lines; i++) 310 { 311 String line = (String )lines.elementAt(i); 313 int beg_index = 0; 314 int end_index = line.length(); 315 316 if (end_index > 0) { 318 String line_segment = null; 319 boolean fits = true; 320 boolean hyphen = false; 321 while (beg_index < end_index) { 323 line_segment = line.substring(beg_index, end_index); 324 326 TextAttribute tattr = new TextAttribute(style, color, line_segment); 327 Font f = getTextAttributeFont(tattr); 328 FontMetrics fm = getGraphics().getFontMetrics(f); 329 330 if ((x + fm.stringWidth(line_segment) + cont_char_width) < screen_width) { 333 addTextToDisplayList(line_segment, color, style, new_line); 334 x += fm.stringWidth(line_segment); 335 336 beg_index = end_index; 337 end_index = line.length(); 338 339 if (beg_index <= end_index) 341 { 342 if (fits == false) 346 { 347 if (hyphen == true) 348 { 349 addTextToDisplayList("-", 350 foregroundColor, Font.PLAIN, false); 351 hyphen = false; 352 353 addTextToDisplayList(" ", color, style, true); 354 x = fm.stringWidth(" "); 355 new_line = false; 356 } 357 else 358 { 359 x = 0; 360 new_line = true; 361 } 362 } 363 } 364 365 fits = true; 366 } 367 else { 369 if (hyphen == false) 370 { 371 int saved_index = end_index; 373 int j = 0; 374 375 for (j = line_segment.length() - 1; j >= 0; j--, end_index--) 376 { 377 if (line_segment.charAt(j) == ' ') 378 { 379 end_index--; 380 break; 381 } 382 } 383 384 if (j < 0) { 386 end_index = saved_index; 387 hyphen = true; 388 } 389 } 390 391 if (hyphen == true) 392 { 393 end_index--; 394 } 395 396 fits = false; 397 } 398 399 } 401 x = 0; 402 new_line = true; 403 404 } 409 else { 411 addNewLineToTextSegment(); 412 } 413 } 414 } 415 416 private Vector preProcessText(String text) 417 { 418 char[] array = text.toCharArray(); 419 Vector v = new Vector(); 420 421 StringBuffer buf = new StringBuffer (); 422 for (int i = 0; i < array.length; i++) 423 { 424 switch (array[i]) 425 { 426 case '\t': 427 buf.append("\b\b\b\b\b\b\b\b"); 428 break; 429 430 case '\r': 431 v.addElement(buf.toString()); 432 buf = new StringBuffer (); 433 434 if (i < array.length - 1) 435 { 436 if (array[i+1] == '\n') 437 { 438 i++; 439 } 440 } 441 break; 442 443 case '\n': 444 v.addElement(buf.toString()); 445 buf = new StringBuffer (); 446 break; 447 448 default: 449 buf.append(array[i]); 450 break; 451 } 452 } 453 454 v.addElement(buf.toString()); 455 return v; 456 } 457 458 public void clearText() 459 { 460 displayList.removeAllElements(); 461 displayList.addElement(new Vector()); 462 463 textList.removeAllElements(); 464 465 Graphics g = getGraphics(); 466 if (g != null) 467 { 468 paint(g); 469 } 470 } 471 472 public void addText(String text, Color color, int style) 473 { 474 textList.addElement(new TextAttribute(style, color, text)); 477 478 addTextSegment(text, color, style); 480 481 adjustBar(); 483 484 Graphics g = getGraphics(); 485 if (g != null) 486 { 487 paint(g); 488 } 489 } 490 491 private void componentResized() 492 { 493 displayList = new Vector(); 494 displayList.addElement(new Vector()); 495 496 int size = textList.size(); 497 for (int i = 0; i < size; i++) 498 { 499 TextAttribute attr = (TextAttribute)textList.elementAt(i); 501 addTextSegment(attr.getText(), 502 attr.getColor(), 503 attr.getStyle()); 504 } 505 506 adjustBar(); 507 508 Graphics g = getGraphics(); 509 if (g != null) 510 { 511 paint(g); 512 } 513 } 514 515 private void initializeBar() 516 { 517 int num_lines = getBounds().height / getGraphics().getFontMetrics().getHeight(); 519 520 bar.setValues(0, num_lines, 0, num_lines); 521 bar.setBlockIncrement(num_lines); 522 bar.setUnitIncrement(1); 523 524 barInitialized = true; 525 } 526 527 private void adjustBar() 528 { 529 int num_lines = getBounds().height / getGraphics().getFontMetrics().getHeight(); 530 int size = displayList.size(); 531 532 int max = size < num_lines ? num_lines : size; 535 bar.setValues(max - num_lines, 536 num_lines, 537 0, 538 max); 539 540 bar.setBlockIncrement(num_lines); 541 542 } 543 544 public String getText() 545 { 546 StringBuffer buffer = new StringBuffer (); 547 548 int size = textList.size(); 549 for (int i = 0; i < size; i++) 550 { 551 TextAttribute attribute = (TextAttribute)textList.elementAt(i); 552 buffer.append(attribute.getText()); 553 } 554 555 return buffer.toString(); 556 } 557 558 class CanvasComponentListener implements ComponentListener 559 { 560 public void componentHidden(ComponentEvent e) 561 { 562 } 563 564 public void componentMoved(java.awt.event.ComponentEvent componentEvent) 565 { 566 } 567 568 public void componentResized(java.awt.event.ComponentEvent componentEvent) 569 { 570 RichTextCanvas.this.componentResized(); 572 } 573 574 public void componentShown(java.awt.event.ComponentEvent componentEvent) 575 { 576 } 577 } 578 579 class BarListener implements AdjustmentListener 580 { 581 public void adjustmentValueChanged(java.awt.event.AdjustmentEvent adjustmentEvent) 582 { 583 paint(getGraphics()); 584 } 585 } 586 587 private static final int DEFAULT_NUM_ROWS = 5; 588 private static final int DEFAULT_NUM_COLUMNS = 60; 589 private static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 12); 590 private static final Color DEFAULT_FOREGROUND_COLOR = Color.black; 591 private static final Color DEFAULT_BACKGROUND_COLOR = Color.white; 592 593 private Font font; 594 private Color foregroundColor; 595 private Color backgroundColor; 596 private int defaultRows; 597 private int defaultColumns; 598 599 private Vector textList = new Vector(); 600 private Vector displayList = new Vector(); 601 private Scrollbar bar; 602 private boolean barInitialized = false; 603 } 604 | Popular Tags |