Java 在JTable单元格中编辑时间

Java 在JTable单元格中编辑时间,java,swing,time,calendar,jtable,Java,Swing,Time,Calendar,Jtable,现在,我有一个日历,我使用SimpleDateFormat(“hh:mm”)将日历时间转换为字符串,并将其放入JTable单元格中。该单元格是可编辑的,但如何检查编辑后的值是否正确格式为hh:mm,如果不正确,如何将其更改回原来的时间 或者是他们将时间放入单元格并进行编辑的另一种方式?您可以使用以下简单的正则表达式进行检查: (([01]\d)|(2[0-3])):([0-5]\d) 您需要编写自己的自定义数据模型、渲染和单元编辑器。 看看setModel()、setDefaultRender

现在,我有一个日历,我使用
SimpleDateFormat(“hh:mm”)
将日历时间转换为字符串,并将其放入JTable单元格中。该单元格是可编辑的,但如何检查编辑后的值是否正确格式为
hh:mm
,如果不正确,如何将其更改回原来的时间


或者是他们将时间放入单元格并进行编辑的另一种方式?

您可以使用以下简单的正则表达式进行检查:

(([01]\d)|(2[0-3])):([0-5]\d)

您需要编写自己的自定义数据模型、渲染和单元编辑器。 看看setModel()、setDefaultRenderer()和setDefaultEditor()。 这里有一个很棒的教程

我给你们写了一个简单的例子:

package test;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.AbstractCellEditor;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.JTable;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.event.CaretListener;
import javax.swing.event.CaretEvent;
import javax.swing.JScrollPane;

public class Poligon extends JFrame {

    private JPanel contentPane;
    private JTable table;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Poligon frame = new Poligon();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Poligon() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JScrollPane scrollPane = new JScrollPane();
        contentPane.add(scrollPane, BorderLayout.CENTER);

        table = new JTable();
        table.setModel(new DataModel("12:34:00"));
        table.setDefaultRenderer(Date.class, new DateRenderer());
        table.setDefaultEditor(Date.class, new DateEditor());
        table.setRowHeight(35);

        scrollPane.setViewportView(table);


    }

}

class DateRenderer implements TableCellRenderer
{

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {

        JPanel c = new JPanel();

        if (value instanceof Date)
        {
            SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
            c.add(new JLabel(dateFormat.format(value)));
        }

        return c;
    }

}

class DateEditor extends AbstractCellEditor implements TableCellEditor
{

    private Object cellEditorValue;

    @Override
    public Object getCellEditorValue() {    
        return this.cellEditorValue;
    }

    public void setCellEditorValue(Object value)
    {
        this.cellEditorValue = value;
    }

    @Override
    public Component getTableCellEditorComponent(JTable table,  Object value, boolean isSelected, int row, int col) 
    {   

        JPanel c = new JPanel();

        if (value instanceof Date)
        {
            final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");

            final JTextField textField = new JTextField();

            textField.setText(dateFormat.format(value));

            textField.addCaretListener(new CaretListenerForDate(this, textField));

            c.add(textField);       
        }

        return c;
    }

}

class CaretListenerForDate implements CaretListener
{       
    private JTextField textField;
    private DateEditor dateEditor;

    public CaretListenerForDate(DateEditor dateEditor, JTextField textField)
    {
        this.textField = textField;
        this.dateEditor = dateEditor;
    }

    public void caretUpdate(CaretEvent e) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm"); 
        try {
            dateEditor.setCellEditorValue(dateFormat.parse(textField.getText()));
        } catch (ParseException e1) {
            System.err.println(String.format("Worng date format! [%s] Error is [%s]", textField.getText(), e1.getMessage() ));
        }

    }                               
}

class DataModel extends AbstractTableModel
{

    private String timeString;
    private SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm"); 

    public DataModel(String time) {
        this.timeString = time;
    }

    @Override
    public int getRowCount() {
        return 1;
    }

    @Override
    public int getColumnCount() {
        return 1;
    }

    @Override
    public Class<?> getColumnClass(int col) {
        if (col >= 0) {
            return Date.class;
        } else {
            return null;
        }
    }

    @Override
    public boolean isCellEditable(int row, int col) 
    {
        return col >= 0;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {

        Date date = null;

        try {
            date = dateFormat.parse(timeString);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return date;
    }

    @Override
    public void setValueAt(Object aValue, int row, int col) {           

        this.timeString = dateFormat.format(aValue);

        this.fireTableCellUpdated(row, col);  
    }
}
封装测试;
导入java.awt.BorderLayout;
导入java.awt.Component;
导入java.awt.EventQueue;
导入javax.swing.AbstractCellEditor;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.JTextField;
导入javax.swing.border.EmptyBorder;
导入javax.swing.table.AbstractTableModel;
导入javax.swing.table.TableCellEditor;
导入javax.swing.table.TableCellRenderer;
导入javax.swing.JTable;
导入java.text.ParseException;
导入java.text.simpleDataFormat;
导入java.util.Date;
导入javax.swing.event.CaretListener;
导入javax.swing.event.CaretEvent;
导入javax.swing.JScrollPane;
公共类Poligon扩展JFrame{
私有JPanel内容窗格;
专用JTable表;
/**
*启动应用程序。
*/
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
公开募捐{
试一试{
Poligon帧=新Poligon();
frame.setVisible(true);
}捕获(例外e){
e、 printStackTrace();
}
}
});
}
/**
*创建框架。
*/
公共政策{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
立根(100100450300);
contentPane=newjpanel();
setboorder(新的EmptyBorder(5,5,5,5));
setLayout(新的BorderLayout(0,0));
setContentPane(contentPane);
JScrollPane scrollPane=新的JScrollPane();
添加(滚动窗格,BorderLayout.CENTER);
table=新的JTable();
表.setModel(新数据模型(“12:34:00”);
table.setDefaultRenderer(Date.class,new DateRenderer());
table.setDefaultEditor(Date.class,new DateEditor());
表3.设置行高(35);
scrollPane.setViewportView(表);
}
}
类DateRenderer实现TableCellRenderer
{
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、,
布尔值(已选择,布尔值为焦点,整数行,整数列){
JPanel c=新的JPanel();
if(值instanceof Date)
{
SimpleDataFormat dateFormat=新的SimpleDataFormat(“HH:mm”);
c、 添加(新的JLabel(dateFormat.format(value));
}
返回c;
}
}
类DateEditor扩展AbstractCellEditor实现TableCellEditor
{
私有对象cellEditorValue;
@凌驾
公共对象getCellEditorValue(){
返回此.cellEditorValue;
}
public void setCellEditorValue(对象值)
{
this.cellEditorValue=值;
}
@凌驾
公共组件getTableCellEditorComponent(JTable表、对象值、布尔ISselect、int行、int列)
{   
JPanel c=新的JPanel();
if(值instanceof Date)
{
最终SimpleDataFormat日期格式=新SimpleDataFormat(“HH:mm”);
最终JTextField textField=新JTextField();
setText(dateFormat.format(value));
addCaretListener(新的CaretListenerForDate(this,textField));
c、 添加(文本字段);
}
返回c;
}
}
类CaretListenerForDate实现CaretListener
{       
私有JTextField textField;
专用日期编辑器;
public CaretListenerForDate(日期编辑器DateEditor,JTextField textField)
{
this.textField=textField;
this.dateEditor=dateEditor;
}
公共无效caretUpdate(CaretEvent e){
SimpleDataFormat dateFormat=新的SimpleDataFormat(“HH:mm”);
试一试{
setCellEditorValue(dateFormat.parse(textField.getText());
}捕获(解析异常e1){
System.err.println(String.format(“工作日期格式![%s]错误为[%s]”,textField.getText(),e1.getMessage());
}
}                               
}
类DataModel扩展了AbstractTableModel
{
私有字符串时间字符串;
私有SimpleDataFormat dateFormat=新SimpleDataFormat(“HH:mm”);
公共数据模型(字符串时间){
this.timeString=时间;
}
@凌驾
public int getRowCount(){
返回1;
}
@凌驾
public int getColumnCount(){
返回1;
}
@凌驾
公共类getColumnClass(int-col){
如果(列>=0){
返回日期.class;
}否则{
返回null;
}
}
@凌驾
公共布尔值可编辑(int行,int列)
{
返回列>=0;
}
@凌驾
公共对象getValueAt(int行索引、int列索引){
日期=空;
试一试{
date=dateFormat.parse(timeString);
}捕获(解析异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回日期;
}
@凌驾
public void setValueAt(对象有效,int行,int列){
this.timeString=dateFormat.format(aValue);
此.firetablecell已更新(行、列);
}
}

但如果提交的值无效,如何返回到旧值?@P1nGu1n将其旧值保存在单独的字段中,并在输入无效时将其放回原处