PageRenderTime 249ms CodeModel.GetById 60ms app.highlight 123ms RepoModel.GetById 58ms app.codeStats 1ms

/src/mpv5/utils/models/MPTableModel.java

http://mp-rechnungs-und-kundenverwaltung.googlecode.com/
Java | 921 lines | 584 code | 91 blank | 246 comment | 102 complexity | 6c47725df77bb072c14d6bf05509517d MD5 | raw file
  1/*
  2 *  This file is part of YaBS.
  3 *  
  4 *      YaBS is free software: you can redistribute it and/or modify
  5 *      it under the terms of the GNU General Public License as published by
  6 *      the Free Software Foundation, either version 3 of the License, or
  7 *      (at your option) any later version.
  8 *  
  9 *      YaBS is distributed in the hope that it will be useful,
 10 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 *      GNU General Public License for more details.
 13 *  
 14 *      You should have received a copy of the GNU General Public License
 15 *      along with YaBS.  If not, see <http://www.gnu.org/licenses/>.
 16 */
 17package mpv5.utils.models;
 18
 19import java.text.DateFormat;
 20import java.util.ArrayList;
 21import java.util.Arrays;
 22import java.util.HashMap;
 23import java.util.Iterator;
 24import java.util.LinkedList;
 25import java.util.List;
 26import java.util.Map.Entry;
 27import java.util.Set;
 28import java.util.Vector;
 29import javax.swing.DefaultCellEditor;
 30
 31import javax.swing.Icon;
 32import javax.swing.JFormattedTextField;
 33import javax.swing.JLabel;
 34import javax.swing.JTable;
 35import javax.swing.JTextField;
 36import javax.swing.event.ChangeEvent;
 37import javax.swing.event.ListSelectionEvent;
 38import javax.swing.event.TableColumnModelEvent;
 39import javax.swing.event.TableColumnModelListener;
 40import javax.swing.event.TableModelEvent;
 41import javax.swing.table.DefaultTableCellRenderer;
 42import javax.swing.table.DefaultTableModel;
 43import javax.swing.table.TableCellEditor;
 44import mpv5.db.common.Context;
 45import mpv5.db.common.DatabaseObject;
 46import mpv5.db.common.NodataFoundException;
 47import mpv5.db.objects.ValueProperty;
 48import mpv5.globals.Headers;
 49import mpv5.globals.Messages;
 50import mpv5.logging.Log;
 51import mpv5.utils.arrays.ArrayUtilities;
 52import mpv5.utils.numberformat.FormatNumber;
 53import mpv5.utils.renderer.TableCellEditorForDezimal;
 54import mpv5.utils.tables.DynamicTableCalculator;
 55import mpv5.utils.tables.TableCalculator;
 56
 57/**
 58 *
 59 * A custom table model which implements various convenience methods
 60 */
 61public class MPTableModel extends DefaultTableModel implements Cloneable, TableColumnModelListener {
 62
 63    private static final long serialVersionUID = 1L;
 64    private Class[] types;
 65    private boolean[] canEdits;
 66    private Context context;
 67    private Object[] predefinedRow;
 68    private Integer autoCountColumn;
 69    private ArrayList<DynamicTableCalculator> calculators = new ArrayList<DynamicTableCalculator>();
 70    private JTable owner;
 71
 72    /**
 73     * Creates an empty, uneditable model
 74     */
 75    public MPTableModel() {
 76        super();
 77        setEditable(false);
 78
 79        Class[] typs = new Class[333];
 80        for (int i = 0; i < 333; i++) {
 81            typs[i] = Object.class;
 82        }
 83        setTypes(typs);
 84    }
 85
 86    /**
 87     * May get slow on lots of data within the given Context
 88     *
 89     * @param c
 90     * @param target
 91     */
 92    public MPTableModel(final Context c, final JTable target) {
 93        super();
 94        try {
 95            setContext(c);
 96            final ArrayList<DatabaseObject> data = DatabaseObject.getObjects(c, true);
 97            final Object[][] dat = new Object[data.size()][];
 98            final Class[] classes = new Class[100];
 99            int j = 0;
100            LinkedList<String> head = new LinkedList<String>();
101            Entry<String, Object> e;
102            for (DatabaseObject o : data) {
103                final HashMap<String, Object> mod = o.getValues4();
104                Set<Entry<String, Object>> set = mod.entrySet();
105                dat[j] = new Object[set.size()];
106                Iterator<Entry<String, Object>> it = set.iterator();
107                int i = 0;
108                while (it.hasNext()) {
109                    e = it.next();
110                    dat[j][i] = e.getValue();
111                    if (j == 0) {
112                        Class class1 = e.getValue().getClass();
113                        classes[i] = class1;
114                        head.add(i, e.getKey().toUpperCase());
115                    }
116                    i++;
117                }
118                j++;
119            }
120            final Object[] headers = new Object[head.size()];
121            int x = 0;
122            for (String hea : head) {
123                headers[x] = hea;
124                x++;
125            }
126            setDataVector(dat, headers);
127            setEditable(false);
128            setTypes(classes);
129            if (target != null) {
130                target.setAutoCreateRowSorter(true);
131            }
132        } catch (NodataFoundException ex) {
133            Log.Debug(ex);
134        }
135    }
136
137    public <T extends DatabaseObject> MPTableModel(final List<T> list, final JTable target) {
138        super();
139        final Object[][] dat = new Object[list.size()][];
140        final Class[] classes = new Class[100];
141
142        int j = 0;
143        LinkedList<String> head = new LinkedList<String>();
144        Entry<String, Object> e;
145        for (DatabaseObject object : list) {
146            if (context == null) {
147                setContext(object.getContext());
148            }
149            final HashMap<String, Object> mod = object.getValues4();
150            Set<Entry<String, Object>> set = mod.entrySet();
151            dat[j] = new Object[set.size()];
152            Iterator<Entry<String, Object>> it = set.iterator();
153            int i = 0;
154            while (it.hasNext()) {
155                e = it.next();
156                dat[j][i] = e.getValue();
157                if (j == 0) {
158                    Class class1 = e.getValue().getClass();
159                    classes[i] = class1;
160                    head.add(i, e.getKey().toUpperCase());
161                }
162                i++;
163            }
164            j++;
165        }
166
167        final Object[] headers = new Object[head.size()];
168        int x = 0;
169        for (String hea : head) {
170            headers[x] = hea;
171            x++;
172        }
173        setEditable(false);
174        setTypes(classes);
175        try {
176//            Log.PrintArray(dat);
177            Object[] h = getDefaultHeader(15);
178            setDataVector(dat, h);
179        } catch (Exception ge) {
180        }
181        if (target != null) {
182            target.setAutoCreateRowSorter(true);
183        }
184        target.repaint();
185        target.getParent().validate();
186    }
187
188    @Override
189    public MPTableModel clone() {
190        MPTableModel t = new MPTableModel(types, canEdits, getData(), predefinedRow);
191        return t;
192    }
193
194    /**
195     * Creates an uneditable model out of the given data
196     *
197     * @param data
198     */
199    public MPTableModel(Object[][] data) {
200        super();
201
202        if (data != null && data.length > 0) {
203            String[] header = new String[data[0].length];
204            for (int i = 0; i < header.length; i++) {
205                header[i] = "" + i;
206            }
207            setDataVector(data, header);
208            Class[] typs = new Class[header.length];
209            for (int i = 0; i < header.length; i++) {
210                typs[i] = Object.class;
211            }
212            setTypes(typs);
213        }
214
215        setEditable(false);
216    }
217
218//    /**
219//     * Creates an uneditable model out of the given data
220//     * @param list
221//     * @param header
222//     */
223//    public MPTableModel(ArrayList<DatabaseObject> list, String[] header) {
224//        super();
225//        nativeMode = true;
226//        setDataVector(MPTableModelRow.toRows(list), header);
227//
228//    }
229    /**
230     * Creates an uneditable model out of the given data
231     *
232     * @param datstr
233     * @param header
234     */
235    public MPTableModel(Object[][] datstr, String[] header) {
236        super();
237
238        setDataVector(datstr, header);
239        setEditable(false);
240        Class[] typs = new Class[header.length];
241        for (int i = 0; i < header.length; i++) {
242            typs[i] = Object.class;
243        }
244        setTypes(typs);
245    }
246
247    /**
248     * Creates an uneditable model out of the given data
249     *
250     * @param data
251     * @param header
252     */
253    public MPTableModel(Object[][] data, Headers header) {
254        super(data, header.getValue());
255        setEditable(false);
256
257        Class[] typs = new Class[header.getValue().length];
258        for (int i = 0; i < header.getValue().length; i++) {
259            typs[i] = Object.class;
260        }
261        setTypes(typs);
262    }
263
264    /**
265     * Creates an uneditable model out of the given data
266     *
267     * @param datstr
268     * @param header
269     * @param types
270     */
271    public MPTableModel(Object[][] datstr, String[] header, Class[] types) {
272        super(datstr, header);
273        setEditable(false);
274        setTypes(types);
275    }
276
277    /**
278     * Creates an uneditable model out of the given data
279     *
280     * @param types
281     * @param canEdits
282     * @param data
283     * @param columnNames
284     */
285    public MPTableModel(Class[] types, boolean[] canEdits, Object[][] data, Object[] columnNames) {
286        super(data, columnNames);
287        setTypes(types);
288        setCanEdits(canEdits);
289    }
290
291    /**
292     * Creates a model out of the given data
293     *
294     * @param types
295     * @param canEdits
296     * @param columnNames
297     */
298    public MPTableModel(Class[] types, boolean[] canEdits, Object[] columnNames) {
299        super(columnNames, 1);
300        setTypes(types);
301        setCanEdits(canEdits);
302    }
303
304    /**
305     * Creates an uneditable model out of the given data
306     *
307     * @param types
308     * @param data
309     * @param columnNames
310     */
311    public MPTableModel(Class[] types, Object[][] data, Object[] columnNames) {
312        super(data, columnNames);
313        setTypes(types);
314        setEditable(false);
315    }
316
317    /**
318     * Creates an uneditable model out of the given data
319     *
320     * @param types
321     * @param data
322     * @param columnNames
323     */
324    public MPTableModel(List<Object[]> list, String[] header) {
325        super();
326        int width = 0;
327        for (int i = 0; i < list.size(); i++) {
328            Object[] objects = list.get(i);
329            if (objects.length > width) {
330                width = objects.length;
331            }
332        }
333
334        if (list.size() > 0) {
335            if (header == null) {
336                header = new String[width];
337                for (int i = 0; i < header.length; i++) {
338                    header[i] = String.valueOf(i);
339                }
340            }
341            Object[][] arr = ArrayUtilities.listToTableArray(list);
342            setDataVector(arr, header);
343        }
344
345        setEditable(false);
346        Class[] typs = new Class[header.length];
347        for (int i = 0; i < header.length; i++) {
348            typs[i] = Object.class;
349        }
350        setTypes(typs);
351    }
352
353    public MPTableModel(List<ValueProperty> properties) {
354        super();
355        final Object[][] data = new Object[properties.size() + 10][2];
356        for (int i = 0; i < properties.size(); i++) {
357            ValueProperty valueProperty = properties.get(i);
358            data[i][0] = valueProperty.__getCname();
359            data[i][1] = valueProperty.getValueObj();
360        }
361
362        setDataVector(data, new Object[]{Messages.PROPERTY, Messages.VALUE});
363        setEditable(true);
364        setTypes(new Class<?>[]{String.class, Object.class});
365    }
366
367    /**
368     * Add a cell calculator for this model
369     *
370     * @param cv
371     */
372    public void addCalculator(DynamicTableCalculator cv) {
373        this.calculators.add(cv);
374    }
375
376    @Override
377    public Class<?> getColumnClass(int columnIndex) {
378        try {
379            getTypes()[columnIndex].toString();//Check for non-null
380        } catch (Exception e) {
381            return Object.class;
382        }
383        //not sortable
384        if (getTypes()[columnIndex].equals(void.class)) {
385            return Object.class;
386        } else {
387            return getTypes()[columnIndex];
388        }
389    }
390
391    @Override
392    public boolean isCellEditable(int rowIndex, int columnIndex) {
393        new Boolean(getCanEdits()[columnIndex]).toString();//Check for non-null
394        return getCanEdits()[columnIndex];
395    }
396
397    public void setCellEditable(int rowIndex, int columnIndex, boolean editable) {
398        new Boolean(getCanEdits()[columnIndex]).toString();//Check for non-null
399        getCanEdits()[columnIndex] = editable;
400    }
401
402    /**
403     *
404     * @return
405     */
406    public Class[] getTypes() {
407        return types;
408    }
409
410    /**
411     *
412     * @param types
413     */
414    public final void setTypes(Class... types) {
415        this.types = types;
416    }
417
418    /**
419     *
420     * @return
421     */
422    public boolean[] getCanEdits() {
423        return canEdits;
424    }
425
426//    /**
427//     *
428//     * @param canEdits
429//     */
430//    public void setCanEdits(boolean[] canEdits) {
431//        this.canEdits = canEdits;
432//    }
433    /**
434     *
435     * @return
436     */
437    public Vector getColumnIdentifiers() {
438        return columnIdentifiers;
439    }
440
441    /**
442     * Set the table editable
443     *
444     * @param bool
445     */
446    public final void setEditable(boolean bool) {
447        setCanEdits(new boolean[]{bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool,
448                    bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool,
449                    bool, bool, bool, bool, bool, bool, bool, bool, bool});
450    }
451
452    @Override
453    @SuppressWarnings("unchecked")
454    public Object getValueAt(int row, int column) {
455        if (column < getColumnCount()) {
456            if (row < getRowCount()) {
457                return super.getValueAt(row, column);
458            } else {
459                throw new ArrayIndexOutOfBoundsException("The row " + row + " is not within the models row count of " + getRowCount());
460            }
461        } else {
462            throw new ArrayIndexOutOfBoundsException("The column " + column + " is not within the models column count of " + getColumnCount());
463        }
464    }
465
466    /**
467     * Behaves like setValueAt(row, column)
468     *
469     * @param aValue
470     * @param row
471     * @param column
472     * @param dontFire If true, does not fire table cell event!
473     */
474    @SuppressWarnings("unchecked")
475    public void setValueAt(Object aValue, int row, int column, boolean dontFire) {
476        Vector rowVector = (Vector) dataVector.elementAt(row);
477        rowVector.setElementAt(aValue, column);
478        if (!dontFire) {
479            fireTableCellUpdated(row, column);
480        }
481    }
482
483    private void setDataVector(Object[][] object, Headers head) {
484        super.setDataVector(object, head.getValue());
485    }
486
487    @Override
488    public synchronized void fireTableCellUpdated(int row, int column) {
489
490        for (int i = 0; i < calculators.size(); i++) {
491            DynamicTableCalculator calculator = calculators.get(i);
492            if (calculator != null && !calculator.isTargetCell(row, column)) {
493                calculator.calculateOnce();
494            }
495        }
496
497        fireTableChanged(new TableModelEvent(this, row, row, column));
498    }
499
500    /**
501     * Checks if the model has empty rows
502     *
503     * @param columnsToCheck The columns to be checked for emptyness
504     * @return TRUE if the last row of the model has a NULL value at the
505     * specified columns
506     */
507    public boolean hasEmptyRows(int[] columnsToCheck) {
508        boolean empty = true;
509        for (int i = 0; i < columnsToCheck.length; i++) {
510            if (getValueAt(getRowCount() - 1, columnsToCheck[i]) != null) {
511                empty = false;
512            }
513        }
514        return empty;
515    }
516
517    /**
518     * Checks if the model has empty rows
519     *
520     * @param columnsToCheck The columns to be checked for emptyness
521     * @return the count of rows in the model with a NULL or empty "" value at
522     * the specified columns
523     */
524    public int getEmptyRows(int[] columnsToCheck) {
525        int count = 0;
526        for (int j = 0; j < getRowCount(); j++) {
527            boolean found = false;
528            for (int i = 0; i < columnsToCheck.length; i++) {
529                if (getValueAt(j, columnsToCheck[i]) == null || String.valueOf(getValueAt(j, columnsToCheck[i])).length() == 0) {
530                    found = true;
531                }
532            }
533            if (found) {
534                count++;
535            }
536        }
537        return count;
538    }
539
540    /**
541     * Removes the invalid rows
542     *
543     * @param columnsToCheck The columns to be checked for emptyness
544     */
545    public void removeEmptyRows(int[] columnsToCheck) {
546        for (int j = 0; j < getRowCount(); j++) {
547            for (int i = 0; i < columnsToCheck.length; i++) {
548                if (getValueAt(j, columnsToCheck[i]) == null || String.valueOf(getValueAt(j, columnsToCheck[i])).length() == 0) {
549                    removeRow(j);
550                }
551            }
552        }
553    }
554
555    /**
556     * Adds rows to the end of the model. The new rows will contain null
557     * values.<br/> If this.context is defined, Context specific values may be
558     * added.
559     *
560     * @param count
561     */
562    public void addRow(int count) {
563        for (int i = 0; i < count; i++) {
564            if (predefinedRow == null) {
565                addRow((Object[]) null);
566            } else {
567                if (autoCountColumn != null) {
568                    predefinedRow[autoCountColumn] = getRowCount() + 1;
569                }
570                addRow(predefinedRow);
571            }
572        }
573    }
574
575    @Override
576    public void removeRow(int row) {
577        super.removeRow(row);
578        rearrangeAutocountColumn();
579    }
580
581    public void insertRow(int row) {
582        if (predefinedRow == null) {
583            super.insertRow(row, (Object[]) null);
584        } else {
585            super.insertRow(row, predefinedRow);
586        }
587        rearrangeAutocountColumn();
588    }
589
590    @Override
591    public void moveRow(int start, int end, int to) {
592        super.moveRow(start, end, to);
593        rearrangeAutocountColumn();
594    }
595
596    @SuppressWarnings("unchecked")
597    private void rearrangeAutocountColumn() {
598        if (autoCountColumn == null) {
599            return;
600        }
601        int index = 0;
602        for (Object rowVector : dataVector) {
603            ((Vector) rowVector).setElementAt(index + 1, autoCountColumn);
604            fireTableCellUpdated(index++, autoCountColumn);
605        }
606    }
607
608    /**
609     * @return the context
610     */
611    public Context getContext() {
612        return context;
613    }
614
615    /**
616     * @param context the context to set
617     */
618    public final void setContext(Context context) {
619        this.context = context;
620    }
621
622    /**
623     * Define a row which is used in addRow(int)
624     *
625     * @param object
626     */
627    public void defineRow(Object[] object) {
628        predefinedRow = object;
629    }
630
631    /**
632     * Returns all rows where all of the specified columns are not NULL. <br/>
633     *
634     * @param columns
635     * @return
636     */
637    public LinkedList<Object[]> getValidRows(int[] columns) {
638
639        LinkedList<Object[]> rows = new LinkedList<Object[]>();
640        for (int ki = 0; ki < getRowCount(); ki++) {
641            boolean valid = true;
642            for (int i = 0; i < columns.length; i++) {
643                int j = columns[i];
644                if (getValueAt(ki, j) == null || getValueAt(ki, j).toString().length() == 0) {
645                    valid = false;
646                }
647            }
648            if (valid) {
649                Object[] t = new Object[getColumnCount()];
650                for (int i = 0; i < getColumnCount(); i++) {
651                    t[i] = getValueAt(ki, i);
652                }
653                rows.add(t);
654            }
655        }
656        return rows;
657    }
658
659    /**
660     * Set/replace the given rows data
661     *
662     * @param rowData
663     * @param row
664     * @param columnToIgnore
665     */
666    public synchronized void setRowAt(Object[] rowData, int row, Integer... columnToIgnore) {
667
668        if (getRowCount() <= row) {
669            addRow(1);
670        }
671        List<Integer> ignores = Arrays.asList(columnToIgnore);
672        for (Integer i = 0; i < rowData.length; i++) {
673            if (!ignores.contains(i)) {
674                Object object = rowData[i];
675                try {
676                    setValueAt(object, row, i);
677                } catch (Exception e) {
678                }
679            }
680        }
681    }
682
683    /**
684     * Set the auto increment column for addRows(int)
685     *
686     * @param column
687     */
688    public void setAutoCountColumn(int column) {
689        autoCountColumn = column;
690    }
691
692    /**
693     * Returns the data as array
694     *
695     * @return
696     */
697    @SuppressWarnings("unchecked")
698    public Object[][] getData() {
699        Object[][] k = new Object[getRowCount()][getColumnCount()];
700        for (int i = 0; i < k.length; i++) {
701            for (int j = 0; j < k[i].length; j++) {
702                k[i][j] = getValueAt(i, j);
703            }
704        }
705        return k;
706    }
707
708    /**
709     * Returns the last valid row in a table whereas "valid" is defined as "all
710     * columns in columns are not null"
711     *
712     * @param columns
713     * @return
714     */
715    public int getLastValidRow(int[] columns) {
716
717        int row = 0;
718        for (int ki = 0; ki < getRowCount(); ki++) {
719            for (int i = 0; i < columns.length; i++) {
720                int j = columns[i];
721                if (getValueAt(ki, j) == null || getValueAt(ki, j).toString().length() == 0) {
722                } else {
723                    row = ki;
724                }
725            }
726        }
727        return row;
728    }
729
730    /**
731     * Add all rows
732     *
733     * @param rowsl
734     */
735    public void addRows(List<Object[]> rowsl) {
736        for (Object[] obj : rowsl) {
737            addRow(obj);
738        }
739    }
740
741    /**
742     * Adds all rows using the toArray() method of {@link DatabaseObject}
743     *
744     * @param l
745     */
746    public void addRows(ArrayList<DatabaseObject> l) {
747        for (DatabaseObject b : l) {
748            addRow(b.toArray());
749        }
750    }
751
752    /**
753     * Returns an Object where the objects ID is stored in the first column of
754     * the given row; <b>From database/cache, NOT from the model!</b>
755     *
756     * @param <T>
757     * @param selectedRow
758     * @param target
759     * @return
760     */
761    @SuppressWarnings("unchecked")
762    public <T extends DatabaseObject> T getRowAt(int selectedRow, T target) {
763        try {
764            return (T) target.getObject(target.getContext(), Integer.valueOf(String.valueOf(getValueAt(selectedRow, 0))));
765        } catch (Exception ex) {
766            Log.Debug(this, ex.getMessage());
767            return null;
768        }
769    }
770
771    /**
772     * Set the editable columns
773     *
774     * @param editable
775     */
776    public final void setCanEdits(boolean... editable) {
777        this.canEdits = editable;
778    }
779
780    public static TableCellEditor getTablecCellEditorFor(Class<?> clazz) {
781
782        if (clazz.isAssignableFrom(Number.class)) {
783            return new TableCellEditorForDezimal(new JFormattedTextField());
784        } else {
785            return new DefaultCellEditor(new JTextField());
786        }
787    }
788
789    /**
790     * @return the owner
791     */
792    public JTable getOwner() {
793        return owner;
794    }
795
796    /**
797     * @param owner the owner to set
798     */
799    public void setOwner(JTable owner) {
800        this.owner = owner;
801    }
802
803    @Override
804    public void columnAdded(TableColumnModelEvent e) {
805    }
806
807    @Override
808    public void columnRemoved(TableColumnModelEvent e) {
809    }
810
811    @Override
812    public void columnMoved(TableColumnModelEvent e) {
813        resort();
814    }
815
816    @Override
817    public void columnMarginChanged(ChangeEvent e) {
818    }
819
820    @Override
821    public void columnSelectionChanged(ListSelectionEvent e) {
822    }
823
824    private void resort() {
825    }
826
827    private Object[] getDefaultHeader(int x) {
828        Object[] obj = new Object[x];
829        for (int i = 0; i < x; i++) {
830            obj[i] = i;
831        }
832
833        return obj;
834    }
835
836    public void removeColumn(int column) {
837        columnIdentifiers.remove(column);
838        for (Object row : dataVector) {
839            if (row instanceof Vector) {
840                ((Vector) row).remove(column);
841            }
842        }
843        fireTableStructureChanged();
844    }
845
846    /**
847     * Default renderers
848     *
849     */
850    public static class NumberRenderer extends DefaultTableCellRenderer.UIResource {
851
852        public NumberRenderer() {
853            super();
854            setHorizontalAlignment(JLabel.RIGHT);
855        }
856    }
857
858    /**
859     *
860     */
861    public static class DoubleRenderer extends NumberRenderer {
862
863        public DoubleRenderer() {
864            super();
865        }
866
867        @Override
868        public void setValue(Object value) {
869
870            try {
871                setText((value == null) ? "" : FormatNumber.formatDezimal(Double.valueOf(value.toString())));
872            } catch (Exception e) {
873                Log.Debug(MPTableModel.class, "Error caused by: " + value);
874            }
875        }
876    }
877
878    /**
879     *
880     */
881    public static class DateRenderer extends DefaultTableCellRenderer.UIResource {
882
883        DateFormat formatter;
884
885        public DateRenderer() {
886            super();
887        }
888
889        @Override
890        public void setValue(Object value) {
891            if (formatter == null) {
892                formatter = DateFormat.getDateInstance();
893            }
894            try {
895                setText((value == null) ? "" : formatter.format(value));
896            } catch (Exception e) {
897                Log.Debug(e);
898            }
899        }
900    }
901
902    /**
903     *
904     */
905    public static class IconRenderer extends DefaultTableCellRenderer.UIResource {
906
907        public IconRenderer() {
908            super();
909            setHorizontalAlignment(JLabel.CENTER);
910        }
911
912        @Override
913        public void setValue(Object value) {
914            try {
915                setIcon((value instanceof Icon) ? (Icon) value : null);
916            } catch (Exception e) {
917                Log.Debug(e);
918            }
919        }
920    }
921}