gpt4 book ai didi

java - TableModel 中的 setValueAt 总是获取一个字符串

转载 作者:行者123 更新时间:2023-12-01 23:53:34 26 4
gpt4 key购买 nike

我有一个 JTable,其中一列包含不同的对象类型。每种类型都有自己的渲染器和编辑器(getDefaultRenderer(Number.class)、我自己的日期渲染器/编辑器等)。

但是,我的表模型(我重写 DefaultTableModel)中的方法 setValueAt(Object value, int row, int col) 始终将 String 作为 value。因此,尽管有不同的编辑器,我无法在不解析字符串的情况下更新行,这不是一个好主意,因为我的表将来应该可以轻松处理其他对象类型。

getValueAt(int row, int col) 不会将对象转换为字符串。我查了一下。这种行为的原因是什么?

编辑:下面的代码。只有 boolean 单元格编辑器似乎可以正常工作。

import java.awt.Component;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

public class Tabela {

public static void main(String[] args){
JFrame fr = new JFrame("tabela");
fr.setSize(600, 400);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// custom renderer and editor for Date
final DateCellEditor dateEditor = new DateCellEditor();
final DateCellRenderer dateRenderer = new DateCellRenderer();

final TableModel model = new TableModel();
JTable table = new JTable(model){
public TableCellEditor getCellEditor(int row, int col){
if (model.getValueAt(row, col) instanceof Boolean)
return getDefaultEditor(Boolean.class);
else if (model.getValueAt(row, col) instanceof Number)
return getDefaultEditor(model.getValueAt(row, col).getClass());
else if (model.getValueAt(row, col) instanceof Date)
return dateEditor;
else return getDefaultEditor(Object.class);
}

public TableCellRenderer getCellRenderer(int row, int col){
if (model.getValueAt(row, col) instanceof Boolean)
return getDefaultRenderer(Boolean.class);
else if (model.getValueAt(row, col) instanceof Number)
return getDefaultRenderer(model.getValueAt(row, col).getClass());
else if (model.getValueAt(row, col) instanceof Date)
return dateRenderer;
else
return getDefaultRenderer(Object.class);
}
};
JScrollPane sc = new JScrollPane(table);
fr.getContentPane().add(sc);
fr.setVisible(true);
}

public static class TableModel extends DefaultTableModel{
// data in first column
private ArrayList<String> names = new ArrayList<String>();
// data in second column - can by any object
private ArrayList<Object> values = new ArrayList<Object>();

public TableModel(){
// insert example data
names.add("string value");
values.add("some string");
names.add("number value");
values.add(new Integer(12345));
names.add("Boolean value");
values.add(new Boolean(false));
names.add("Double value");
values.add(new Double(10.5));
names.add("Date object");
values.add(new Date(System.currentTimeMillis()));
}

public void setValueAt(Object value, int row, int col){
values.set(row, value);
fireTableCellUpdated(row, col);
}

public Object getValueAt(int row, int col){
if (col==0)
return names.get(row) + " ["+values.get(row).getClass().getSimpleName()+"]";
else return values.get(row);
}

public int getRowCount(){
if (values==null) return 0;
else return values.size();
}

public int getColumnCount(){
return 2;
}

public boolean isCellEditable(int row, int col){
return col==1; // only column 2 is editable
}

public Class<?> getColumnClass(int col){
switch(col){
case 0:
return String.class;
default:
return Object.class;
}
}

}

// My own renderer and editor for Date type
protected static class DateCellRenderer extends DefaultTableCellRenderer{
private static DateFormat format = new SimpleDateFormat("dd-MM-y HH:mm:ss");

public static void setDateFormat(String f){
format = new SimpleDateFormat(f);
}

public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
if (value instanceof Date){
value = format.format(value);
}
else if(value instanceof Calendar)
{
Calendar dateValue = (Calendar) value;
value = format.format(dateValue.getTime());
}
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (c instanceof JComponent){
JComponent jc = (JComponent) c;
jc.setToolTipText("dd-MM-y HH:mm:ss");
}
return c;
}
}

protected static class DateCellEditor extends DefaultCellEditor{
private static DateFormat format = new SimpleDateFormat("dd-MM-y HH:mm:ss");
private JFormattedTextField textField = new JFormattedTextField(format);

public DateCellEditor(){
super(new JFormattedTextField(format));
}

public void setDateFormat(String f){
format = new SimpleDateFormat(f);
textField = new JFormattedTextField(format);
}

public Component getTableCellEditorComponent (JTable table, Object value, boolean isSelected, int row, int column)
{ System.out.println("editor: "+value.getClass());
if (value instanceof Date){
value = format.format(value);
}
else if(value instanceof Calendar)
{
Calendar dateValue = (Calendar) value;
value = format.format(dateValue.getTime());
}
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
}
}

最佳答案

从您的代码示例中(立即)有许多值得关注的事情。

首先,不需要覆盖 getCellEditorgetCellRenderer JTable的方法.

我对你这样做的方式遇到的最大问题是,如果模型的值是null怎么办? ?

您可以修改单元格编辑器并呈现给定的 Class通过使用setDefaultEditor(Class, TableCellEditor)setDefaultRenderer(Class, TableCellRenderer)方法代替。

从您的表模型中,您应该返回所有适当的 Class所需列的类型(来自 getColumnClass )。这里的假设是给定列具有相同类型 Class值。

但是,问题的原因在于编辑器。

如果示例编辑器可以作为引用,那么您将从 DefaultCellEditor 进行扩展。 ,它只使用 JTextField因为它是编辑器。这意味着getCellEditorValue将返回String ,这就是你的 setValueAt 的原因方法传递一个 String值。

有多种选择。

  1. 你可以设计一个更好的 TableCellEditor使用了更合适的编辑器(例如 JSpinnerJCheckBox )
  2. 您可以覆盖 getCellEditorValue转换String值从默认编辑器改为更合适的 Object类型。

我更喜欢选项 1,因为它代表了适合的表单和编辑器中的基础数据,并且可以避免处理错误解析带来的麻烦。

我会仔细看看 How to use tables并密切关注自定义编辑器的部分

关于java - TableModel 中的 setValueAt 总是获取一个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15985474/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com