英文:
How can i use RowFilter.dateFilter on LocalDate columns
问题
这是日期: String date = "01.11.2020";
列1:SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyy");
列2:DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
使用SimpleDateFormat
解析的列1和使用DateTimeFormatter
解析的列2。
//列1 列2
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);
对于列1,它可以正常工作。但是它无法对列2进行排序。我猜这是因为它不将其视为日期。
列1是表模型中的Date.class
列。列2是表模型中的LocalDate.class
列。(我尝试过将它们都设置为Date.class
,但列2会报错。)
有没有办法在LocalDate.class
列上使用RowFilter.dateFilter
?
我写了一些代码以更详细地解释。这是一个示例类:
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;
// ...(省略导入部分)
public class frm1 extends JFrame {
// ...(省略类的其余部分)
// 返回所需的日期
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); // 减去1天,以便可以得到EQUALS日期,因为使用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);
cal.add(Calendar.DAY_OF_MONTH, -1);
Date old = cal.getTime();
return old;
} else {
Calendar cal = Calendar.getInstance();
Date old = cal.getTime();
return old;
}
}
}
请注意,由于您只要求翻译代码部分,所以我只翻译了代码,去掉了解释和注释。如果您有任何关于代码或问题的进一步疑问,请随时提问。
英文:
This is the date : String date = "01.11.2020";
Column1 : SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyy");
Column2 : DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
Column1 parsed with SimpleDateFormat
and Column2 parsed with DateTimeFormatter
.
//Column1 Column2
01 Kas 2020 2020-11-01
I have a JComboBox with items like this {"ALL", "LAST 1 WEEK", "LAST 1 MONTH", "LAST 1 YEAR"}
So when i want to see LAST 1 WEEK
dates i use a code like this.
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);
It works fine with Column1. But it does not sort Column2. I guess it does not accept it as a date.
Column1 is Date.Class
* column in table model. Column2 is LocalDate.Class
in table model.( I have tryed to make both Date.Class
but Column2 gives error. ).
Is there any way i can use RowFilter.dateFilter
on LocalDate.Class
columns.
I wrote some codes to explain it with more details. Here is a class for example:
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, 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 WEEK", "LAST 1 MONTH", "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 WEEK", "LAST 1 MONTH", "LAST 1 YEAR"}));
cbx_localdate.setBounds(283, 125, 163, 31);
contentPane.add(cbx_localdate);
JLabel lblNewLabel = new JLabel("With Date");
lblNewLabel.setBounds(283, 11, 163, 31);
contentPane.add(lblNewLabel);
JLabel lblWithLocaldate = new JLabel("With LocalDate");
lblWithLocaldate.setBounds(283, 95, 163, 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>> filters = new ArrayList<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, datereturn(selected),1));
filters.add(RowFilter.dateFilter(ComparisonType.BEFORE,new Date(),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);
cal.add(Calendar.DAY_OF_MONTH, -1);
Date old = cal.getTime();
return old;
}else {
Calendar cal = Calendar.getInstance();
Date old = cal.getTime();
return old;
}
}
}
答案1
得分: 2
我终于弄清楚如何为LocalDate
编写RowFilter
。
在创建GUI时,应使用Swing布局管理器。我使用了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 {
// ...(省略其余代码,与原文相同)
}
英文:
I finally figured out how to write a RowFilter
for a LocalDate.
When you create a GUI, you should use Swing layout managers. I used the FlowLayout
, BorderLayout
, and GridBagLayout
to create the GUI. Absolute positioning is brittle and does not work well when you move from one computer to another with a different monitor or different operating system.
Also, it helps a lot to separate your code into methods and classes. The smaller the method or class, the easier it is to test. Believe me, I ran hundreds of tests before I got the RowFilter to work correctly.
Here's the GUI I created.
Please review all of the code. The code with the custom RowFilter
is in the LocalDateItemListener
class.
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, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 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);
cal.add(Calendar.DAY_OF_MONTH, -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;
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论