home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-07-30 | 8.5 KB | 280 lines |
- package borland.samples.intl.beans;
-
- import java.awt.*;
- import java.awt.event.*;
- import java.io.*;
- import java.text.*;
- import java.util.*;
- import borland.jbcl.control.*;
- import borland.jbcl.dataset.*;
- import borland.jbcl.view.*;
- import borland.jbcl.model.*;
- import borland.jbcl.layout.*;
-
- import borland.samples.intl.beans.event.*;
-
- /**
- * WrappingTextViewer displays and wraps text in a locale-sensitive way.
- * A 'component resized' listener detects when the dimensions of the bean
- * have changed. Based on the new dimensions, the text is wrapped into
- * lines which are then appended to a JBCL ListControl.
- */
- public class WrappingTextViewer extends BevelPanel implements ComponentListener, LocaleChangeListener, NavigationListener, DataChangeListener, AccessListener {
- private BasicVectorContainer basicVectorContainer = new BasicVectorContainer();
- private BasicViewManager basicViewManager = new BasicViewManager(new TextItemPainter(),
- null);
- private ListControl listControl = new ListControl();
- private BreakIterator breakIterator = BreakIterator.getLineInstance(getLocale());
- private String text = null;
- private int lastWidth = 0;
- private int maxLineWidth = 0;
- private FontMetrics fontMetrics = null;
- private Font font = null;
- private int margin = 30;
- private String columnName = null;
- private DataSet dataSet = null;
-
- public WrappingTextViewer() {
- this("");
- }
-
- public WrappingTextViewer(String text) {
- listControl.setModel(basicVectorContainer);
- listControl.setViewManager(basicViewManager);
- listControl.setReadOnly(true);
- listControl.setUniformWidth(true);
- listControl.setUniformHeight(true);
- addComponentListener(this);
- setLayout(new BorderLayout());
- add(listControl, BorderLayout.CENTER);
- setText(text);
- }
-
- public void setText(String text) {
- this.text = text;
- if ((maxLineWidth > 0) && (fontMetrics != null)) {
- wrapText(true);
- }
- }
-
- public String getText() {
- return text;
- }
-
- public void setLocale(Locale locale) {
- super.setLocale(locale);
- breakIterator = BreakIterator.getLineInstance(locale);
- setText(text);
- }
-
- public Locale getLocale() {
- try {
- return super.getLocale();
- } catch (IllegalComponentStateException e) {
- return Locale.getDefault();
- }
- }
-
- public void setFont(Font font) {
- super.setFont(font);
- if (this.font != font) {
- fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
- listControl.setItemHeight(fontMetrics.getLeading() + fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent());
- this.font = font;
- wrapText(true);
- }
- }
-
- public void localeChanged(LocaleChangeEvent e) {
- breakIterator = BreakIterator.getLineInstance(e.getLocale());
- setText(text);
- }
-
- protected void wrapText(boolean doUnconditionally) {
-
- if (!doUnconditionally && lastWidth == maxLineWidth) {
- return;
- } else {
- lastWidth = maxLineWidth;
- }
-
- Component component = this;
- Frame frame = null;
-
- while ((component = component.getParent()) != null) {
- if (component instanceof Frame) {
- frame = (Frame) component;
- break;
- }
- }
-
- if (frame == null) {
- frame = new Frame();
- }
- this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-
- basicVectorContainer.removeAll();
-
- BufferedReader bufferedReader = new BufferedReader(new StringReader(text));
-
- String line;
- try {
- while ((line = bufferedReader.readLine()) != null) {
- breakIterator.setText(line);
- if (fontMetrics.stringWidth(line) < maxLineWidth) {
- basicVectorContainer.addItem(line);
- } else {
- char [] chars = new char[line.length()+1];
- line.getChars(0, chars.length-1, chars, 0);
- chars[chars.length-1] = ' ';
-
- int lastStartPosition = 0;// char position
- int lastBreakPosition = -1;// char position
- int wordWidth = 0; // display width, not char count
- int lineWidth = 0; // display width, not char count
- int breakCharWidth = 0; // display width, not char count
- int current = 0; // index into char array
-
- breakIterator.first();
- while (breakIterator.next() != BreakIterator.DONE) {
- current = breakIterator.current() - 1;
-
- // the width of the word (wordWidth) and break character (breakCharWidth) are maintained separately.
- // the width of the break character is only included in the width of the word (see below) if
- // it's not a whitespace character.
- wordWidth = fontMetrics.charsWidth(chars, lastBreakPosition+1, (current - lastBreakPosition - 1));
-
- breakCharWidth = fontMetrics.charWidth(chars[current]);
- // if the break character is not a whitespace char (e.g., a Japanese kanji character)
- // then it has to be included as part of the word width calculation below
- if (!Character.isWhitespace(chars[current])) {
- wordWidth += breakCharWidth;
- breakCharWidth = 0;
- }
- // will adding the next word make the current line too long?
- if (lineWidth + wordWidth >= maxLineWidth) {
- // failed on first word, treat this as a special case
- if (lastBreakPosition == -1) {
- basicVectorContainer.addItem(new String(chars, lastStartPosition, current));
- lastStartPosition = 0;
- lastBreakPosition = current;
- lineWidth = 0;
- continue;
- }
- // can't always assume it's okay to remove the break character because in some languages (e.g., Japanese)
- // the break character may not be a whitespace character
- int whitespaceOffset = 1;
- if (Character.isWhitespace(chars[lastBreakPosition])) {
- whitespaceOffset = 0;
- }
- basicVectorContainer.addItem(new String(chars, lastStartPosition, lastBreakPosition-lastStartPosition+whitespaceOffset));
- lastStartPosition = lastBreakPosition + 1;
- lastBreakPosition = current;
- lineWidth = wordWidth + breakCharWidth;
- continue;
- }
-
- lastBreakPosition = current;
- lineWidth += wordWidth + breakCharWidth;
- }
- basicVectorContainer.addItem(line.substring(lastStartPosition));
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
- this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
- }
-
- public void componentResized(ComponentEvent e) {
- Font targetFont = e.getComponent().getFont();
- maxLineWidth = e.getComponent().getSize().width - margin;
- if (targetFont != font) {
- fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(targetFont);
- listControl.setItemHeight(fontMetrics.getLeading() + fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent());
- font = targetFont;
- }
- wrapText(false);
- }
-
- public void componentMoved(ComponentEvent e) {
- }
-
- public void componentShown(ComponentEvent e) {
- }
-
- public void componentHidden(ComponentEvent e) {
- }
-
- public String getColumnName() {
- return columnName;
- }
-
- public void setColumnName(String columnName) {
- this.columnName = columnName;
- }
-
- public DataSet getDataSet() {
- return dataSet;
- }
-
- public void setDataSet(DataSet dataSet) {
- if (dataSet != null) {
- dataSet.removeAccessListener(this);
- dataSet.removeNavigationListener(this);
- dataSet.removeDataChangeListener(this);
- }
- this.dataSet = dataSet;
- if (dataSet == null)
- setText("");
- else {
- try {
- updateText();
- dataSet.addAccessListener(this);
- dataSet.addNavigationListener(this);
- dataSet.addDataChangeListener(this);
- } catch (DataSetException e) {
- e.printStackTrace();
- return;
- }
- }
- }
-
- public void accessChange(AccessEvent e) {
- updateText();
- }
-
- public void navigated(NavigationEvent e) {
- updateText();
- }
-
- public void dataChanged(DataChangeEvent e) {
- if ((e.getID() == DataChangeEvent.ROW_CHANGE_POSTED) &&
- (e.getRowAffected() == dataSet.getRow())) {
- updateText();
- }
- }
-
- public void postRow(DataChangeEvent e) {
- }
-
- private void updateText() {
- try {
- if ((dataSet != null) &&
- (columnName != null) &&
- (dataSet.isOpen()) &&
- (dataSet.hasColumn(columnName) != null)) {
- setText(dataSet.getString(columnName));
- } else {
- setText("");
- }
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
- }
-
-
-