problem formatting fields in a JTable - differences between Integer and Double

前端 未结 4 1657
清酒与你
清酒与你 2020-11-30 15:05

Update

Confirmed as a bug on JTable can\'t format given Object as Number when columnClass is Double (bug ID: 7051636). Feel free to vote for it, or if if you have

4条回答
  •  遥遥无期
    2020-11-30 15:50

    how did Walter Laan says in his thread

    Never give up! Never surrender!
    

    EDIT: I can't resist, but due to my poor English I dare not to commenting why, where and how is that possible, nor works correctly, for confirmations I added Rob's two (little bit) modified class for TableColumnRendering ...,

    import java.awt.EventQueue;
    import java.math.RoundingMode;
    import java.text.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.RowSorter.SortKey;
    import javax.swing.SwingConstants;
    import javax.swing.table.*;
    
    public class TableExample extends JFrame {
    
        public static final Object EMPTY_ROW = "";
        private static final long serialVersionUID = 1L;
        private JTable tab;
        private Calendar cal;
        private Date dateWithOutTime = new java.util.Date();
        private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");//standard continental EU date format
    
        public class EmptyRowComparator> implements Comparator {//extends RuleBasedCollator{
    
            private TableRowSorter sorter;
            private int column;
    
            public EmptyRowComparator(TableRowSorter sorter, int col) throws ParseException {
                this.sorter = sorter;
                this.column = col;
            }
    
            private int getSortOrder() {
                SortOrder order = SortOrder.ASCENDING;
                for (SortKey sortKey : sorter.getSortKeys()) {
                    if (sortKey.getColumn() == this.column) {
                        order = sortKey.getSortOrder();
                        break;
                    }
                }
                return order == SortOrder.ASCENDING ? 1 : -1;
            }
    
            @Override
            public int hashCode() {
                return 0;
            }
    
            @Override
            @SuppressWarnings("unchecked")
            public int compare(Object arg0, Object arg1) {
                boolean empty1 = arg0 == EMPTY_ROW;
                boolean empty2 = arg1 == EMPTY_ROW;
                if (empty1 && empty2) {
                    return 0;
                } else if (empty1) {
                    return 1 * getSortOrder();
                } else if (empty2) {
                    return -1 * getSortOrder();
                }
                return ((Comparable) (COLUMN_TYPE) arg0).compareTo((COLUMN_TYPE) arg1);
            }
        }
    
        public class ConcreteTable extends AbstractTableMod {
    
            private static final long serialVersionUID = 4672561280810649603L;
            private String[] columnNames = {"Integer", "String", "Integer", "Double", "Boolean", "Double", "String", "Boolean", "Date"};
            private Class[] types = {Integer.class, String.class, String.class, String.class, String.class,
                String.class, String.class, String.class, String.class};
            private int minimumDisplayedRow;
    
            public ConcreteTable() {
                this.minimumDisplayedRow = 10;
                this.datas = new ArrayList>();
                for (int i = 0; i < this.minimumDisplayedRow; i++) {
                    this.addEmptyRow();
                }
                Random rnd = new Random();
                for (int i = 0; i < 7; i++) {
                    ArrayList row = new ArrayList();
                    row.add(i);
                    row.add(((rnd.nextInt(25)) + "prova"));
                    row.add(rnd.nextInt(25));
                    row.add(rnd.nextInt(25) + 3.14);
                    row.add((i % 2 == 0) ? true : false);
                    row.add(rnd.nextInt(25) + 3.14);
                    row.add(((rnd.nextInt(25)) + "prova"));
                    row.add((i % 2 == 0) ? false : true);
                    cal = Calendar.getInstance();
                    cal.add(Calendar.DATE, -rnd.nextInt(25));
                    dateWithOutTime = cal.getTime();
                    String nullTimeForDateString = sdf.format(dateWithOutTime);
                    try {
                        dateWithOutTime = sdf.parse(nullTimeForDateString);
                    } catch (ParseException ex) {
                    }
                    row.add(dateWithOutTime);
                    this.addRow(row);
    
                }
            }
    
            @Override
            public String getColumnName(int col) {
                System.out.println("getColumnName " + col + " = " + columnNames[col]);
                return columnNames[col];
            }
    
            @Override
            protected Class[] getTypeArray() {
                return this.types;
            }
    
            @Override
            protected ArrayList getKeysColumnIndex() {
                ArrayList keys = new ArrayList();
                keys.add(0);
                return keys;
            }
    
            @Override
            public boolean isCellEditable(int row, int col) {
                System.out.println("isCellEditable row " + row + " col " + col);
                if (col == 1) {
                    System.out.println("TRUE");
                    return true;
                }
                return false;
            }
    
            @Override
            protected Object getGeneratedKeys(int col) {
                if (col != 0) {
                    return null;
                }
                return new Integer(this.rowNumber);
            }
    
            @Override
            protected int getMinimumDisplayedRow() {
                return this.minimumDisplayedRow;
            }
        }
    
        public abstract class AbstractTableMod extends AbstractTableModel {
    
            private static final long serialVersionUID = 1L;
            protected ArrayList> datas;
            protected int rowNumber = 0;
    
            protected abstract Class[] getTypeArray();
    
            protected abstract ArrayList getKeysColumnIndex();
    
            protected abstract Object getGeneratedKeys(int col);
    
            protected abstract int getMinimumDisplayedRow();
    
            public int getRowCount() {
                return this.datas.size();
            }
    
            @Override
            public int getColumnCount() {
                return this.getTypeArray().length;
            }
    
            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                if (rowIndex >= this.rowNumber) {
                    return EMPTY_ROW;
                }
                try {
                    ArrayList row = this.datas.get(rowIndex);
                    if (row == null) {
                        return null;
                    }
                    Object obj = row.get(columnIndex);
                    return obj;
                } catch (IndexOutOfBoundsException e) {
                    return null;
                }
            }
    
            @Override
            public void setValueAt(Object value, int row, int col) {
                Class targetColClass = this.getColumnClass(col);
                if (!targetColClass.isInstance(value)) {
                    return;
                }
                if (value instanceof String) {
                    String stringVal = (String) value;
                    if (stringVal.compareTo("") == 0) {
                        return;
                    }
                }
                if (row >= this.rowNumber) {
                    ArrayList newRow = new ArrayList();
                    ArrayList keysIndexList = this.getKeysColumnIndex();
                    for (int i = 0; i < this.getColumnCount(); i++) {
                        if (i == col) {
                            newRow.add(value);
                        } else if (keysIndexList.contains(i)) {
                            newRow.add(this.getGeneratedKeys(i));
                        } else {
                            newRow.add(EMPTY_ROW);
                        }
                    }
                    this.addRow(newRow);
                } else {
                    this.datas.get(row).set(col, value);
                }
                this.fireTableCellUpdated(row, col);
            }
    
            @Override
            @SuppressWarnings("unchecked")
            public Class getColumnClass(int c) {
                if (c > this.getTypeArray().length - 1) {
                    return null;
                } else {
                    return this.getTypeArray()[c];
                }
            }
    
            public void addEmptyRow() {
                ArrayList emptyRow = new ArrayList();
                for (int i = 0; i < this.getTypeArray().length; i++) {
                    emptyRow.add(EMPTY_ROW);
                }
                this.datas.add(emptyRow);
            }
    
            public void addRow(ArrayList row) {
                Object[] types = this.getTypeArray();
                if (types.length != row.size()) {
                    return;
                }
                for (int i = 0; i < row.size(); i++) {
                    Class targetColClass = this.getColumnClass(i);
                    Object rowItem = row.get(i);
                }
                this.datas.add(this.rowNumber, row);
                this.rowNumber++;
                if (this.rowNumber < this.getMinimumDisplayedRow()) {
                    this.datas.remove(this.datas.size() - 1);
                }
                this.fireTableRowsInserted(this.rowNumber, this.rowNumber);
            }
        }
    
        public TableExample() {
            super("JTable example");
            getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
            ConcreteTable model = new ConcreteTable();
            tab = new JTable(model);
            TableRowSorter sorter = new TableRowSorter(model);
            try {
                sorter.setComparator(0, new EmptyRowComparator(sorter, 0));
                sorter.setComparator(1, new EmptyRowComparator(sorter, 1));
                sorter.setComparator(2, new EmptyRowComparator(sorter, 2));
                sorter.setComparator(3, new EmptyRowComparator(sorter, 3));
                sorter.setComparator(4, new EmptyRowComparator(sorter, 4));
                sorter.setComparator(5, new EmptyRowComparator(sorter, 5));
                sorter.setComparator(6, new EmptyRowComparator(sorter, 6));
                sorter.setComparator(7, new EmptyRowComparator(sorter, 7));
                sorter.setComparator(8, new EmptyRowComparator(sorter, 8));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            tab.setRowSorter(sorter);
            JScrollPane table = new JScrollPane(tab);
            this.getContentPane().add(table);
            this.setSize(800, 400);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setRenderers();
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    setVisible(true);
                }
            });
            //TableExample tableExample = new TableExample();
        }
    
        public void setRenderers() {
            TableColumnModel m = tab.getColumnModel();
            //"Integer", "String", "Interger", "Double", "Boolean", "Double", "String", "Boolean", "Date"
            m.getColumn(0).setCellRenderer(NumberRenderer.getIntegerRenderer());
            m.getColumn(2).setCellRenderer(NumberRenderer.getIntegerRenderer());
            m.getColumn(3).setCellRenderer(NumberRenderer.getDoubleRenderer5());
            m.getColumn(5).setCellRenderer(NumberRenderer.getDoubleRenderer3());
            m.getColumn(8).setCellRenderer(FormatRenderer.getDateRenderer());
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    TableExample tableExample = new TableExample();
                }
            });
            TableExample tableExample = new TableExample();
        }
    }
    
    class FormatRenderer extends DefaultTableCellRenderer {
    
        private static final long serialVersionUID = 1L;
        private Format formatter;
        private static DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");//standard continental EU date format
    
        FormatRenderer(Format formatter) {
            this.formatter = formatter;
        }
    
        @Override
        public void setValue(Object value) {
            try {
                if ((value != null)) {
                    if ((value instanceof Number) || (value instanceof Date)) {
                        setHorizontalAlignment(SwingConstants.RIGHT);
                        value = formatter.format(value);
                    }
                }
            } catch (IllegalArgumentException e) {
            }
            super.setValue(value);
        }
    
        public static FormatRenderer getDateRenderer() {
            return new FormatRenderer(dateFormat);
        }
    }
    
    class NumberRenderer extends FormatRenderer {
    
        private static final long serialVersionUID = 1L;
        private static Number numberValue;
        private static NumberFormat nf;
    
        NumberRenderer(NumberFormat formatter) {
            super(formatter);
            setHorizontalAlignment(SwingConstants.RIGHT);
        }
    
        public static NumberRenderer getIntegerRenderer() {
            return new NumberRenderer(NumberFormat.getIntegerInstance());
        }
    
        public static NumberRenderer getDoubleRenderer3() {
            nf = NumberFormat.getNumberInstance();
            nf.setMinimumFractionDigits(3);
            nf.setMaximumFractionDigits(3);
            nf.setRoundingMode(RoundingMode.HALF_UP);
            return new NumberRenderer(nf);
        }
    
        public static NumberRenderer getDoubleRenderer5() {
            nf = NumberFormat.getNumberInstance();
            nf.setMinimumFractionDigits(5);
            nf.setMaximumFractionDigits(5);
            nf.setRoundingMode(RoundingMode.HALF_UP);
            return new NumberRenderer(nf);
        }
    }
    
        

    提交回复
    热议问题