- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
基本上这里的问题如下,我有这个 TableCellRenderer:
public class CellRenderer_LocalDate extends DefaultTableCellRenderer implements TableCellRenderer {
private static final long serialVersionUID = -9184414041940041458L;
String displayFormat;
public CellRenderer_LocalDate(String dateFormat) {
this.displayFormat = dateFormat;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
if (value instanceof LocalDate) {
LocalDate date = (LocalDate) value;
value = date.format(DateTimeFormatter.ofPattern(displayFormat));
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
还有这个搜索 JTable 的函数:
/**
* Filters the table to show a specific text
*/
public void searchTable(JTextField searchTextField) {
// Get model & instantiate table sorter
DefaultTableModel tableToFilter = (DefaultTableModel) this.getModel();
TableRowSorter<DefaultTableModel> trSorter = new TableRowSorter<DefaultTableModel>(tableToFilter);
// Get text to search & Set row filter for this table
String search = searchTextField.getText();
// Filter table in correct format
trSorter.setRowFilter(RowFilter.regexFilter("(?i)" + search)); // Insensitive to upper case or lower case
this.setRowSorter(trSorter);
}
我在 JTable 中有一列,其中包含 LocalDate。我让 TableCellRenderer 将 LocalDate 列显示为 dd.mm.yyyy。它按应有的方式工作。
问题是,当我使用 dd.mm.yyyy 格式的搜索功能时,它没有显示任何与 JTable 中显示的 LocalDate 方式相匹配的行。
例如:我有一列包含 LocalDate 2022-05-10。由于 TableCellRenderer,它显示为 10.05.2022。现在,如果我使用搜索并查找 10.05.2022,则不会显示任何内容,就好像没有任何匹配项一样。但是,如果我在搜索字段 2022-05-10 中输入,它会立即显示正确的结果。拜托,我应该更改我的功能以修复此错误吗?
最佳答案
因此,基于 this example ,我深入研究了 Java 源代码并提取了 RowFilter.dateFilter
并对其进行了修改以直接支持 LocalDate
。这意味着,您可以获得 RowFilter.dateFilter
的所有特性和功能,但使用 LocalDate
而不是 Date
。
如果我要为一系列混合值提供可搜索的解决方案,我会设计一个专用的“过滤器组件”,它提供了允许用户自行配置过滤器的机制。在这种情况下,这意味着允许用户独立地为日期值配置过滤参数(即,包括/排除给定范围,按月或年过滤或直接过滤,仅在这一天)
这将根据用户偏好相应地构建RowSorter
以下示例过于简单,仅用于演示如何自定义 RowSorter
以处理不同的数据类型。
要按日期值搜索,您必须提供格式为 dd/MM/yyyy
的有效日期。
该示例使用了 RowFilter.orFilter
,因此它将匹配 LocalDateFilter
或 RowFilter.regexFilter
再次重申,这仅作为演示。
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.RowFilter.ComparisonType;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTable table;
private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
public TestPane() {
setLayout(new BorderLayout());
table = new JTable();
DefaultTableModel model = new DefaultTableModel(
new Object[][]{
{"A", 1, LocalDate.parse("12/05/2000", formatter)},
{"B", 2, LocalDate.parse("12/06/2000", formatter)},
{"C", 3, LocalDate.parse("12/07/2000", formatter)},
{"D", 4, LocalDate.parse("12/08/2000", formatter)},
{"E", 5, LocalDate.parse("12/09/2000", formatter)},
{"F", 1, LocalDate.parse("12/10/2000", formatter)},
{"G", 2, LocalDate.parse("12/11/2000", formatter)},
{"H", 3, LocalDate.parse("12/12/2000", formatter)},
{"I", 4, LocalDate.parse("12/01/1990", formatter)},
{"J", 5, LocalDate.parse("12/02/1990", formatter)},
{"K", 1, LocalDate.parse("12/03/1990", formatter)},
{"L", 2, LocalDate.parse("12/04/1995", formatter)},
{"M", 3, LocalDate.parse("12/05/1995", formatter)},
{"N", 4, LocalDate.parse("12/06/1995", formatter)},
{"O", 5, LocalDate.parse("12/07/1995", formatter)},
{"P", 1, LocalDate.parse("12/08/1980", formatter)},
{"Q", 2, LocalDate.parse("12/09/1980", formatter)},
{"R", 3, LocalDate.parse("12/10/1980", formatter)},
{"S", 4, LocalDate.parse("12/11/1980", formatter)},
{"T", 5, LocalDate.parse("12/12/1980", formatter)},
{"U", 1, LocalDate.parse("12/01/1985", formatter)},
{"V", 2, LocalDate.parse("12/02/1985", formatter)},
{"W", 3, LocalDate.parse("12/03/1985", formatter)},
{"X", 4, LocalDate.parse("12/04/1985", formatter)},
{"Y", 5, LocalDate.parse("12/05/1985", formatter)},
{"Z", 1, LocalDate.parse("12/06/1985", formatter)},},
new Object[]{"Name", "Number", "Date"}) {
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return String.class;
case 1:
return Integer.class;
case 2:
return LocalDate.class;
}
return Object.class;
}
};
table.setModel(model);
table.setAutoCreateRowSorter(true);
table.setDefaultRenderer(LocalDate.class, new LocalDateTableCellRenderer(formatter));
add(new JScrollPane(table));
JTextField textField = new JTextField(10);
add(textField, BorderLayout.SOUTH);
textField.addActionListener(new ActionListener() {
protected LocalDate toLocalDate(String text) {
try {
return LocalDate.parse(textField.getText(), formatter);
} catch (DateTimeParseException exp) {
return null;
}
}
@Override
public void actionPerformed(ActionEvent e) {
String text = textField.getText();
if (text.isEmpty()) {
table.setRowSorter(null);
return;
}
List<RowFilter<Object, Object>> filters = new ArrayList<>(2);
// Include the date only if we can parse the text
LocalDate searchDate = toLocalDate(text);
if (searchDate != null) {
filters.add(new LocalDateFilter(ComparisonType.EQUAL, searchDate, 2));
// You can also support date rangers if you want
//filters.add(new LocalDateFilter(ComparisonType.BEFORE, searchDate, 2));
//filters.add(new LocalDateFilter(ComparisonType.AFTER, searchDate, 2));
}
// OR filter every thing else...
filters.add(RowFilter.regexFilter("(?i)" + text, new int[]{0, 1}));
TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<>((DefaultTableModel) table.getModel());
sorter.setRowFilter(RowFilter.orFilter(filters));
table.setRowSorter(sorter);
}
});
}
}
public class LocalDateTableCellRenderer extends DefaultTableCellRenderer {
private DateTimeFormatter formatter;
public LocalDateTableCellRenderer(DateTimeFormatter formatter) {
this.formatter = formatter;
}
public DateTimeFormatter getFormatter() {
return formatter;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (value instanceof LocalDate) {
setText(getFormatter().format((LocalDate) value));
}
return this;
}
}
public abstract class AbstractFilter<M, I> extends RowFilter<M, I> {
private int[] columns;
public AbstractFilter(int[] columns) {
this.columns = columns;
}
@Override
public boolean include(RowFilter.Entry<? extends M, ? extends I> value) {
int count = value.getValueCount();
if (columns.length > 0) {
for (int i = columns.length - 1; i >= 0; i--) {
int index = columns[i];
if (index < count) {
if (include(value, index)) {
return true;
}
}
}
} else {
while (--count >= 0) {
if (include(value, count)) {
return true;
}
}
}
return false;
}
protected abstract boolean include(RowFilter.Entry<? extends M, ? extends I> value, int index);
}
public class LocalDateFilter<M, I> extends AbstractFilter<M, I> {
private LocalDate date;
private RowFilter.ComparisonType type;
public LocalDateFilter(RowFilter.ComparisonType type, LocalDate date, int column) {
this(type, date, new int[]{column});
}
public LocalDateFilter(RowFilter.ComparisonType type, LocalDate date, int[] columns) {
super(columns);
if (type == null) {
throw new IllegalArgumentException("type must be non-null");
}
this.type = type;
this.date = date;
}
@Override
protected boolean include(RowFilter.Entry<? extends M, ? extends I> value, int index) {
Object v = value.getValue(index);
if (v instanceof LocalDate) {
LocalDate vDate = (LocalDate) v;
switch (type) {
case BEFORE:
return (vDate.isBefore(date));
case AFTER:
return (vDate.isAfter(date));
case EQUAL:
return (vDate.equals(date));
case NOT_EQUAL:
return !(vDate.equals(date));
default:
break;
}
}
return false;
}
}
}
您“可以”修改 LocalDateFilter
以通过提供的 DateTimeFormatter
将日期值转换为 String
,但我担心您不恰本地混合了表示和数据概念,因为它们应该彼此不可知 - 但我就是这样。
关于是否应该使用渲染器来“更改数据项的文本”存在一些讨论。老实说,我不认为这是非黑即白的。有时你,主人,不想要那种功能,但对我来说, View 是“数据的可视化表示”,你不应该“需要”按摩数据以通过 View ,这不是模型的工作,而是 View 的工作。
例如,我可以在 JList
中表示相同的数据,根据应用程序的需要以及应用程序试图向用户呈现的内容,使用短日期格式或长日期格式- 甚至更多,它可能是需要应用的用户提供的配置 - 这些是渲染器/ View 的域,数据应该需要更改(恕我直言)。
所以,复制粘贴。当我复制一行 (Command+C) 时,它复制了 A 1 2000-05-12
,因此,这里无需执行任何操作。如果您需要更改其复制的“方式”(即,您希望将其显示为 ddd MMM yyyy
,您可以执行类似 this for example 的操作 - 这里重要的是,您我已经控制了)
至于可访问性,如果你通读了 How to Support Assistive Technologies您会注意到,可访问性是通过 toolTipText
和 JComponent#getAccessibleContext
等功能提供的,它们是单元格渲染的方法,因此,再次强调,这不是驱动的问题我“按摩”我的数据。
再次重申,上下文为王。有时包装器/代理对象值得付出努力,但我总是问自己,“我失去了什么?”和“我得到了什么?”通过这样做以及我需要创建多少这些,所以我在 JTable
或 JComboBox
或 JList
或其他一些中呈现相同的数据组件 - 但是,那就是我。
关于java - 当使用 TableCellRenderer 以 dd.mm.yyyy 格式显示本地日期时,我的 JTable 搜索功能无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72179266/
我的数据库中有两张表,一张用于 field ,另一张用于预订。我需要的是一个查询来选择所有未预订的 field 。见下文: 餐 table 预订具有以下字段: bk_id venue_id 作为(预订
嗨,我是编码新手,我有一些培训项目,其中包括从 HTML 表单输入 MySQL 数据库。它就像你玩过的游戏的日志。第一个日期输入是您开始游戏的时间,第二个日期输入是您完成游戏的时间。但我需要检查器或类
我是这个 sql 编码的新手,我正在尝试学习新的东西。因此,我创建了一个交货表,其中包含一些属性,如商品代码、交货日期、交货数量。所以如何从同一张表中获取第一个交货日期(最小日期)和交货数量以及最晚交
我从支付网关返回了这个日期 2014-05-15T08:40:52+01:00 我得到 2014-05-15T08:40:52 但我无法识别时区 +01:00 的含义 我的位置时区是 UTC−06:0
我快要疯了,请帮忙。 我有一列包含日期时间值。 我需要找到每天的最小值和最大值。 数据看起来像这样 2012-11-23 05:49:26.000 2012-11-23 07:55:43.000
我从 json 数据中获取日期为 2015 年 4 月 15 日晚上 10:15我只想在 html 页面中显示 json 响应数据的时间,例如 10:15 PM这里我放了我的js函数和html代码 J
是否有 javascript 库或其他机制允许我将 .NET 日期/时间格式字符串(即 yyyy-MM-dd HH:mm:ss)传递给 javascript函数并让它相应地解析提供的日期时间值?我一直
我正在使用以下代码以正确的格式获取当前的 UTC 时间,但客户返回并要求时间戳现在使用 EST 而不是 UTC。我搜索了 Google 和 stackoverflow,但找不到适用于我现有代码的答案。
我有以下日期的平均温度数据。我想找到连续至少 5 天低于或高于 0 摄氏度的开始日期。 date_short mean.temp 1 2018-05-18 17.54 2 2018-05-19
它可以在其他网络浏览器中使用,但 IE11 返回无效日期。 为了调试我使用了下面的代码。 console.log('before - ' + date.value); date.value = new
我在 Excel 中有一个数据的 Web 提取,其中日期列带有/Date(1388624400000)/。我需要在 Excel 中将其转换为日期。 最佳答案 能够从 here 中推断出它. 假设字符串
嗨,我的 Schmema 有一个带有 ISO 日期的字段: ISODate("2015-04-30T14:47:46.501Z") Paypal 在成功付款后以该形式返回日期对象: Time/Date
我的 table : CREATE TABLE `tbdata` ( `ID` INT(10) NOT NULL AUTO_INCREMENT, `PatientID` INT(10) NOT
我正在 Ubuntu 服务器 12.04 中编写一个 shell 脚本,它应该比较日志文件中的一些数据。在日志文件中,日期以以下格式给出: [Mon Apr 08 15:02:54 2013] 如您所
我想使用 GROUP BY WITH ROLLUP 创建一个表并获取总行数而不是 null。 $sql ="SELECT IF(YEAR(transaktioner.datum
我正在创建博客文章,在成功迁移我的博客文件后,当我转到我网站的博客页面时返回一个错误(无法解析其余部分:':“Ymd”'来自'post.date|date: "Ymd"') 我似乎无法确定这是语法错误
我正在尝试获取要插入到 CAML 查询中的月份范围,即:2010-09-01 和 2010-09-30。 我使用以下代码生成这两个值: var month = "10/2010"; var month
如何将代码document.write("直到指定日期")更改为writeMessage(date)中的日期?此外,writeMessage(date) 中的日期未正确显示(仅显示年份)。感谢您帮助解
我在 Windows (XP) 和 Linux 上都尝试过 utime()。在 Windows 上我得到一个 EACCES 错误,在 Linux 上我没有得到任何错误(但时间没有改变)。我的 utim
我正在尝试计算发生在同一日期的值的总和(在 XYZmin 中)。 我的数据看起来像这样, bar <- structure(list(date = structure(c(15622, 15622,
我是一名优秀的程序员,十分优秀!