JTable 中的格式化字段问题 - Integer 和 Double 之间的差异

2024-04-28

##更新## 已确认为错误当 columnClass 为 Double 时,JTable 无法将给定对象格式化为 Number(错误 ID:7051636) https://bugs.java.com/bugdatabase/view_bug?bug_id=7051636。请随意投票,或者如果您有替代(更好)的解决方法,请将其作为报告的评论发布。


我正在构建一个 JTable,其中包含扩展 AbstractTableModel 的自定义表模型。 我的模型需要支持空行的显示和排序。 所以我遵循了这个来实现这一点,现在效果很好。

我仍然遇到 JTable 中格式化字段的问题。 假设我有以下模型:

public class MyModel extends AbstractTableModel{

    public Object[] types= {new Integer(0), ""};
    public static final Object EMPTY_ROW = "";

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
         return this.EMPTY_ROW;
    }
    public Class<? extends Object> getColumnClass(int c) {
      if (c > this.types.length - 1)
        return null;
      else
        return this.types[c].getClass();
    
    }
}

一切正常。 但如果我有一个 Double 而不是 Integer:

public class MyModel extends AbstractTableModel{
    
        public Object[] types= {new Double(0.0), ""};
  .......

我会得到一个非法参数异常:

编辑: @Aaron Digulla 建议后的新堆栈跟踪输出

线程“AWT-EventQueue-0”中的异常 java.lang.IllegalArgumentException:无法将给定对象格式化为数字 在 java.text.DecimalFormat.format(DecimalFormat.java:487) 在 java.text.Format.format(Format.java:140) 在 javax.swing.JTable$DoubleRenderer.setValue(JTable.java:5352) 在 javax.swing.table.DefaultTableCellRenderer.getTableCellRendererComponent(DefaultTableCellRenderer.java:237) 在javax.swing.JTable.prepareRenderer(JTable.java:5720) 在javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2072) 在javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1974) 在javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1770) 在 javax.swing.plaf.ComponentUI.update(ComponentUI.java:143) 在 javax.swing.JComponent.paintComponent(JComponent.java:752) 在 javax.swing.JComponent.paint(JComponent.java:1029) 在 javax.swing.JComponent.paintChildren (JComponent.java:862) 在 javax.swing.JComponent.paint(JComponent.java:1038) 在 javax.swing.JViewport.paint(JViewport.java:747) 在 javax.swing.JComponent.paintChildren (JComponent.java:862) 在 javax.swing.JComponent.paint(JComponent.java:1038) 在 javax.swing.JComponent.paintChildren (JComponent.java:862) 在 javax.swing.JComponent.paint(JComponent.java:1038) 在 javax.swing.JComponent.paintChildren (JComponent.java:862) 在 javax.swing.JComponent.paint(JComponent.java:1038) 在 javax.swing.JLayeredPane.paint(JLayeredPane.java:567) 在 javax.swing.JComponent.paintChildren (JComponent.java:862) 在 javax.swing.JComponent.paintToOffscreen(JComponent.java:5131) 在 javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:278) 在 javax.swing.RepaintManager.paint(RepaintManager.java:1224) 在 javax.swing.JComponent.paint(JComponent.java:1015) 在 java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21) 在 sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60) 在 sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97) 在 java.awt.Container.paint(Container.java:1780) 在 java.awt.Window.paint(Window.java:3375) 在 javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796) 在 javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713) 在 javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693) 在 javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125) 在 java.awt.event.InitationEvent.dispatch(InitationEvent.java:209) 在 java.awt.EventQueue.dispatchEvent(EventQueue.java:597) 在java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) 在 java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) 在java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) 在java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) 在java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) 在 java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

为什么这个?

getValueAt 始终返回相同的值以用它填充所有表条目。 这仅用于调试:

@Override
    public Object getValueAt(int rowIndex, int columnIndex) {
         return this.EMPTY_ROW;
    }

例如,如果我更改为:

 @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
         return new Integer(3);
         //or return new Double(3.3);
         //return new String("foobar"); doesn't work
    }

即使表的某些字段是字符串,一切都可以正常工作。这向我表明,因为 Integer 和 Double 可以转换为 String,这不会引起问题。 无论如何,我想了解为什么像我的 EMPTY_ROW 这样的通用对象可以被接受作为声明的 Integer 字段的值,而这不适用于 Double 字段。

EDIT2:

如果我删除表模型中的 getClass 方法。有用。无论如何,我想解决这个问题,而不必删除该方法,即使这将迫使我实现一些自定义渲染方法。

EDIT3:

这是一个 SSCCE。向表中添加新值时出现一些错误,但与渲染问题无关。

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Comparator;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SortOrder;
import javax.swing.RowSorter.SortKey;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableRowSorter;


public class TableExample extends JFrame{
    public static final  Object EMPTY_ROW = "";
    public class EmptyRowComparator<COLUMN_TYPE extends Comparable<COLUMN_TYPE>> implements Comparator<Object>{//extends RuleBasedCollator{

        private TableRowSorter<? extends AbstractTableMod> sorter;
    private int column;

        public EmptyRowComparator(TableRowSorter<? extends AbstractTableMod> sorter, int col) throws ParseException {
        //  super(arg0);
            this.sorter = sorter;
            this.column = col;
            // TODO Auto-generated constructor stub
        }
        
        
        
         private int getSortOrder() {
             SortOrder order = SortOrder.ASCENDING;
//           List<? extends SortKey> keys = sorter.getSortKeys();
//           sorter.getSortKeys();
//       
        
             for (SortKey sortKey : sorter.getSortKeys()) {
                 if (sortKey.getColumn() == this.column) {
                     order = sortKey.getSortOrder();
                     break;
                 }
             }
             return order == SortOrder.ASCENDING ? 1 : -1;
         }
         


        @Override
        public int hashCode() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public int compare(Object arg0, Object arg1) {
            // TODO Auto-generated method stub
            //System.out.println("Comparing Integer arg0 " + arg0 + " arg1 " + 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>) (COLUMN_TYPE)arg0).compareTo((COLUMN_TYPE)arg1);
        //  return 0;
        }

    }

    public class ConcreteTable extends AbstractTableMod{

        //
        private static final long serialVersionUID = 4672561280810649603L;
        private String[] columnNames = {"ID",
                                        "description"};
        
        
        Class[] types = {Integer.class, String.class};
        //Object[] types = {Double.class, String.class};
        private int minimumDisplayedRow;
        
        
        public ConcreteTable(){
            //System.out.println("DEBUG ARRAY length " + data.length);
            this.minimumDisplayedRow = 10;
            this.datas = new ArrayList<ArrayList<Object>>();
            for (int i = 0 ; i < this.minimumDisplayedRow  ; i++){
                this.addEmptyRow();
            }
            for (int i = 0 ; i < 5 ; i++){
                ArrayList<Object> row = new ArrayList<Object>();
                row.add(new Integer(i));
                row.add(new String("prova " + i));
                this.addRow(row);
            }
            
        }


        public String getColumnName(int col) {
            System.out.println("getColumnName " + col + " = " + columnNames[col]);
            return columnNames[col];
        }
        
        @Override
        protected Class[] getTypeArray() {
            // TODO Auto-generated method stub
            return this.types;
        }

        @Override
        protected ArrayList<Integer> getKeysColumnIndex() {
            // TODO Auto-generated method stub
            ArrayList<Integer> keys = new ArrayList<Integer>();
            keys.add(0);
            return keys;
        }
        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;
        }
        /*note: generated keys must be in the same order they appear in the table*/
        @Override
        protected Object getGeneratedKeys(int col) {
            // TODO Auto-generated method stub
            if (col != 0 )
                return null;
            return new Integer(this.rowNumber);
        }
        @Override
        protected int getMinimumDisplayedRow() {
            // TODO Auto-generated method stub
            return this.minimumDisplayedRow;
        }
        
        
    }

    public abstract class AbstractTableMod extends AbstractTableModel {

        
        ArrayList<ArrayList<Object>> datas ;
        protected int rowNumber = 0;
        protected abstract Class[] getTypeArray();
        protected abstract ArrayList<Integer> 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<Object> row = this.datas.get(rowIndex);
                if (row == null)
                    return null;
                Object obj = row.get(columnIndex);
                return obj;
            }catch(IndexOutOfBoundsException e){
                return null;
            }

            
        }
        public void setValueAt(Object value, int row, int col) {
            
            //System.out.println("setValueAt object : " + value.getClass().getName());
            Class<? extends Object> 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<Object> newRow = new ArrayList<Object>();
                ArrayList<Integer> 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);
            
        }
        public Class<? extends Object> getColumnClass(int c) {
            System.out.println("AbstractTable: getColumnClass");
            if (c > this.getTypeArray().length - 1)
                return null;
            else
                return this.getTypeArray()[c];
        }
        
        public void addEmptyRow(){
            ArrayList<Object> emptyRow = new ArrayList<Object>();
            for (int i = 0 ; i < this.getTypeArray().length; i++){
                emptyRow.add(EMPTY_ROW);
            }
            this.datas.add(emptyRow);
        }
        public void addRow(ArrayList<Object> row){
            Object[] types = this.getTypeArray();
            if (types.length != row.size())
                return;
            for (int i = 0 ; i < row.size() ; i++){
                Class<? extends Object> 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();
        JTable tab = new JTable(model);
        TableRowSorter<ConcreteTable> sorter = new TableRowSorter<ConcreteTable>(model);
        
        

        try {
            
            sorter.setComparator(0, new EmptyRowComparator<Integer>(sorter,0));
            sorter.setComparator(1, new EmptyRowComparator<String>(sorter,1));
        
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        tab.setRowSorter(sorter);
        JScrollPane table = new JScrollPane(tab);
        
        this.getContentPane().add(table);
        this.setSize(600, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
            new TableExample();
    }

}

如果你尝试改变

Class[] types = {Integer.class, String.class}; 

with :

Class[] types = {Double.class, String.class};

你可以看到问题所在。


how did Walter Laan在他的帖子中说

Never give up! Never surrender!

编辑:我无法抗拒,但由于我的英语很差,我不敢评论为什么、在哪里以及如何可能,也不敢正确工作,为了确认我为 TableColumnRendering 添加了 Rob 的两个(一点点)修改类...,

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<COLUMN_TYPE extends Comparable<COLUMN_TYPE>> implements Comparator<Object> {//extends RuleBasedCollator{

        private TableRowSorter<? extends AbstractTableMod> sorter;
        private int column;

        public EmptyRowComparator(TableRowSorter<? extends AbstractTableMod> 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>) (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<ArrayList<Object>>();
            for (int i = 0; i < this.minimumDisplayedRow; i++) {
                this.addEmptyRow();
            }
            Random rnd = new Random();
            for (int i = 0; i < 7; i++) {
                ArrayList<Object> row = new ArrayList<Object>();
                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<Integer> getKeysColumnIndex() {
            ArrayList<Integer> keys = new ArrayList<Integer>();
            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<ArrayList<Object>> datas;
        protected int rowNumber = 0;

        protected abstract Class<?>[] getTypeArray();

        protected abstract ArrayList<Integer> 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<Object> 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<? extends Object> 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<Object> newRow = new ArrayList<Object>();
                ArrayList<Integer> 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<? extends Object> getColumnClass(int c) {
            if (c > this.getTypeArray().length - 1) {
                return null;
            } else {
                return this.getTypeArray()[c];
            }
        }

        public void addEmptyRow() {
            ArrayList<Object> emptyRow = new ArrayList<Object>();
            for (int i = 0; i < this.getTypeArray().length; i++) {
                emptyRow.add(EMPTY_ROW);
            }
            this.datas.add(emptyRow);
        }

        public void addRow(ArrayList<Object> row) {
            Object[] types = this.getTypeArray();
            if (types.length != row.size()) {
                return;
            }
            for (int i = 0; i < row.size(); i++) {
                Class<? extends Object> 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<ConcreteTable> sorter = new TableRowSorter<ConcreteTable>(model);
        try {
            sorter.setComparator(0, new EmptyRowComparator<Integer>(sorter, 0));
            sorter.setComparator(1, new EmptyRowComparator<String>(sorter, 1));
            sorter.setComparator(2, new EmptyRowComparator<String>(sorter, 2));
            sorter.setComparator(3, new EmptyRowComparator<String>(sorter, 3));
            sorter.setComparator(4, new EmptyRowComparator<String>(sorter, 4));
            sorter.setComparator(5, new EmptyRowComparator<String>(sorter, 5));
            sorter.setComparator(6, new EmptyRowComparator<String>(sorter, 6));
            sorter.setComparator(7, new EmptyRowComparator<String>(sorter, 7));
            sorter.setComparator(8, new EmptyRowComparator<String>(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);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JTable 中的格式化字段问题 - Integer 和 Double 之间的差异 的相关文章

  • MP3:一种以毫秒为单位获取任何给定字节位置的位置的方法?

    我创建了一个 servlet 它返回从客户端请求的任何给定字节位置开始的流 来自 MP3 文件 这允许客户端在任何给定字节位置立即开始播放 而无需进行任何本地查找 现在 我有一个滑块可以直观地显示进度 我正在使用当前字节位置来更新滑块 但是
  • 将链接对象转换为流或集合

    我想迭代堆栈跟踪 堆栈跟踪由可抛出对象组成 其 getCause 返回下一个可抛出对象 最后一次调用 getCause 返回 null 示例 a gt b gt null 我尝试使用 Stream iterable 这会导致 NullPoi
  • Java 创建浮雕(红/蓝图像)

    我正在编写一个 Java 游戏引擎 http victoryengine org http victoryengine org 并且我一直在尝试生成具有深度的 3D 图像 您可以使用那些红色 蓝色眼镜看到 我正在使用 Java2D 进行图形
  • JTree 节点不会被直观地选择

    不知何故 我无法为我的 JTree 节点启用 选择突出显示 我正在我的项目中使用自定义单元格渲染器 这很可能导致此问题 这是完整的渲染器类代码 protected class ProfessionTreeCellRenderer exten
  • Java 泛型/类型调度问题

    考虑以下程序 import java util List import java util ArrayList public class TypeTest public static class TypeTestA extends Type
  • Google Inbox 类似 RecyclerView 项目打开动画

    目前 我正在尝试实现 Google Inbox 例如RecyclerView行为 我对电子邮件打开动画很好奇 我的问题是 该怎么做 我的意思是 他们使用了哪种方法 他们用过吗ItemAnimator dispatchChangeStarti
  • 如何将 Spotlight for Help 插入本地化的 macOS 应用程序?

    我正在 macOS 上使用 Swing GUI 框架实现 Java 应用程序 当使用system外观和感觉以及screen菜单栏 Swing 自动插入一个搜索栏 called 聚光灯寻求帮助 https developer apple co
  • 为什么我在 Mac 上看到“java.lang.reflect.InaccessibleObjectException: Unable to make private java.nio.DirectByteBuffer(long,int)accessibl

    我已经在工作中愉快地构建代码好几天了 但突然我的一个项目 不是全部 失败并出现此错误消息 看看下面的答案吧 我是如何修复它的 起初我用谷歌搜索 看到很多有这个问题的人正在使用 Java 16 但我认为 错误 我正在使用 Java 11 因为
  • 使用 Guava 联合两个 ImmutableEnumSets

    我想联合两个ImmutableEnumSets来自番石榴 这是我的尝试 public final class OurColors public enum Colors RED GREEN BLUE YELLOW PINK BLACK pub
  • Java:VM 如何在 32 位处理器上处理 64 位“long”

    JVM 如何在 32 位处理器上处理 64 位的原始 long 在多核 32 位机器上可以并行利用多个核心吗 64 位操作在 32 位机器上慢了多少 它可能使用多个核心来运行不同的线程 但不会并行使用它们进行 64 位计算 64 位长基本上
  • 参数动态时如何构建 JPQL 查询?

    我想知道是否有一个好的解决方案来构建基于过滤器的 JPQL 查询 我的查询太 富有表现力 我无法使用 Criteria 就像是 query Select from Ent if parameter null query WHERE fiel
  • 为什么 ConcurrentHashMap::putIfAbsent 比 ConcurrentHashMap::computeIfAbsent 更快?

    使用 ConcurrentHashMap 我发现computeIfAbsent 比putIfAbsent 慢两倍 这是简单的测试 import java util ArrayList import java util List import
  • 从 Java 日历迁移到 Joda 日期时间

    以前 当我第一次设计股票应用相关软件时 我决定使用java util Date表示股票的日期 时间信息 后来我体会到了大部分方法java util Date已弃用 因此 很快 我重构了所有代码以利用java util Calendar 然而
  • 让JScrollPane控制多个组件

    对于我的应用程序 我正在设计一个脚本编辑器 目前我有一个JPanel其中包含另一个JPanel保存行号 位于左侧 以及JTextArea用于允许用户输入代码 位于右侧 目前 我已经实施了JScrollPane on the JTextAre
  • 在 AKKA 中,对主管调用 shutdown 是否会停止其监督的所有参与者?

    假设我有一位主管连接了 2 位演员 当我的应用程序关闭时 我想优雅地关闭这些参与者 调用supervisor shutdown 是否会停止所有参与者 还是我仍然需要手动停止我的参与者 gracias 阻止主管 https github co
  • OpenJDK 版本控制

    上下文 我想确保我们系统上安装的 Java 不受 CVE 2022 21449 的影响 java version 给出 openjdk version 11 0 7 2020 04 14 LTS OpenJDK Runtime Enviro
  • 如何为 Jackson 编写一个包罗万象的(反)序列化器

    当您提前知道类型时 编写自定义序列化器非常容易 例如 MyType一个人可以写一个MyTypeSerializer extends StdSerializer
  • 使用 Java 从 S3 上的文件在 S3 上创建 zip 文件

    我在 S3 上有很多文件 需要对其进行压缩 然后通过 S3 提供压缩文件 目前 我将它们从流压缩到本地文件 然后再次上传该文件 这会占用大量磁盘空间 因为每个文件大约有 3 10MB 而且我必须压缩多达 100 000 个文件 所以一个 z
  • java中如何找到class文件的包

    我正在编写一个使用 class 文件的 java 程序 我希望能够读取文件系统上的 class 文件 使用 InputStream 并确定它所在的包 该 class 文件可能不在一个好的包目录结构中 它可能位于某个随机位置 我怎样才能做到这
  • 使用 eclipse IDE 配置 angularjs

    我想开始使用 AngularJs 和 Java Spring 进行开发 我使用 Eclipse 作为 IDE 我想配置我的 Eclipse 以使这些框架无缝工作 我知道我可能要求太多 但相信我 我已经做了很多研究 你们是我最后的选择 任何帮

随机推荐

  • 您必须至少选择一个列出的平台才能显示

    我正在创建一个简单的应用程序 当我尝试保存更改时收到此错误 您必须至少选择一个要显示的列出平台 请参阅此处的屏幕截图 http panstickers com au webimages fb error gif http pansticke
  • Ace编辑器使用javascript触发事件

    有没有类似的东西 editor getSession trigger change 我想要这个的原因是因为编辑器进出新的 所以当它返回视图时我需要它做正常的 更改 事情 但我不想等待用户输入 目前我有 editor getSession o
  • 如何解决curl php中的HTTP/1.1 400 Bad Request

    我必须打一个 aspx来自 php 代码的页面 url 我试图使用curl 来访问 但出现以下错误并且 url 中没有空格 HTTP 1 1 400 Bad Request Content Type text html charset us
  • PHP 通过 FTP 下载整个文件夹(递归)

    我目前有一个非常大的网站 大小约为 5GB 包含 60 000 个文件 当前主机并没有做太多事情来帮助我将网站转移到新主机 我的想法是在新主机上制作一个简单的脚本 通过 FTP 传输到旧主机并下载整个 public html 文件夹 递归地
  • 在进行字符识别之前使用 OpenCV 进行图像预处理(超正方体)

    我正在尝试开发简单的 PC 应用程序用于车牌识别 Java OpenCV Tess4j 图像不是很好 进一步它们会很好 我想对超立方体图像进行预处理 但我被困在车牌检测 矩形检测 上 我的步骤 1 源图像 Mat img new Mat i
  • 在 Matlab、VB6 和 VB.NET 程序之间发送消息的最简单方法

    我们正在将一套数据采集和分析例程从 VB6 程序升级为 VB NET VB6 和 Matlab 程序的混合体 我们希望保持系统模块化 单独的 EXE 以便我们可以轻松创建专门的独立分析程序 而无需不断升级大型应用程序 当所有程序都是用 VB
  • 何时在 Springs @Configuration 中将 proxyBeanMethods 设置为 false?

    当查看 spring 自动配置时源代码 https github com spring projects spring boot tree master spring boot project spring boot autoconfigu
  • 如何用Spring进行只读和读写的数据库路由

    我正在研究 Spring 中的事务路由 但我的应用程序存在运行时问题 我有两个 MySQL 数据库 一个用于读取 一个用于读 写 但是我的路由配置不起作用 当我应用只读配置时 我没有成功 这是我的配置 pom xml
  • Akka、SQS 和 Camel 的消费者投票率

    我正在做的一个项目需要从SQS读取消息 我决定使用Akka来分布式处理这些消息 由于 Camel 支持 SQS 并且在 Consumer 类中内置了 Akka 中使用的功能 因此我认为最好以这种方式实现端点并读取消息 尽管我还没有看到很多人
  • 如何在中等规模的 Rails 应用程序中组织控制器?

    我正在开发一个具有相当多相关模型的应用程序 并且想听听一些关于如何最好地组织控制器的意见 以下是我一直在考虑的一些选择 1 为控制器命名空间 例如 有一个controllers admin 目录和一个controllers public 目
  • Apache mod_rewrite:在 Windows 计算机上使用 PHP 脚本的 RewriteMap 指令

    这已经让我发疯了 我似乎无法让 RewriteMap 指令适用于 Windows 上的 php 脚本 这是我的 httpd conf 文件中的相关片段
  • 在 AspNet WebApi 帮助页面中生成模型描述

    我如何生成一个描述对于 Asp Net Web Api 帮助页面中的我的模型 Example 正如您从示例中看到的 我已经可以生成Name Type and Additional Information 但我如何生成Description
  • 部署后配置文件中缺少

    更新 我在下面有一个问题 但实际上我的问题可以通过提出一个稍微不同的问题来解决 为什么在某些机器上我的应用程序会抛出错误 Configuration system failed to initialize System Configurat
  • 由于 QCoreApplication 事件循环,QThread 永远不会退出

    Problem 所以我有一个 CommandRetriever 类来保存一些命令 并且should在不同的线程上执行这些命令 class CommandRetriever public CommandRetriever CommandRet
  • Azure DevOps API 版本定义

    尝试从其他项目复制发布模板时出现以下错误 VS402982 未为 PROJECT ENV 阶段设置保留策略 发布管道级别的保留策略已弃用 id 8 name PROJECT ENV rank 1 owner displayName Zoe
  • 根据一列删除重复项并保留最后一个条目

    我正在尝试根据一列删除重复项并保留最后一个条目 现在我的公式保持第一个值 我正在使用这篇文章中找到的公式 选择具有不同列值的所有行 Google 查询语言 https stackoverflow com questions 30318460
  • 关闭 MAMP 中的缓存

    尝试关闭 MAMP 中的缓存进行开发 在进行小更改后等待缓存过期会降低我的工作效率 当我更改为 PHP 5 5 3 时出现问题 更改回来并不能解决问题 经过研究 我采取了以下步骤来 未成功 禁用缓存 注释掉 php ini 中的 OPcac
  • 引用的项目x不存在

    大家好 我将一个项目的解决方案从vs2008升级到vs2010 但现在我有一个奇怪的问题 我在多个解决方案中引用了一个项目 3个解决方案 在其中两个解决方案中 引用出现错误 我可以添加引用 项目引用 但是当我构建时 我收到警告 引用的项目
  • iOS Siri 意图扩展“我没有看到适用于该功能的应用程序。您需要下载一个。”

    我正在编写一个 Swift 框架 其中包含 Siri 意图定义文件和代码 可从主应用程序 Today 扩展和 Siri 意图扩展中使用 我正在使用 Cocoapods 来分发框架 它位于私人存储库中 因此我无法共享框架本身 这非常适合从应用
  • JTable 中的格式化字段问题 - Integer 和 Double 之间的差异

    更新 已确认为错误当 columnClass 为 Double 时 JTable 无法将给定对象格式化为 Number 错误 ID 7051636 https bugs java com bugdatabase view bug bug i