【问题标题】:How to set a JTable column as String and sort as Double?如何将 JTable 列设置为 String 并排序为 Double?
【发布时间】:2013-06-26 17:32:27
【问题描述】:

我对 Java 还很陌生,并且对 JTable(更具体地说是 JXTable)和按列类对具有混合数据类型的行排序有疑问...让我详细说明...

我有一个保存产品列表数据的 JXTable。此表有一个价格列,我已将其设置为 String.class,以便我可以显示带有“$”前缀的价格。

我遇到的问题是,当行按价格排序时,它们没有按双精度排序,而是按字符串排序,因此这些值:

89.85、179.70、299.40、478.80

排序为:

179.70、299.40、478.80、89.85(上升) 和 89.85、478.80、299.40、179.70(降序)

我想做的是在排序时删除“$”并将列排序为双精度。我将如何做到这一点?

编辑:

非常感谢 Jiri Patera 的回复。这对帮助我理解 tablecellrenderer 负责在这些类型的情况下操作值很有帮助。下面是完成的摘录,终于完成了我想要的。

public Component getTableCellRendererComponent(JTable pTable, Object pValue, boolean pIsSelected, boolean pHasFocus, int pRow, int pColumn) {

        // Use the wrapped renderer
        Component renderedComponent = mWrappedRenderer.getTableCellRendererComponent(pTable, pValue, pIsSelected, pHasFocus, pRow, pColumn);
        Component renderedComponentHeader = pTable.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(pTable, pValue, pIsSelected, pHasFocus, pRow, pColumn);

        if (pColumn == 4 && pValue instanceof Double){
            DecimalFormat df = new DecimalFormat("$###,##0.00");
            Double d = (Double) pValue;
            String s = df.format(d);
            renderedComponent = mWrappedRenderer.getTableCellRendererComponent(pTable, s, pIsSelected, pHasFocus, pRow, pColumn);
        }

        // Set the alignment
        Integer alignment = mSpecialColumnAlignmentMap.get(pColumn);
        Integer width = mSpecialColumnWidthMap.get(pColumn);
        if (alignment != null) {
            ((JLabel) renderedComponent).setHorizontalAlignment(alignment);
            ((JLabel) renderedComponentHeader).setHorizontalAlignment(alignment);
        } else {
            ((JLabel) renderedComponent).setHorizontalAlignment(mDefaultAlignment);
            ((JLabel) renderedComponentHeader).setHorizontalAlignment(mDefaultAlignment);
        }

        if (width != null){
            pTable.getColumnModel().getColumn(pColumn).setPreferredWidth(width);
            pTable.getColumnModel().getColumn(pColumn).setMaxWidth(width);
        }

        return renderedComponent;
    }

如您所见,我已经有一个自定义的 tablecellrenderer。我使用 DecimalFormat 来格式化我想要的价格。

希望这对将来的其他人有所帮助。

【问题讨论】:

  • 不要将列类设为字符串,而应设为数字类型。而是让单元格渲染器使用显示“$”符号的 NumberFormat / 货币实例。

标签: java swing jtable jxtable


【解决方案1】:

HFOE 是对的。但是,这对于 Java 新手来说可能很棘手。请原谅我使用匿名内部类。请参阅以下示例以获取一些提示...

package test; import java.awt.Component; import java.util.ArrayList; import java.util.List; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; public class TableTest { public static void main(String[] args) { TableTest tt = new TableTest(); tt.start(); } private void start() { JTable t = new JTable(new AbstractTableModel() { private static final long serialVersionUID = 1L; private List<Double> values = new ArrayList<Double>(); { values.add(Double.valueOf(179.70d)); values.add(Double.valueOf(299.40d)); values.add(Double.valueOf(478.80d)); values.add(Double.valueOf(89.85d)); } @Override public String getColumnName(int column) { return "Double"; } @Override public Class<?> getColumnClass(int column) { return Double.class; } @Override public int getRowCount() { return values.size(); } @Override public int getColumnCount() { return 1; } @Override public Object getValueAt(int rowIndex, int columnIndex) { return values.get(rowIndex); } }); t.setDefaultRenderer(Double.class, new DefaultTableCellRenderer() { private static final long serialVersionUID = 1L; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Double d = (Double)value; String s = "$" + String.valueOf(d.doubleValue()); Component c = super.getTableCellRendererComponent(table, s, isSelected, hasFocus, row, column); return c; } }); t.setAutoCreateRowSorter(true); JFrame f = new JFrame(); f.setSize(320, 200); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JScrollPane sp = new JScrollPane(t); f.getContentPane().add(sp); f.setVisible(true); } }

【讨论】:

  • +1,但是.. “请原谅我使用匿名内部类。” 嗯?那是一些设计“禁止”吗?作为编写大量 SSCCE 的人,我经常做出糟糕的“设计”决策,只是为了在自包含代码中展示一个观点。在那种情况下,我绝不会考虑为设计道歉!
  • @AndrewThompson:对于快速的continuation,它们完全可以接受。他们只是不能很好地扩展。为 Jiri +1 识别此边缘情况下的快捷方式。我有时会在 sscce 中使用 静态嵌套类 以便于重构。
  • 谢谢大家的意见。当它们长于三行时,我只是感觉不对。我只在 SSCCE 中使用它们,尽管我知道它们对于新手来说可能很难阅读。
猜你喜欢
  • 1970-01-01
  • 2021-02-21
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 2013-12-07
  • 2017-12-29
  • 2013-11-10
  • 2019-09-19
相关资源
最近更新 更多