【问题标题】:Render the double value in the cell渲染单元格中的双精度值
【发布时间】:2014-04-18 08:17:43
【问题描述】:

我使用自定义表格模型 (MyTableModel.java) 创建了一个 JTable,并使用了一些 CellRenderer 类来查看单元格的效果。我使用CustomTableCellRenderer 类将当前单元格更改为绿色背景。它工作得很好。同时,我创建了一个RenderPrice 类来以十进制类型显示单元格,如果我编辑未更新的单元格,它会在我第一次执行时采用十进制值,它将显示$ 符号作为前缀。我想解决这个问题。请尽快给出一些解决方案。谢谢

RenderPrice 类代码

class RenderPrice extends DefaultTableCellRenderer {
    Object result; 
    RenderPrice() { 
        setHorizontalAlignment(SwingConstants.RIGHT);  
    }

    public void setValue(Object aValue) {
        result = aValue;
        if ((aValue != null) && (aValue instanceof Number)) {
            Number numberValue = (Number)aValue;
            NumberFormat formatter = NumberFormat.getCurrencyInstance();
            result = formatter.format(numberValue.doubleValue());
        } 
        super.setValue(result);
    }   
} 

我的 Tableclass (Accept.java) 的前面代码

gradeColumn = jTable1.getColumnModel().getColumn(2);
gradeColumn.setCellRenderer(new RenderPrice());

gradeColumn = jTable1.getColumnModel().getColumn(0);
gradeColumn.setCellEditor(new IntegerEditor(1,100));

gradeColumn = jTable1.getColumnModel().getColumn(0);
gradeColumn.setCellRenderer(new CustomTableCellRenderer());

gradeColumn = jTable1.getColumnModel().getColumn(1);
gradeColumn.setCellEditor(new ComboBoxCellEditor(comboBox));

【问题讨论】:

  • 一切都在你的代码的大部分/其余部分,为了更好的帮助,尽快发布一个 SSCCE 或 MCVE 或 MCTRE,简短,可运行,可编译,只是 JFrame 中的 JTable,硬编码值存储在本地变量中JTable/XxxTableModel
  • 看不懂,请详细说明

标签: java swing jtable tablecellrenderer tablecelleditor


【解决方案1】:

您应该在这样的渲染器中存储任何状态。您可能正在寻找类似的东西

class RenderPrice extends DefaultTableCellRenderer
{
    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected,
        boolean hasFocus, int row, int column)
    {
        super.getTableCellRendererComponent(
            table, value, isSelected, hasFocus, row, column);

        if ((value != null) && (value instanceof Number))
        {
            Number numberValue = (Number)value;
            NumberFormat formatter = NumberFormat.getCurrencyInstance();
            String valueString = formatter.format(numberValue.doubleValue());
            setText(valueString);
        }

        return this;
    }
}

编辑:响应 cmets 和示例

import java.text.NumberFormat;
import java.text.ParseException;

import javax.swing.DefaultCellEditor;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.text.NumberFormatter;

public class CurrencyCellEditorTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JTable table = new JTable(
            new Object[][]{
                { 1.2, 3.4 },
                { 5.6, 7.8 }
            },
            new Object[] {
                "A", "B"
            });


        TableColumn column0 = table.getColumnModel().getColumn(0);
        column0.setCellEditor(new PriceEditor());
        column0.setCellRenderer(new PriceRenderer());

        TableColumn column1 = table.getColumnModel().getColumn(1);
        column1.setCellEditor(new PriceEditor());
        column1.setCellRenderer(new PriceRenderer());

        f.getContentPane().add(table);
        f.setSize(400,400);
        f.setLocationRelativeTo(null);
        f.setVisible(true);

    }
}

class PriceRenderer extends DefaultTableCellRenderer
{
    PriceRenderer()
    {
        setHorizontalAlignment(SwingConstants.RIGHT);
    }

    @Override
    public void setValue(Object aValue)
    {
        Object result = aValue;
        if ((aValue != null) && (aValue instanceof Number))
        {
            Number numberValue = (Number) aValue;
            NumberFormat formatter = NumberFormat.getCurrencyInstance();
            result = formatter.format(numberValue.doubleValue());
        }
        super.setValue(result);
    }
}

class PriceEditor extends DefaultCellEditor
{
    public PriceEditor()
    {
        super(createComponent());
        delegate = new EditorDelegate()
        {
            @Override
            public void setValue(Object value)
            {
                Number numberValue = 0.0;
                if (value != null && value instanceof Number)
                {
                    numberValue = (Number)value;
                }
                getFormattedTextField().setValue(numberValue);
            }

            @Override
            public Object getCellEditorValue()
            {
                try
                {
                    NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
                    String text = getFormattedTextField().getText();
                    Number number = numberFormat.parse(text);
                    return number;
                }
                catch (ParseException e)
                {
                    e.printStackTrace();
                    return new Double(0.0);
                }
            }
        };
    }

    private static JTextField createComponent()
    {
        NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
        NumberFormatter numberFormatter = new NumberFormatter(numberFormat);
        JFormattedTextField formattedTextField = new JFormattedTextField(numberFormatter);
        formattedTextField.setHorizontalAlignment(SwingConstants.RIGHT);
        return formattedTextField;
    }

    private JFormattedTextField getFormattedTextField()
    {
        return (JFormattedTextField)getComponent();
    }

}

【讨论】:

  • 第一次执行时,它会以双精度形式显示,但如果我单击单元格,$ 符号会隐藏并且编辑的值不会更改为双精度。我不能在这里覆盖 setValue 方法吗?
  • @user3391137 在这种情况下,您还必须设置适当的编辑器。参见informit.com/articles/article.aspx?p=333472&seqNum=3,例如
  • You should not use (or override) - 当然可以。该方法用于设置应呈现的值。它不会改变模型中的数据。
  • @camickr 好吧,使用 可能没问题,但是覆盖它(并以任何原因存储在那里传递的值)至少是可疑的。除了不是正确的方法之外,几乎无法确定有人调用“setValue”还是“setText”——如果他调用后者,那么“setValue”的覆盖版本将被绕过......
  • setValue(...) 方法是用来设置要渲染的文本的方法。这实际上是 Using Custom Renderers 上的 Swing 教程中使用的方法。重写 setValue() 方法时,无需重写 getCellRendererComponent() 方法。
【解决方案2】:

查看Table Format Renderers,了解创建自定义渲染器的简单方法。您只需指定一个特定的格式化程序。

在这种情况下,该类有一个方便的货币格式化方法。

TableColumnModel m = table.getColumnModel();
m.getColumn(???).setCellRenderer(NumberRenderer.getCurrencyRenderer());

【讨论】:

    猜你喜欢
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    相关资源
    最近更新 更多