问题描述
这是日期:String date = "01.11.2020";
Column1 :SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyy");
Column2 :DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
Column1 用SimpleDateFormat
解析,而 Column2 用DateTimeFormatter
解析。
//Column1 Column2
01 Kas 2020 2020-11-01
我有一个 JComboBox ,其中包含类似{"ALL","LAST 1 WEEK","LAST 1 MONTH","LAST 1 YEAR"}
的项目
因此,当我想查看LAST 1 WEEK
日期时,我会使用类似这样的代码。
tablerowsorter<TableModel> sorter = new tablerowsorter<TableModel>(m1);
java.util.List<RowFilter<Object,Object>> filters = new ArrayList<RowFilter<Object,Object>>(2);
table.setRowSorter(sorter);
filters.add(RowFilter.datefilter(ComparisonType.AFTER,date,columnIndex));
RowFilter<Object,Object> serviceFilter = RowFilter.andFilter(filters);
sorter.setRowFilter(serviceFilter);
它与 Column1 一起正常工作。但是它不会对 Column2 进行排序。我猜它不接受为日期。
Column1 是表模型中的Date.Class
*列。 Column2 在表模型中是LocalDate.Class
。(我试图制作两个Date.Class
,但Column2给出了错误。)。
有什么方法可以在RowFilter.datefilter
列上使用LocalDate.Class
。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.tablerowsorter;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.RowFilter.ComparisonType;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.DefaultComboBoxModel;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
public class frm1 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 {
frm1 frame = new frm1();
frame.setVisible(true);
} catch (Exception e) {
e.printstacktrace();
}
}
});
}
/**
* Create the frame.
* @throws ParseException
*/
public frm1() throws ParseException {
setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,501,425);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5,5,5));
setContentPane(contentPane);
contentPane.setLayout(null);
DefaultTableModel m1 = new DefaultTableModel() {
public Class getColumnClass(int column) {
switch (column) {
case 0:
return Date.class;
case 1:
return LocalDate.class;
default:
return String.class;
}
}
public boolean isCellEditable(int row,int column) {
return false;
}
};
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10,11,263,325);
contentPane.add(scrollPane);
table = new JTable();
table.setBounds(329,256,1,1);
//contentPane.add(table);
scrollPane.setViewportView(table);
JComboBox cbx_date = new JComboBox();
cbx_date.setModel(new DefaultComboBoxModel(new String[] {"ALL","LAST 1 YEAR"}));
cbx_date.setBounds(283,53,163,31);
contentPane.add(cbx_date);
JComboBox cbx_localdate = new JComboBox();
cbx_localdate.setModel(new DefaultComboBoxModel(new String[] {"ALL","LAST 1 YEAR"}));
cbx_localdate.setBounds(283,125,31);
contentPane.add(cbx_localdate);
JLabel lblNewLabel = new JLabel("With Date");
lblNewLabel.setBounds(283,31);
contentPane.add(lblNewLabel);
JLabel lblWithLocaldate = new JLabel("With LocalDate");
lblWithLocaldate.setBounds(283,95,31);
contentPane.add(lblWithLocaldate);
//Columns
table.setModel(m1);
Object[] columns = {"Date","Local Date"};
m1.setColumnIdentifiers(columns);
tablerowsorter<TableModel> sorter = new tablerowsorter<TableModel>(m1);
java.util.List<RowFilter<Object,Object>>(2);
table.setRowSorter(sorter);
//Rows
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyy");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
String[] dates = {"01.08.2020","05.08.2020","20.08.2020","21.08.2020","01.09.2020","15.09.2020","01.10.2020","15.10.2020","01.11.2020","01.08.2019","01.07.2019"};
Object[] rows = new Object[2];
for(int i=0;i<dates.length;i++) {
rows[0]=sdf.parse(dates[i]);
rows[1]=LocalDate.parse(dates[i],formatter);
m1.addRow(rows);
}
//Date state change event.
cbx_date.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
filters.clear();
String selected = cbx_date.getSelectedItem().toString();
if(!selected.equals("ALL")) {
filters.add(RowFilter.datefilter(ComparisonType.AFTER,datereturn(selected),0));
filters.add(RowFilter.datefilter(ComparisonType.BEFORE,new Date(),0));
}
RowFilter<Object,Object> serviceFilter = RowFilter.andFilter(filters);
sorter.setRowFilter(serviceFilter);
}
});
//LocalDate state change event.
cbx_localdate.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
filters.clear();
String selected = cbx_localdate.getSelectedItem().toString();
if(!selected.equals("ALL")) {
filters.add(RowFilter.datefilter(ComparisonType.AFTER,1));
filters.add(RowFilter.datefilter(ComparisonType.BEFORE,1));
}
RowFilter<Object,Object> serviceFilter = RowFilter.andFilter(filters);
sorter.setRowFilter(serviceFilter);
}
});
}
//Returs the date as wanted.
public static Date datereturn (String selected) {
if(selected.equals("LAST 1 WEEK")) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH,-7);
cal.add(Calendar.DAY_OF_MONTH,-1);// make 1 less date so i can get the EQUALS day.Becouse of ComparisonType.AFTER
Date old = cal.getTime();
return old;
}else if(selected.equals("LAST 1 MONTH")) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MONTH,-1);
cal.add(Calendar.DAY_OF_MONTH,-1);
Date old = cal.getTime();
return old;
}else if(selected.equals("LAST 1 YEAR")) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR,-1);
Date old = cal.getTime();
return old;
}else {
Calendar cal = Calendar.getInstance();
Date old = cal.getTime();
return old;
}
}
}
解决方法
我终于弄清楚了如何为LocalDate编写RowFilter
。
创建GUI时,应使用Swing layout managers。我使用了FlowLayout
,BorderLayout
和GridBagLayout
来创建GUI。当您从一台计算机使用另一台显示器或不同的操作系统从另一台计算机移动到另一台计算机时,绝对定位非常脆弱,无法正常工作。
此外,将您的代码分为方法和类也很有帮助。方法或类越小,测试就越容易。相信我,在使RowFilter正常工作之前,我进行了数百次测试。
这是我创建的GUI。
请查看所有代码。自定义RowFilter
的代码在LocalDateItemListener
类中。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.RowFilter.ComparisonType;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class DatePickerExample implements Runnable {
private DefaultTableModel model;
private JFrame frame;
private JTable table;
private TableRowSorter<TableModel> sorter;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new DatePickerExample());
}
@Override
public void run() {
frame = new JFrame("Date Picker Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTablePanel(),BorderLayout.CENTER);
frame.add(createControlPanel(),BorderLayout.AFTER_LINE_ENDS);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createControlPanel() {
JPanel panel = new JPanel(new FlowLayout());
JPanel innerPanel = new JPanel(new GridBagLayout());
innerPanel.setBorder(BorderFactory.createEmptyBorder(
5,5,5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5,5);
gbc.gridx = 0;
gbc.gridy = 0;
JLabel lblNewLabel = new JLabel("With Date");
innerPanel.add(lblNewLabel,gbc);
String[] options = { "ALL","LAST 1 WEEK","LAST 1 MONTH","LAST 1 YEAR" };
gbc.gridy++;
JComboBox<String> cbx_date = new JComboBox<>();
cbx_date.setModel(
new DefaultComboBoxModel<String>(options));
cbx_date.addItemListener(new DateItemListener(sorter));
innerPanel.add(cbx_date,gbc);
gbc.gridy++;
JLabel lblWithLocaldate = new JLabel("With LocalDate");
innerPanel.add(lblWithLocaldate,gbc);
gbc.gridy++;
JComboBox<String> cbx_localdate = new JComboBox<>();
cbx_localdate.setModel(
new DefaultComboBoxModel<String>(options));
cbx_localdate.addItemListener(new LocalDateItemListener(sorter));
innerPanel.add(cbx_localdate,gbc);
panel.add(innerPanel);
return panel;
}
private JPanel createTablePanel() {
JPanel panel = new JPanel(new BorderLayout());
model = new MyTableModel();
// Columns
Object[] columns = { "Date","Local Date" };
model.setColumnIdentifiers(columns);
// Rows
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyy");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"dd.MM.yyyy");
String[] dates = { "01.08.2020","05.08.2020","20.08.2020","21.08.2020","01.09.2020","15.09.2020","01.10.2020","15.10.2020","01.11.2020","01.08.2019","01.07.2019" };
Object[] rows = new Object[2];
for (int i = 0; i < dates.length; i++) {
try {
rows[0] = sdf.parse(dates[i]);
} catch (ParseException e) {
e.printStackTrace();
}
rows[1] = LocalDate.parse(dates[i],formatter);
model.addRow(rows);
}
table = new JTable(model);
sorter = new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);
JScrollPane scrollPane = new JScrollPane(table);
panel.add(scrollPane,BorderLayout.CENTER);
return panel;
}
public class MyTableModel extends DefaultTableModel {
private static final long serialVersionUID = 1L;
@Override
public Class<?> getColumnClass(int column) {
switch (column) {
case 0:
return Date.class;
case 1:
return LocalDate.class;
default:
return String.class;
}
}
@Override
public boolean isCellEditable(int row,int column) {
return false;
}
}
public class DateItemListener implements ItemListener {
private List<RowFilter<Object,Object>> filters =
new ArrayList<RowFilter<Object,Object>>(2);
private TableRowSorter<TableModel> sorter;
public DateItemListener(TableRowSorter<TableModel> sorter) {
this.sorter = sorter;
}
@Override
public void itemStateChanged(ItemEvent event) {
filters.clear();
String selected = event.getItem().toString();
if (!selected.equals("ALL")) {
filters.add(RowFilter.dateFilter(
ComparisonType.AFTER,calculateAfterDate(
selected)));
filters.add(RowFilter.dateFilter(
ComparisonType.BEFORE,new Date()));
}
RowFilter<Object,Object> serviceFilter =
RowFilter.andFilter(filters);
sorter.setRowFilter(serviceFilter);
}
// Returns the date as wanted.
private Date calculateAfterDate(String selected) {
Calendar cal = Calendar.getInstance();
if (selected.equals("LAST 1 WEEK")) {
cal.add(Calendar.DAY_OF_MONTH,-7);
// Make 1 less date so I can get the EQUALS day.
// Because of ComparisonType.AFTER
cal.add(Calendar.DAY_OF_MONTH,-1);
} else if (selected.equals("LAST 1 MONTH")) {
cal.add(Calendar.MONTH,-1);
cal.add(Calendar.DAY_OF_MONTH,-1);
} else if (selected.equals("LAST 1 YEAR")) {
cal.add(Calendar.YEAR,-1);
}
return cal.getTime();
}
}
public class LocalDateItemListener implements ItemListener {
private TableRowSorter<TableModel> sorter;
public LocalDateItemListener(TableRowSorter<TableModel> sorter) {
this.sorter = sorter;
}
@Override
public void itemStateChanged(ItemEvent event) {
String selected = event.getItem().toString();
LocalDate afterDate = calculateAfterDate(selected);
sorter.setRowFilter(null);
RowFilter<TableModel,Integer> localDateFilter =
new RowFilter<TableModel,Integer>() {
@Override
public boolean include(Entry<? extends TableModel,? extends Integer> entry) {
TableModel model = entry.getModel();
LocalDate date = (LocalDate) model.getValueAt(
entry.getIdentifier(),1);
return date.isAfter(afterDate) &&
date.isBefore(LocalDate.now());
}
};
if (!selected.equals("ALL")) {
sorter.setRowFilter(localDateFilter);
}
}
private LocalDate calculateAfterDate(String selected) {
LocalDate date = LocalDate.now();
if (selected.equals("LAST 1 WEEK")) {
date = date.plusDays(-7);
date = date.plusDays(-1);
} else if (selected.equals("LAST 1 MONTH")) {
date = date.plusMonths(-1);
date = date.plusDays(-1);
} else if (selected.equals("LAST 1 YEAR")) {
date = date.plusYears(-1);
date = date.plusDays(-1);
}
return date;
}
}
}