QJCC homepage

biz.chitec.quarterback.swing
Class MultiLineTableRenderer

java.lang.Object
  extended byjava.awt.Component
      extended byjava.awt.Container
          extended byjavax.swing.JComponent
              extended byjavax.swing.text.JTextComponent
                  extended byjavax.swing.JEditorPane
                      extended byjavax.swing.JTextPane
                          extended bybiz.chitec.quarterback.swing.MultiLineTableRenderer
All Implemented Interfaces:
javax.accessibility.Accessible, java.util.EventListener, java.awt.image.ImageObserver, java.awt.MenuContainer, java.beans.PropertyChangeListener, javax.swing.Scrollable, java.io.Serializable, javax.swing.table.TableCellRenderer, javax.swing.event.TableModelListener, TableRowHeightProvider

public class MultiLineTableRenderer
extends javax.swing.JTextPane
implements javax.swing.table.TableCellRenderer, TableRowHeightProvider, javax.swing.event.TableModelListener, java.beans.PropertyChangeListener

Special table cell renderer capable of presenting the content wrapped in multiple lines.

Renderer is based on a JTextPane and can therefore present almost everything, including HTML and whatsoever.

MultiLineTableRenderer's shape is determined by the width set to the column it is presented in: The JTextPane it is based on will use as much width as it is allowed to. Height therefore depends on width. This means, the renderer will need to change cell height during rendering process. This is nothing JTable is prepared for in the first place. We can perform the needed operation nevertheless without too much hazzle. MultiLineTableRenderer has two operation modes for this case:

  1. If there is only one MultiLineTableRenderer in the table and there is only text in the other table columns, it's simple: MultiLineTableRenderer simply sets the height of the currently rendered column as it needs it. This overrides any other setups! We could say, it's the rude mode.
  2. In case there are multiple potential sources for the preferred row height, a controlling instance is needed. Unfortunately, JTable does not offer any infrastructure for this case. However, we happen to have TableCellSizeAdjustor in place, who can do this kind of job perfectly. For communication between the two, TableRowHeightEvents are used.
Using the event mechanism, you can also use any other class. It only has to understand the event type. MultiLineTableRenderer switches automatically to event operation mode as soon as a listener is attached to it. It goes back to raw mode if all listeners are removed from it. Note: In its current implementation, one instance of MultiLineTableRenderer should only be used for renderering cells of one table. For cleaning its internal row height cache, it uses a little trick to attach itself as listener to the model.

Version:
$Id: d410871e8994a744c1b760796049eb1663a9a6a6 $
Author:
Dirk Hillbrecht 2004,2005, based on ideas from Heinz M. Kabutz, http://www.javaspecialists.co.za/
See Also:
TableCellSizeAdjustor, TableRowHeightEvent, TableRowHeightListener, Serialized Form

Nested Class Summary
 
Nested classes inherited from class javax.swing.JEditorPane
javax.swing.JEditorPane.AccessibleJEditorPane, javax.swing.JEditorPane.AccessibleJEditorPaneHTML, javax.swing.JEditorPane.JEditorPaneAccessibleHypertextSupport
 
Nested classes inherited from class javax.swing.text.JTextComponent
javax.swing.text.JTextComponent.AccessibleJTextComponent, javax.swing.text.JTextComponent.KeyBinding
 
Nested classes inherited from class javax.swing.JComponent
javax.swing.JComponent.AccessibleJComponent
 
Nested classes inherited from class java.awt.Container
java.awt.Container.AccessibleAWTContainer
 
Nested classes inherited from class java.awt.Component
java.awt.Component.AccessibleAWTComponent, java.awt.Component.BltBufferStrategy, java.awt.Component.FlipBufferStrategy
 
Field Summary
private  javax.swing.table.TableModel attachedmodel
           
private  javax.swing.JTable attachedtable
           
private  boolean eventmode
           
private  javax.swing.JScrollPane jsp
           
private  java.util.HashMap lastfiredpreferredheight
           
private  javax.swing.event.EventListenerList listenerList
           
protected static javax.swing.border.Border noFocusBorder
           
private  TableRowHeightEvent trhEvent
           
 
Fields inherited from class javax.swing.JTextPane
 
Fields inherited from class javax.swing.JEditorPane
 
Fields inherited from class javax.swing.text.JTextComponent
DEFAULT_KEYMAP, FOCUS_ACCELERATOR_KEY
 
Fields inherited from class javax.swing.JComponent
accessibleContext, TOOL_TIP_TEXT_KEY, ui, UNDEFINED_CONDITION, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, WHEN_FOCUSED, WHEN_IN_FOCUSED_WINDOW
 
Fields inherited from class java.awt.Container
 
Fields inherited from class java.awt.Component
BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT
 
Fields inherited from interface java.awt.image.ImageObserver
ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH
 
Constructor Summary
MultiLineTableRenderer()
          Instanciates a renderer for normal text rendering
MultiLineTableRenderer(java.lang.String contenttype)
          Instanciates a renderer for text of certain type.
 
Method Summary
 void addTableRowHeightListener(TableRowHeightListener l)
          Adds a listener for row height events to the renderer.
protected  void fireTableRowHeightEvent(int type, int columnindex, int rowindex, int newvalue)
          Notify all listeners on changes of a particular preferred row height.
 int getPreferredRowHeight(int column, int row)
          Return the preferred row height for the requested cell.
 boolean getScrollableTracksViewportHeight()
           
 boolean getScrollableTracksViewportWidth()
           
 java.awt.Component getTableCellRendererComponent(javax.swing.JTable jTable, java.lang.Object obj, boolean isSelected, boolean hasFocus, int row, int col)
           
 void propertyChange(java.beans.PropertyChangeEvent evt)
          Listens on JTable: If model changes, rebind
private  void rebindToModel()
           
private  void rebindToTable(javax.swing.JTable newtable)
           
 void removeTableRowHeightListener(TableRowHeightListener l)
          Removes a listener for row height events.
 void tableChanged(javax.swing.event.TableModelEvent e)
          Listens on TableModel: If header changes, clear cache
 
Methods inherited from class javax.swing.JTextPane
addStyle, createDefaultEditorKit, getCharacterAttributes, getInputAttributes, getLogicalStyle, getParagraphAttributes, getStyle, getStyledDocument, getStyledEditorKit, getUIClassID, insertComponent, insertIcon, paramString, removeStyle, replaceSelection, setCharacterAttributes, setDocument, setEditorKit, setLogicalStyle, setParagraphAttributes, setStyledDocument
 
Methods inherited from class javax.swing.JEditorPane
addHyperlinkListener, createEditorKitForContentType, fireHyperlinkUpdate, getAccessibleContext, getContentType, getEditorKit, getEditorKitClassNameForContentType, getEditorKitForContentType, getHyperlinkListeners, getPage, getPreferredSize, getStream, getText, read, registerEditorKitForContentType, registerEditorKitForContentType, removeHyperlinkListener, scrollToReference, setContentType, setEditorKitForContentType, setPage, setPage, setText
 
Methods inherited from class javax.swing.text.JTextComponent
addCaretListener, addInputMethodListener, addKeymap, copy, cut, fireCaretUpdate, getActions, getCaret, getCaretColor, getCaretListeners, getCaretPosition, getDisabledTextColor, getDocument, getDragEnabled, getFocusAccelerator, getHighlighter, getInputMethodRequests, getKeymap, getKeymap, getMargin, getNavigationFilter, getPreferredScrollableViewportSize, getScrollableBlockIncrement, getScrollableUnitIncrement, getSelectedText, getSelectedTextColor, getSelectionColor, getSelectionEnd, getSelectionStart, getText, getToolTipText, getUI, isEditable, loadKeymap, modelToView, moveCaretPosition, paste, processInputMethodEvent, read, removeCaretListener, removeKeymap, removeNotify, select, selectAll, setCaret, setCaretColor, setCaretPosition, setComponentOrientation, setDisabledTextColor, setDragEnabled, setEditable, setFocusAccelerator, setHighlighter, setKeymap, setMargin, setNavigationFilter, setSelectedTextColor, setSelectionColor, setSelectionEnd, setSelectionStart, setUI, updateUI, viewToModel, write
 
Methods inherited from class javax.swing.JComponent
addAncestorListener, addNotify, addPropertyChangeListener, addPropertyChangeListener, addVetoableChangeListener, computeVisibleRect, contains, createToolTip, disable, enable, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, fireVetoableChange, getActionForKeyStroke, getActionMap, getAlignmentX, getAlignmentY, getAncestorListeners, getAutoscrolls, getBorder, getBounds, getClientProperty, getComponentGraphics, getConditionForKeyStroke, getDebugGraphicsOptions, getDefaultLocale, getGraphics, getHeight, getInputMap, getInputMap, getInputVerifier, getInsets, getInsets, getListeners, getLocation, getMaximumSize, getMinimumSize, getNextFocusableComponent, getPropertyChangeListeners, getPropertyChangeListeners, getRegisteredKeyStrokes, getRootPane, getSize, getToolTipLocation, getToolTipText, getTopLevelAncestor, getTransferHandler, getVerifyInputWhenFocusTarget, getVetoableChangeListeners, getVisibleRect, getWidth, getX, getY, grabFocus, isDoubleBuffered, isLightweightComponent, isManagingFocus, isMaximumSizeSet, isMinimumSizeSet, isOpaque, isOptimizedDrawingEnabled, isPaintingTile, isPreferredSizeSet, isRequestFocusEnabled, isValidateRoot, paint, paintBorder, paintChildren, paintComponent, paintImmediately, paintImmediately, print, printAll, printBorder, printChildren, printComponent, processComponentKeyEvent, processKeyBinding, processKeyEvent, processMouseMotionEvent, putClientProperty, registerKeyboardAction, registerKeyboardAction, removeAncestorListener, removePropertyChangeListener, removePropertyChangeListener, removeVetoableChangeListener, repaint, repaint, requestDefaultFocus, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, resetKeyboardActions, reshape, revalidate, scrollRectToVisible, setActionMap, setAlignmentX, setAlignmentY, setAutoscrolls, setBackground, setBorder, setDebugGraphicsOptions, setDefaultLocale, setDoubleBuffered, setEnabled, setFont, setForeground, setInputMap, setInputVerifier, setMaximumSize, setMinimumSize, setNextFocusableComponent, setOpaque, setPreferredSize, setRequestFocusEnabled, setToolTipText, setTransferHandler, setUI, setVerifyInputWhenFocusTarget, setVisible, unregisterKeyboardAction, update
 
Methods inherited from class java.awt.Container
add, add, add, add, add, addContainerListener, addImpl, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getContainerListeners, getFocusTraversalKeys, getFocusTraversalPolicy, getLayout, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusCycleRoot, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paintComponents, preferredSize, printComponents, processContainerEvent, processEvent, remove, remove, removeAll, removeContainerListener, setFocusCycleRoot, setFocusTraversalKeys, setFocusTraversalPolicy, setLayout, transferFocusBackward, transferFocusDownCycle, validate, validateTree
 
Methods inherited from class java.awt.Component
action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, createImage, createImage, createVolatileImage, createVolatileImage, disableEvents, dispatchEvent, enable, enableEvents, enableInputMethods, getBackground, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getFontMetrics, getForeground, getGraphicsConfiguration, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputContext, getInputMethodListeners, getKeyListeners, getLocale, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMouseWheelListeners, getName, getParent, getPeer, getSize, getToolkit, getTreeLock, gotFocus, handleEvent, hasFocus, hide, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isShowing, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, postEvent, prepareImage, prepareImage, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processMouseEvent, processMouseWheelEvent, remove, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, repaint, repaint, repaint, resize, resize, setBounds, setBounds, setCursor, setDropTarget, setFocusable, setFocusTraversalKeysEnabled, setIgnoreRepaint, setLocale, setLocation, setLocation, setName, setSize, setSize, show, show, size, toString, transferFocus, transferFocusUpCycle
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

noFocusBorder

protected static javax.swing.border.Border noFocusBorder

jsp

private javax.swing.JScrollPane jsp

listenerList

private javax.swing.event.EventListenerList listenerList

trhEvent

private TableRowHeightEvent trhEvent

lastfiredpreferredheight

private java.util.HashMap lastfiredpreferredheight

attachedtable

private javax.swing.JTable attachedtable

attachedmodel

private javax.swing.table.TableModel attachedmodel

eventmode

private boolean eventmode
Constructor Detail

MultiLineTableRenderer

public MultiLineTableRenderer()
Instanciates a renderer for normal text rendering


MultiLineTableRenderer

public MultiLineTableRenderer(java.lang.String contenttype)
Instanciates a renderer for text of certain type. Give a MIME type string as parameter. E.g. "text/html" will render HTML text.

Parameters:
contenttype - MIME type string describing the text to be rendered
Method Detail

getScrollableTracksViewportHeight

public boolean getScrollableTracksViewportHeight()
Specified by:
getScrollableTracksViewportHeight in interface javax.swing.Scrollable

getScrollableTracksViewportWidth

public boolean getScrollableTracksViewportWidth()
Specified by:
getScrollableTracksViewportWidth in interface javax.swing.Scrollable

getTableCellRendererComponent

public java.awt.Component getTableCellRendererComponent(javax.swing.JTable jTable,
                                                        java.lang.Object obj,
                                                        boolean isSelected,
                                                        boolean hasFocus,
                                                        int row,
                                                        int col)
Specified by:
getTableCellRendererComponent in interface javax.swing.table.TableCellRenderer

addTableRowHeightListener

public void addTableRowHeightListener(TableRowHeightListener l)
Adds a listener for row height events to the renderer. Adding a listener automatically activates the event mode. So, the listener actually has to do something with the events it receives.

Specified by:
addTableRowHeightListener in interface TableRowHeightProvider
Parameters:
l - The listener

removeTableRowHeightListener

public void removeTableRowHeightListener(TableRowHeightListener l)
Removes a listener for row height events. If the number of listeners attached to this renderer reaches 0, event mode is automatically disabled. Then, the renderer will tickle the map itself to setup a correct row height for its rendering.

Specified by:
removeTableRowHeightListener in interface TableRowHeightProvider
Parameters:
l - The listener

fireTableRowHeightEvent

protected void fireTableRowHeightEvent(int type,
                                       int columnindex,
                                       int rowindex,
                                       int newvalue)
Notify all listeners on changes of a particular preferred row height.


getPreferredRowHeight

public int getPreferredRowHeight(int column,
                                 int row)
Return the preferred row height for the requested cell. The renderer must have been rendered the cell at least once to provide a sensible value here. If it has not, it will return -1.

Specified by:
getPreferredRowHeight in interface TableRowHeightProvider
Parameters:
column - Column to ask
row - Row to ask
Returns:
Value used the last time for the cell.

rebindToTable

private void rebindToTable(javax.swing.JTable newtable)

rebindToModel

private void rebindToModel()

propertyChange

public void propertyChange(java.beans.PropertyChangeEvent evt)
Listens on JTable: If model changes, rebind

Specified by:
propertyChange in interface java.beans.PropertyChangeListener

tableChanged

public void tableChanged(javax.swing.event.TableModelEvent e)
Listens on TableModel: If header changes, clear cache

Specified by:
tableChanged in interface javax.swing.event.TableModelListener

QJCC homepage