001: package snow.sortabletable;
002:
003: import javax.swing.table.*;
004: import javax.swing.*;
005: import javax.swing.border.*;
006: import java.awt.*;
007: import java.text.*;
008: import javax.swing.text.*;
009: import java.awt.font.*;
010: import java.awt.geom.*;
011: import java.nio.*;
012: import java.nio.charset.*;
013: import java.util.*;
014:
015: /** Alternative to DefaultTableCellRenderer
016: */
017: public class UniversalTableCellRenderer implements TableCellRenderer {
018: protected final DoubleRenderer doubleRenderer = new DoubleRenderer();
019: protected final StringRenderer stringRenderer = new StringRenderer();
020: protected final ColorRenderer colorRenderer = new ColorRenderer();
021: protected final BooleanRenderer booleanRenderer = new BooleanRenderer();
022:
023: protected Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
024:
025: protected final SortableTableModel sortableTableModel;
026:
027: int fontSize = 10;
028:
029: public UniversalTableCellRenderer() {
030: this .sortableTableModel = null;
031: }
032:
033: /** @param sortableTableModel is used to set column alignments (left, right)
034: */
035: public UniversalTableCellRenderer(
036: SortableTableModel sortableTableModel) {
037: setupUI();
038: this .sortableTableModel = sortableTableModel;
039: }
040:
041: /** must be called after each L&F changes
042: */
043: private void setupUI() {
044: fontSize = UIManager.getFont("Table.font").getSize();
045: noFocusBorder = new EmptyBorder(fontSize / 4, fontSize / 4,
046: fontSize / 4, fontSize / 4);
047:
048: doubleRenderer.setupUI();
049: stringRenderer.setupUI();
050: }
051:
052: // CALLED ONLY FOR COLUMN 0 and 1 ???
053: public Component getTableCellRendererComponent(JTable table,
054: Object value, boolean isSelected, boolean hasFocus,
055: int row, int column) {
056: BasicRenderer comp = getRendererFor(value, column);
057:
058: //new Throwable().printStackTrace();
059:
060: // here comes only string and stringbuffer ????
061: //System.out.println(""+column+" "+value.getClass()+"\t"+value);
062:
063: if (value instanceof Font) {
064: Font font = (Font) value;
065: comp.setValue("Font " + font.getFontName() + ", size="
066: + font.getSize());
067: comp.setFont(font);
068: } else {
069: comp.setFont(table.getFont());
070: comp.setValue(value);
071: }
072:
073: if (value instanceof Color)// || value instanceof javax.swing.plaf.ColorUIResource)
074: {
075: //System.out.println("Color rederer comp");
076: } else {
077: if (isSelected) {
078: //comp.setForeground(table.getSelectionForeground());
079: //comp.setBackground(table.getSelectionBackground());
080: comp.setForeground(UIManager
081: .getColor("Table.selectionForeground"));
082: comp.setBackground(UIManager
083: .getColor("Table.selectionBackground"));
084: } else {
085: //comp.setForeground(table.getForeground());
086: //comp.setBackground(table.getBackground());
087: comp.setForeground(UIManager
088: .getColor("Table.foreground"));
089: comp.setBackground(UIManager
090: .getColor("Table.background"));
091: }
092: }
093:
094: return (Component) comp;
095: }
096:
097: private BasicRenderer getRendererFor(Object value, int viewColumn) {
098: if (value == null)
099: return stringRenderer; // [March2008]: was doubleRenderer;
100: if (value instanceof Double) {
101: return doubleRenderer;
102: } else if (value instanceof Color
103: || value instanceof javax.swing.plaf.ColorUIResource) {
104:
105: return this .colorRenderer;
106: } else if (value instanceof Boolean) {
107: return this .booleanRenderer;
108: } else // String & defaults
109: {
110: // System.out.println(""+value.getClass().getName());
111: if (sortableTableModel != null) {
112: int col = sortableTableModel
113: .getColumnForViewIndex(viewColumn);
114: stringRenderer
115: .setHorizontalAlignment(sortableTableModel
116: .getBasicTableModel()
117: .getColumnAlignment(col));
118: }
119: return stringRenderer;
120: }
121: }
122:
123: //
124: // Renderers
125: //
126:
127: interface BasicRenderer {
128: public void setValue(Object value);
129:
130: public void setFont(Font f);
131:
132: public void setForeground(Color c);
133:
134: public void setBackground(Color c);
135: }
136:
137: class DoubleRenderer extends JComponent implements BasicRenderer {
138: String value = "";
139: DecimalFormat format = new DecimalFormat("#.###");
140: int posPoint = 80;
141: AffineTransform identityTransform = new AffineTransform();
142: FontRenderContext fontRenderContext = new FontRenderContext(
143: identityTransform, false, false);
144: int posX = 0;
145:
146: public DoubleRenderer() {
147: }
148:
149: public void setupUI() {
150: setBorder(noFocusBorder);
151: setOpaque(true);
152: }
153:
154: @Override
155: public void paintComponent(Graphics g) {
156: // fill background and set foreground color.
157: Graphics2D g2 = (Graphics2D) g;
158: g.setColor(this .getBackground());
159: g2.fill(g.getClipBounds());
160: g.setColor(this .getForeground());
161:
162: int fs = g.getFont().getSize();
163: int posY = (int) (this .getSize().getHeight() / 2 + fs / 2);
164:
165: //fontRenderContext
166: //SwingUtilities.
167:
168: g.drawString(value, posX, posY);
169: }
170:
171: public void setValue(Object o) {
172: if (o == null) {
173: System.out
174: .println("Double renderer: null value passed !");
175: value = "<NULL>";
176: } else if (o instanceof Number) // [March2008]: not always Double !
177: {
178: value = format.format((Number) o);
179: } else {
180: System.out.println("Double renderer: not a number !: "
181: + o.getClass() + ": " + o);
182: value = "" + o;
183: }
184:
185: int pos = value.indexOf('.');
186: if (pos < 0)
187: pos = value.length();
188: String beforePoint = value.substring(0, pos);
189: //System.out.println(""+beforePoint+" "+value);
190:
191: TextLayout textLayout = new TextLayout(beforePoint, this
192: .getFont(), fontRenderContext);
193: Rectangle2D bounds = textLayout.getBounds();
194: posX = posPoint - (int) bounds.getWidth();
195: if (posX < 4)
196: posX = 4;
197:
198: }
199: }
200:
201: /* DOESN'T WORK !!!
202: *
203: class DoubleRenderer extends JTextField implements BasicRenderer
204: {
205: DecimalFormat format = new DecimalFormat("0.000");
206: DefaultStyledDocument document = new DefaultStyledDocument();
207: SimpleAttributeSet attributes;
208:
209: public DoubleRenderer()
210: {
211: super();
212: setOpaque(true);
213:
214: this.setEditable(false);
215: this.setDocument(document);
216:
217: TabSet tabset = new TabSet(
218: new TabStop[]{
219: new TabStop(160.2f, TabStop.ALIGN_DECIMAL, TabStop.LEAD_THICKLINE)
220: });
221: attributes = new SimpleAttributeSet();
222: StyleConstants.setTabSet(attributes, tabset);
223: StyleConstants.setForeground(attributes, Color.green);
224:
225: }
226:
227: public void setupUI()
228: {
229: setBorder(noFocusBorder);
230: setOpaque(true);
231: }
232:
233: public void setValue(Object o)
234: {
235: if(o==null)
236: {
237: setText("ERROR: null");
238: //setText("");
239: return;
240: }
241:
242: if(o instanceof Double)
243: {
244: double value = ((Double) o).doubleValue();
245: try
246: {
247: document.remove(0, document.getLength());
248: document.setParagraphAttributes(document.getLength(), 0, attributes, true);
249: document.insertString(document.getLength(), "\t"+format.format(value), attributes);
250: } catch(Exception e){ e.printStackTrace(); }
251: //setText("\t"+format.format(value));
252: return;
253: }
254:
255: try
256: {
257: document.replace(0,document.getLength(), "Bad class "+o.getClass(), attributes);
258: } catch(Exception e){}
259:
260: }
261: } */
262:
263: class StringRenderer extends JLabel implements BasicRenderer {
264: public StringRenderer() {
265: super ();
266: setOpaque(true);
267: }
268:
269: public void setupUI() {
270: setBorder(noFocusBorder);
271: setOpaque(true);
272: }
273:
274: public void setValue(Object o) {
275: setText("" + o);
276: }
277: }
278:
279: class ColorRenderer extends JLabel implements BasicRenderer {
280: public ColorRenderer() {
281: super ();
282: setOpaque(true);
283: }
284:
285: public void setupUI() {
286: setBorder(noFocusBorder);
287: setOpaque(true);
288: }
289:
290: public void setValue(Object o) {
291: this .setText("");
292: if (o == null) {
293: this .setText("<null>");
294: return;
295: }
296:
297: if (o instanceof Color) {
298: this .setBackground((Color) o);
299: }
300: /* else if (o instanceof javax.swing.plaf.ColorUIResource)
301: {
302: System.out.println("*");
303: javax.swing.plaf.ColorUIResource col = (javax.swing.plaf.ColorUIResource) o;
304: this.setBackground(new Color(col.getRGB()));
305: }*/
306: else {
307: this .setText("ERROR " + o.getClass().getName());
308: }
309: }
310: }
311:
312: class BooleanRenderer extends JCheckBox implements BasicRenderer {
313: public BooleanRenderer() {
314: super ();
315: setOpaque(true);
316: }
317:
318: public void setupUI() {
319: setBorder(noFocusBorder);
320: setOpaque(true);
321: }
322:
323: public void setValue(Object o) {
324: if (o instanceof Boolean) {
325: this .setSelected(((Boolean) o).booleanValue());
326: }
327: }
328: }
329:
330: }
|