如何在LocalDate列上使用RowFilter.dateFilter?

huangapple go评论69阅读模式
英文:

How can i use RowFilter.dateFilter on LocalDate columns

问题

这是日期: String date = "01.11.2020";

列1SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyy");

列2DateTimeFormatter 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 = &quot;01.11.2020&quot;;

Column1 : SimpleDateFormat sdf = new SimpleDateFormat(&quot;dd.MM.yyy&quot;);

Column2 : DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&quot;dd.MM.yyyy&quot;);

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 {&quot;ALL&quot;, &quot;LAST 1 WEEK&quot;, &quot;LAST 1 MONTH&quot;, &quot;LAST 1 YEAR&quot;}
So when i want to see LAST 1 WEEK dates i use a code like this.

TableRowSorter&lt;TableModel&gt; sorter = new TableRowSorter&lt;TableModel&gt;(m1);
java.util.List&lt;RowFilter&lt;Object,Object&gt;&gt; filters = new ArrayList&lt;RowFilter&lt;Object,Object&gt;&gt;(2);
table.setRowSorter(sorter);
filters.add(RowFilter.dateFilter(ComparisonType.AFTER, date,columnIndex));
RowFilter&lt;Object,Object&gt; 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[] {&quot;ALL&quot;, &quot;LAST 1 WEEK&quot;, &quot;LAST 1 MONTH&quot;, &quot;LAST 1 YEAR&quot;}));
cbx_date.setBounds(283, 53, 163, 31);
contentPane.add(cbx_date);
JComboBox cbx_localdate = new JComboBox();
cbx_localdate.setModel(new DefaultComboBoxModel(new String[] {&quot;ALL&quot;, &quot;LAST 1 WEEK&quot;, &quot;LAST 1 MONTH&quot;, &quot;LAST 1 YEAR&quot;}));
cbx_localdate.setBounds(283, 125, 163, 31);
contentPane.add(cbx_localdate);
JLabel lblNewLabel = new JLabel(&quot;With Date&quot;);
lblNewLabel.setBounds(283, 11, 163, 31);
contentPane.add(lblNewLabel);
JLabel lblWithLocaldate = new JLabel(&quot;With LocalDate&quot;);
lblWithLocaldate.setBounds(283, 95, 163, 31);
contentPane.add(lblWithLocaldate);
//Columns
table.setModel(m1);
Object[] columns = {&quot;Date&quot;,&quot;Local Date&quot;};
m1.setColumnIdentifiers(columns);
TableRowSorter&lt;TableModel&gt; sorter = new TableRowSorter&lt;TableModel&gt;(m1);
java.util.List&lt;RowFilter&lt;Object,Object&gt;&gt; filters = new ArrayList&lt;RowFilter&lt;Object,Object&gt;&gt;(2);
table.setRowSorter(sorter);
//Rows
SimpleDateFormat sdf = new SimpleDateFormat(&quot;dd.MM.yyy&quot;);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&quot;dd.MM.yyyy&quot;);
String[] dates = {&quot;01.08.2020&quot;,&quot;05.08.2020&quot;,&quot;20.08.2020&quot;,&quot;21.08.2020&quot;,&quot;01.09.2020&quot;,&quot;15.09.2020&quot;,&quot;01.10.2020&quot;,&quot;15.10.2020&quot;,&quot;01.11.2020&quot;,&quot;01.08.2019&quot;,&quot;01.07.2019&quot;};
Object[] rows = new Object[2];
for(int i=0;i&lt;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(&quot;ALL&quot;)) {
filters.add(RowFilter.dateFilter(ComparisonType.AFTER, datereturn(selected),0));
filters.add(RowFilter.dateFilter(ComparisonType.BEFORE,new Date(),0));
}
RowFilter&lt;Object,Object&gt; 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(&quot;ALL&quot;)) {
filters.add(RowFilter.dateFilter(ComparisonType.AFTER, datereturn(selected),1));
filters.add(RowFilter.dateFilter(ComparisonType.BEFORE,new Date(),1));
}
RowFilter&lt;Object,Object&gt; serviceFilter = RowFilter.andFilter(filters);
sorter.setRowFilter(serviceFilter);
}
});
}
//Returs the date as wanted.
public static Date datereturn (String selected) {
if(selected.equals(&quot;LAST 1 WEEK&quot;)) {
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(&quot;LAST 1 MONTH&quot;)) {
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(&quot;LAST 1 YEAR&quot;)) {
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布局管理器。我使用了FlowLayoutBorderLayoutGridBagLayout来创建GUI。绝对定位在从一个具有不同显示器或不同操作系统的计算机移动时很容易出问题。

此外,将代码分成方法和类会有很大帮助。方法或类越小,测试就越容易。相信我,在使RowFilter正确工作之前,我进行了数百次测试。

这是我创建的GUI。

如何在LocalDate列上使用RowFilter.dateFilter?

请查看所有代码。自定义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.

如何在LocalDate列上使用RowFilter.dateFilter?

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&lt;TableModel&gt; sorter;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new DatePickerExample());
}
@Override
public void run() {
frame = new JFrame(&quot;Date Picker Example&quot;);
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(&quot;With Date&quot;);
innerPanel.add(lblNewLabel, gbc);
String[] options = { &quot;ALL&quot;, &quot;LAST 1 WEEK&quot;, &quot;LAST 1 MONTH&quot;,
&quot;LAST 1 YEAR&quot; };
gbc.gridy++;
JComboBox&lt;String&gt; cbx_date = new JComboBox&lt;&gt;();
cbx_date.setModel(
new DefaultComboBoxModel&lt;String&gt;(options));
cbx_date.addItemListener(new DateItemListener(sorter));
innerPanel.add(cbx_date, gbc);
gbc.gridy++;
JLabel lblWithLocaldate = new JLabel(&quot;With LocalDate&quot;);
innerPanel.add(lblWithLocaldate, gbc);
gbc.gridy++;
JComboBox&lt;String&gt; cbx_localdate = new JComboBox&lt;&gt;();
cbx_localdate.setModel(
new DefaultComboBoxModel&lt;String&gt;(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 = { &quot;Date&quot;, &quot;Local Date&quot; };
model.setColumnIdentifiers(columns);
// Rows
SimpleDateFormat sdf = new SimpleDateFormat(&quot;dd.MM.yyy&quot;);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
&quot;dd.MM.yyyy&quot;);
String[] dates = { &quot;01.08.2020&quot;, &quot;05.08.2020&quot;, &quot;20.08.2020&quot;,
&quot;21.08.2020&quot;, &quot;01.09.2020&quot;, &quot;15.09.2020&quot;,
&quot;01.10.2020&quot;, &quot;15.10.2020&quot;, &quot;01.11.2020&quot;,
&quot;01.08.2019&quot;, &quot;01.07.2019&quot; };
Object[] rows = new Object[2];
for (int i = 0; i &lt; 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&lt;TableModel&gt;(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&lt;?&gt; 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&lt;RowFilter&lt;Object, Object&gt;&gt; filters =
new ArrayList&lt;RowFilter&lt;Object, Object&gt;&gt;(2);
private TableRowSorter&lt;TableModel&gt; sorter;
public DateItemListener(TableRowSorter&lt;TableModel&gt; sorter) {
this.sorter = sorter;
}
@Override
public void itemStateChanged(ItemEvent event) {
filters.clear();
String selected = event.getItem().toString();
if (!selected.equals(&quot;ALL&quot;)) {
filters.add(RowFilter.dateFilter(
ComparisonType.AFTER, calculateAfterDate(
selected)));
filters.add(RowFilter.dateFilter(
ComparisonType.BEFORE, new Date()));
}
RowFilter&lt;Object, Object&gt; serviceFilter =
RowFilter.andFilter(filters);
sorter.setRowFilter(serviceFilter);
}
// Returns the date as wanted.
private Date calculateAfterDate(String selected) {
Calendar cal = Calendar.getInstance();
if (selected.equals(&quot;LAST 1 WEEK&quot;)) {
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(&quot;LAST 1 MONTH&quot;)) {
cal.add(Calendar.MONTH, -1);
cal.add(Calendar.DAY_OF_MONTH, -1);
} else if (selected.equals(&quot;LAST 1 YEAR&quot;)) {
cal.add(Calendar.YEAR, -1);
cal.add(Calendar.DAY_OF_MONTH, -1);
}
return cal.getTime();
}
}
public class LocalDateItemListener implements ItemListener {
private TableRowSorter&lt;TableModel&gt; sorter;
public LocalDateItemListener(TableRowSorter&lt;TableModel&gt; sorter) {
this.sorter = sorter;
}
@Override
public void itemStateChanged(ItemEvent event) {
String selected = event.getItem().toString();
LocalDate afterDate = calculateAfterDate(selected);
sorter.setRowFilter(null);
RowFilter&lt;TableModel, Integer&gt; localDateFilter =
new RowFilter&lt;TableModel, Integer&gt;() {
@Override
public boolean include(Entry&lt;? extends TableModel,
? extends Integer&gt; entry) {
TableModel model = entry.getModel();
LocalDate date = (LocalDate) model.getValueAt(
entry.getIdentifier(), 1);
return date.isAfter(afterDate) &amp;&amp;
date.isBefore(LocalDate.now());
}
};
if (!selected.equals(&quot;ALL&quot;)) {
sorter.setRowFilter(localDateFilter);
}
}
private LocalDate calculateAfterDate(String selected) {
LocalDate date = LocalDate.now();
if (selected.equals(&quot;LAST 1 WEEK&quot;)) {
date = date.plusDays(-7);
date = date.plusDays(-1);
} else if (selected.equals(&quot;LAST 1 MONTH&quot;)) {
date = date.plusMonths(-1);
date = date.plusDays(-1);
} else if (selected.equals(&quot;LAST 1 YEAR&quot;)) {
date = date.plusYears(-1);
date = date.plusDays(-1);
}
return date;
}
}
}

huangapple
  • 本文由 发表于 2020年9月2日 16:02:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63701193.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定