2012-04-07 59 views
1

我还是相当新的Java和有关JTable(更具体地说,JXTable)和列数据类型的排序行的问题...让我详细说明...如何将JTable列设置为字符串并按Double排序?

我有一个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(降序)

我想什么做的是去除 '$' 在对列进行分类和排序的时间为双倍。我怎么做到这一点?

编辑:

非常感谢您吉日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格式化我想要的价格。

希望这有助于别人出未来。

+0

不要让列类的字符串,而是一个数字类型。而是让单元格渲染器使用显示“$”符号的NumberFormat/currency实例。 – 2012-04-07 13:03:23

回答

2

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); 
    } 

} 
 
+0

+1,但.. *“请原谅我使用匿名内部类。”*咦?那是一些设计'不'吗?作为编写大量SSCCE的人,我经常做出糟糕的“设计”决策,仅仅是为了展示一个独立代码中的一点。在这种情况下,我绝不会为设计提供道歉! – 2012-04-07 13:58:29

+1

@AndrewThompson:他们是一个快速[续]完全可以接受的(http://en.wikipedia.org/wiki/Continuation_passing_style#Continuations_as_objects)。它们不能很好地扩展; +1到Jiri以识别此边缘情况下的快捷方式。我有时在[sscce](http://sscce.org/)中使用_static嵌套class_来轻松重构因子。 – trashgod 2012-04-08 23:22:01

+0

感谢您的意见,伙计们。当他们比说三行更长时,我感觉不太对劲。我只在SSCCE中使用它们,但我知道它们可能很难读取新手。 – 2012-04-09 11:32:19