home *** CD-ROM | disk | FTP | other *** search
/ BUG 15 / BUGCD1998_06.ISO / aplic / jbuilder / jsamples.z / WrappingTextViewer.java < prev    next >
Encoding:
Java Source  |  1997-07-30  |  8.5 KB  |  280 lines

  1. package borland.samples.intl.beans;
  2.  
  3. import java.awt.*;
  4. import java.awt.event.*;
  5. import java.io.*;
  6. import java.text.*;
  7. import java.util.*;
  8. import borland.jbcl.control.*;
  9. import borland.jbcl.dataset.*;
  10. import borland.jbcl.view.*;
  11. import borland.jbcl.model.*;
  12. import borland.jbcl.layout.*;
  13.  
  14. import borland.samples.intl.beans.event.*;
  15.  
  16. /**
  17.  * WrappingTextViewer displays and wraps text in a locale-sensitive way.
  18.  * A 'component resized' listener detects when the dimensions of the bean
  19.  * have changed.  Based on the new dimensions, the text is wrapped into
  20.  * lines which are then appended to a JBCL ListControl.
  21.  */
  22. public class WrappingTextViewer extends BevelPanel implements ComponentListener, LocaleChangeListener, NavigationListener, DataChangeListener, AccessListener {
  23.   private BasicVectorContainer basicVectorContainer = new BasicVectorContainer();
  24.   private BasicViewManager basicViewManager = new BasicViewManager(new TextItemPainter(),
  25.                                                                    null);
  26.   private ListControl listControl = new ListControl();
  27.   private BreakIterator breakIterator = BreakIterator.getLineInstance(getLocale());
  28.   private String text = null;
  29.   private int lastWidth = 0;
  30.   private int maxLineWidth = 0;
  31.   private FontMetrics fontMetrics = null;
  32.   private Font font = null;
  33.   private int margin = 30;
  34.   private String columnName = null;
  35.   private DataSet dataSet = null;
  36.  
  37.   public WrappingTextViewer() {
  38.     this("");
  39.   }
  40.  
  41.   public WrappingTextViewer(String text) {
  42.     listControl.setModel(basicVectorContainer);
  43.     listControl.setViewManager(basicViewManager);
  44.     listControl.setReadOnly(true);
  45.     listControl.setUniformWidth(true);
  46.     listControl.setUniformHeight(true);
  47.     addComponentListener(this);
  48.     setLayout(new BorderLayout());
  49.     add(listControl, BorderLayout.CENTER);
  50.     setText(text);
  51.   }
  52.  
  53.   public void setText(String text) {
  54.     this.text = text;
  55.     if ((maxLineWidth > 0) && (fontMetrics != null)) {
  56.       wrapText(true);
  57.     }
  58.   }
  59.  
  60.   public String getText() {
  61.     return text;
  62.   }
  63.  
  64.   public void setLocale(Locale locale) {
  65.     super.setLocale(locale);
  66.     breakIterator = BreakIterator.getLineInstance(locale);
  67.     setText(text);
  68.   }
  69.  
  70.   public Locale getLocale() {
  71.     try {
  72.       return super.getLocale();
  73.     } catch (IllegalComponentStateException e) {
  74.       return Locale.getDefault();
  75.     }
  76.   }
  77.  
  78.   public void setFont(Font font) {
  79.     super.setFont(font);
  80.     if (this.font != font) {
  81.       fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
  82.       listControl.setItemHeight(fontMetrics.getLeading() + fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent());
  83.       this.font = font;
  84.       wrapText(true);
  85.     }
  86.   }
  87.  
  88.   public void localeChanged(LocaleChangeEvent e) {
  89.     breakIterator = BreakIterator.getLineInstance(e.getLocale());
  90.     setText(text);
  91.   }
  92.  
  93.   protected void wrapText(boolean doUnconditionally) {
  94.  
  95.     if (!doUnconditionally && lastWidth == maxLineWidth) {
  96.       return;
  97.     } else {
  98.       lastWidth = maxLineWidth;
  99.     }
  100.  
  101.     Component component = this;
  102.     Frame frame = null;
  103.  
  104.     while ((component = component.getParent()) != null) {
  105.       if (component instanceof Frame) {
  106.     frame = (Frame) component;
  107.     break;
  108.       }
  109.     }
  110.  
  111.     if (frame == null) {
  112.       frame = new Frame();
  113.     }
  114.     this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
  115.     frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
  116.  
  117.     basicVectorContainer.removeAll();
  118.  
  119.     BufferedReader bufferedReader = new BufferedReader(new StringReader(text));
  120.     
  121.     String line;
  122.     try {
  123.       while ((line = bufferedReader.readLine()) != null) {
  124.     breakIterator.setText(line);
  125.     if (fontMetrics.stringWidth(line) < maxLineWidth) {
  126.       basicVectorContainer.addItem(line);
  127.     } else {
  128.       char [] chars = new char[line.length()+1];
  129.       line.getChars(0, chars.length-1, chars, 0);
  130.       chars[chars.length-1] = ' ';
  131.  
  132.       int lastStartPosition = 0;// char position 
  133.       int lastBreakPosition = -1;// char position 
  134.       int wordWidth = 0;         // display width, not char count
  135.       int lineWidth = 0;         // display width, not char count
  136.       int breakCharWidth = 0;    // display width, not char count
  137.       int current = 0;           // index into char array
  138.  
  139.       breakIterator.first();
  140.       while (breakIterator.next() != BreakIterator.DONE) {
  141.         current = breakIterator.current() - 1;
  142.  
  143.         // the width of the word (wordWidth) and break character (breakCharWidth) are maintained separately.
  144.         // the width of the break character is only included in the width of the word (see below) if
  145.         // it's not a whitespace character.
  146.         wordWidth = fontMetrics.charsWidth(chars, lastBreakPosition+1, (current - lastBreakPosition - 1));
  147.  
  148.         breakCharWidth = fontMetrics.charWidth(chars[current]);
  149.         // if the break character is not a whitespace char (e.g., a Japanese kanji character)
  150.         // then it has to be included as part of the word width calculation below
  151.         if (!Character.isWhitespace(chars[current])) {
  152.           wordWidth += breakCharWidth;
  153.           breakCharWidth = 0;
  154.         }
  155.         // will adding the next word make the current line too long?
  156.         if (lineWidth + wordWidth >= maxLineWidth) {
  157.           // failed on first word, treat this as a special case
  158.           if (lastBreakPosition == -1) {
  159.         basicVectorContainer.addItem(new String(chars, lastStartPosition, current));
  160.         lastStartPosition = 0;
  161.         lastBreakPosition = current;
  162.         lineWidth = 0;
  163.         continue;
  164.           }
  165.           // can't always assume it's okay to remove the break character because in some languages (e.g., Japanese)
  166.           // the break character may not be a whitespace character
  167.           int whitespaceOffset = 1;
  168.           if (Character.isWhitespace(chars[lastBreakPosition])) {
  169.         whitespaceOffset = 0;
  170.           }
  171.           basicVectorContainer.addItem(new String(chars, lastStartPosition, lastBreakPosition-lastStartPosition+whitespaceOffset));
  172.           lastStartPosition = lastBreakPosition + 1;
  173.           lastBreakPosition = current;
  174.           lineWidth = wordWidth + breakCharWidth;
  175.           continue;
  176.         }
  177.  
  178.         lastBreakPosition = current;
  179.         lineWidth += wordWidth + breakCharWidth;
  180.       }
  181.       basicVectorContainer.addItem(line.substring(lastStartPosition));
  182.     }
  183.       }
  184.     } catch (Exception e) {
  185.       e.printStackTrace();
  186.     }
  187.     frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  188.     this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  189.   }
  190.  
  191.   public void componentResized(ComponentEvent e) {
  192.     Font targetFont = e.getComponent().getFont();
  193.     maxLineWidth = e.getComponent().getSize().width - margin;
  194.     if (targetFont != font) {
  195.       fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(targetFont);
  196.       listControl.setItemHeight(fontMetrics.getLeading() + fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent());
  197.       font = targetFont;
  198.     }
  199.     wrapText(false);
  200.   }
  201.  
  202.   public void componentMoved(ComponentEvent e) {
  203.   }
  204.  
  205.   public void componentShown(ComponentEvent e) {
  206.   }
  207.  
  208.   public void componentHidden(ComponentEvent e) {
  209.   }
  210.  
  211.   public String getColumnName() {
  212.     return columnName;
  213.   }
  214.  
  215.   public void setColumnName(String columnName) {
  216.     this.columnName = columnName;
  217.   }
  218.  
  219.   public DataSet getDataSet() {
  220.     return dataSet;
  221.   }
  222.  
  223.   public void setDataSet(DataSet dataSet) {
  224.     if (dataSet != null) {
  225.       dataSet.removeAccessListener(this);
  226.       dataSet.removeNavigationListener(this);
  227.       dataSet.removeDataChangeListener(this);
  228.     }
  229.     this.dataSet = dataSet;
  230.     if (dataSet == null)
  231.       setText("");
  232.     else {
  233.       try {
  234.     updateText();
  235.     dataSet.addAccessListener(this);
  236.     dataSet.addNavigationListener(this);
  237.     dataSet.addDataChangeListener(this);
  238.       } catch (DataSetException e) {
  239.         e.printStackTrace();
  240.         return;
  241.       }
  242.     }
  243.   }
  244.  
  245.   public void accessChange(AccessEvent e) {
  246.     updateText();
  247.   }
  248.  
  249.   public void navigated(NavigationEvent e) {
  250.     updateText();
  251.   }
  252.  
  253.   public void dataChanged(DataChangeEvent e) {
  254.     if ((e.getID() == DataChangeEvent.ROW_CHANGE_POSTED) &&
  255.     (e.getRowAffected() == dataSet.getRow())) {
  256.       updateText();
  257.     }
  258.   }
  259.  
  260.   public void postRow(DataChangeEvent e) {
  261.   }
  262.  
  263.   private void updateText() {
  264.     try {
  265.       if ((dataSet != null) &&
  266.           (columnName != null) &&
  267.       (dataSet.isOpen()) &&
  268.       (dataSet.hasColumn(columnName) != null)) {
  269.     setText(dataSet.getString(columnName));
  270.       } else {
  271.     setText("");
  272.       }
  273.     } catch (Exception ex) {
  274.       ex.printStackTrace();
  275.     }
  276.   }
  277. }
  278.  
  279.  
  280.