Как установить столбец JTable как String и сортировать как Double?
Я все еще довольно новичок в Java и у меня есть вопрос относительно JTable (точнее, JXTable) и сортировки строк по классу столбцов со смешанным типом данных... Позвольте мне остановиться подробнее...
У меня есть JXTable, в котором хранятся данные для списка товаров. В этой таблице есть столбец для цены, который я установил только для String.class, так что я могу отображать цену с добавленным "$".
У меня проблема в том, что когда строки сортируются по цене, они не сортируются как Double, а скорее сортируются как строки, поэтому эти значения:
89,85, 179,70, 299,40, 478,80
сортируются как:
179,70, 299,40, 478,80, 89,85 (по возрастанию) и 89,85, 478,80, 299,40, 179,70 (по убыванию)
То, что я хотел бы сделать, это удалить '$' во время сортировки и сортировать столбец как Doubles. Как бы я это сделал?
РЕДАКТИРОВАТЬ:
Большое спасибо Иржи Патера за ваш ответ. Это помогло мне понять, что 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 для форматирования цены, как я хочу.
Надеюсь, что это поможет кому-то еще в будущем.
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);
}
}