- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我尝试实现的搜索是类似 google-chrome 的搜索类型,所有匹配项均以黄色突出显示,当前匹配项以橙色突出显示,并且可以使用 Enter 向前导航或使用 Shift+Enter 向后导航。我使用的 Swing 组件是 Netbeans Swing Outline,它基本上看起来像 JTree 表。它一直有效,直到通过单击大纲的任何列对大纲进行排序为止。对于本示例,只有一列。
为了使这个示例正常工作,我们需要来自 Netbeans 发行版的大纲 jar,该文件位于 netbeans\platform\modules\org-netbeans-swing-outline.jar。另一种选择是将此 Gradle 构建文件 (build.gradle) 放置在 Gradle 项目的根目录中:
plugins {
id 'java-library'
}
dependencies {
compile 'uk.gov.nationalarchives.thirdparty.netbeans:org-netbeans-swing-outline:7.2'
}
repositories {
mavenCentral()
}
树模型具有搜索功能 findNodesWithPattern,可将搜索放入列表中:
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Pattern;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
public class TestTreeModel extends DefaultTreeModel {
private static final long serialVersionUID = 1L;
public TestTreeModel() {
super(buildModel());
}
private static TreeNode buildModel() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("");
for (int i = 0; i < 3; i++) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode("test" + i);
for (int j = 0; j < 3; j++) {
node.add(new DefaultMutableTreeNode("subtest" + j));
}
root.add(node);
}
return root;
}
@Override
public DefaultMutableTreeNode getRoot() {
return (DefaultMutableTreeNode) super.getRoot();
}
public List<TreeNode> findNodesMatchingPattern(Pattern pattern) {
List<TreeNode> matchingNodes = new ArrayList<>();
findNodesWithpattern(matchingNodes, getRoot(), pattern);
return matchingNodes;
}
private void findNodesWithpattern(List<TreeNode> matchingNodes, TreeNode node, Pattern pattern) {
if (pattern.matcher(node.toString()).find()) {
matchingNodes.add(node);
}
Enumeration<DefaultMutableTreeNode> children = node.children();
while (children.hasMoreElements()) {
findNodesWithpattern(matchingNodes, children.nextElement(), pattern);
}
}
}
还有一个行模型,它使用对象的哈希代码定义一个名为 Value 的列(仅用于演示目的)
import org.netbeans.swing.outline.RowModel;
public class TestRowModel implements RowModel {
@Override
public Class getColumnClass(int column) {
return Integer.class;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public String getColumnName(int column) {
return "Value";
}
@Override
public Object getValueFor(Object node, int column) {
return node.hashCode();
}
@Override
public boolean isCellEditable(Object node, int column) {
return false;
}
@Override
public void setValueFor(Object node, int column, Object value) {
// do nothing for now
}
}
负责以黄色或橙色突出显示的渲染:
import java.awt.Color;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import org.netbeans.swing.outline.RenderDataProvider;
public class TestRenderData implements RenderDataProvider {
private String searchPattern;
private TreeNode currentMatch;
@Override
public java.awt.Color getBackground(Object o) {
return null;
}
@Override
public String getDisplayName(Object o) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) o;
if (searchPattern == null || searchPattern.length() == 0) {
return node.toString();
}
try {
Pattern pattern = Pattern.compile("(" + searchPattern + ")");
Matcher matcher = pattern.matcher(node.toString());
Color bgColor = Color.YELLOW;
if (matcher.find()) {
if (node == currentMatch) {
bgColor = Color.ORANGE;
}
}
String bgHexColor = Integer.toHexString(bgColor.getRGB() & 0xffffff);
String replacement = matcher.replaceAll("<span style=\"background-color: #" + bgHexColor + "\">$1</span>");
return "<html>" + replacement + "</html>";
} catch (PatternSyntaxException e) {
return node.toString();
}
}
@Override
public java.awt.Color getForeground(Object o) {
return null;
}
@Override
public javax.swing.Icon getIcon(Object o) {
return null;
}
@Override
public String getTooltipText(Object o) {
return null;
}
@Override
public boolean isHtmlDisplayName(Object o) {
return false;
}
public void setSearchPattern(String searchPattern) {
this.searchPattern = searchPattern;
}
public void setCurrentMatch(TreeNode currentMatch) {
this.currentMatch = currentMatch;
}
}
主类使用快速过滤器(不匹配的节点被过滤掉)和触发搜索的关键监听器构建大纲。当输入 Enter 键时,它会增加计数器 (nthMatch),并且索引 nthMatch 处的当前匹配项会被渲染器以橙色高亮显示。
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import org.netbeans.swing.etable.QuickFilter;
import org.netbeans.swing.outline.DefaultOutlineModel;
import org.netbeans.swing.outline.Outline;
import org.netbeans.swing.outline.OutlineModel;
public class MainFrame extends JFrame {
private static final long serialVersionUID = 1L;
public MainFrame() {
TestTreeModel treeMdl = new TestTreeModel();
OutlineModel mdl = DefaultOutlineModel.createOutlineModel(treeMdl, new TestRowModel(), true, "Test");
Outline outline = new Outline();
TestRenderData renderData = new TestRenderData();
outline.setRenderDataProvider(renderData);
outline.setRootVisible(false);
outline.setModel(mdl);
JScrollPane jScrollPane1 = new JScrollPane(outline);
jScrollPane1.setViewportView(outline);
JMenuBar mb = new JMenuBar();
JLabel searchPatternLabel = new JLabel(" Search : ");
mb.add(searchPatternLabel);
JTextField searchPatternTextField = new JTextField();
searchPatternLabel.setLabelFor(searchPatternTextField);
outline.setQuickFilter(0, new QuickFilter() {
@Override
public boolean accept(Object aValue) {
if (searchPatternTextField.getText() == null || searchPatternTextField.getText().length() == 0) {
return true;
}
if (aValue instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) aValue;
Enumeration<DefaultMutableTreeNode> children = node.children();
while (children.hasMoreElements()) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) children.nextElement();
if (accept(child)) {
return true;
}
}
try {
Pattern searchPattern = Pattern.compile(searchPatternTextField.getText());
return searchPattern.matcher(node.toString()).find();
} catch (PatternSyntaxException ex) {
return true;
}
}
return false;
}
});
mb.add(searchPatternTextField);
setJMenuBar(mb);
getContentPane().add(jScrollPane1);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
searchPatternTextField.addKeyListener(new KeyAdapter() {
private int nthMatch = 0;
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
if (e.isShiftDown()) {
nthMatch--;
} else {
nthMatch++;
}
}
try {
Pattern searchPattern = Pattern.compile(searchPatternTextField.getText());
List<TreeNode> matchingNodes = treeMdl.findNodesMatchingPattern(searchPattern);
if (matchingNodes.size() > 0) {
if (nthMatch >= matchingNodes.size()) {
nthMatch = 0;
}
if (nthMatch < 0) {
nthMatch = 0;
}
TreeNode matchingNode = matchingNodes.get(nthMatch);
renderData.setCurrentMatch(matchingNode);
TreePath matchingNodePath = new TreePath(((DefaultMutableTreeNode) matchingNode).getPath());
outline.expandPath(matchingNodePath);
outline.scrollRectToVisible(outline.getPathBounds(matchingNodePath));
renderData.setSearchPattern(searchPatternTextField.getText());
}
} catch (PatternSyntaxException ex) {
}
//outline.repaint();
treeMdl.nodeChanged(treeMdl.getRoot());
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new MainFrame();
}
});
}
}
作为一个基本场景,我通过按 Enter 反复查找“test”。每当单击某一列进行排序时,搜索结果的顺序就会困惑。Outline中有2个继承的方法convertRowIndexToModel和convertRowIndexToView似乎做了索引映射,但我不知道如何使用它们。
最佳答案
每当搜索字段发生变化时,只需通知渲染器新的搜索模式即可。这将处理键入时以黄色突出显示的部分:
searchPatternTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
renderData.setSearchPattern(searchPatternTextField.getText());
treeMdl.nodeChanged(treeMdl.getRoot());
}
@Override
public void insertUpdate(DocumentEvent e) {
renderData.setSearchPattern(searchPatternTextField.getText());
treeMdl.nodeChanged(treeMdl.getRoot());
}
@Override
public void changedUpdate(DocumentEvent e) {
renderData.setSearchPattern(searchPatternTextField.getText());
treeMdl.nodeChanged(treeMdl.getRoot());
}
});
然后监听 Enter 和 Shift+Enter。只需在 View 中查找上一个、当前和下一个匹配节点:
searchPatternTextField.addKeyListener(new KeyAdapter() {
private void showMatchingNode(TreeNode node) {
renderData.setCurrentMatch(node);
TreePath matchingNodePath = new TreePath(((DefaultMutableTreeNode) node).getPath());
outline.expandPath(matchingNodePath);
outline.scrollRectToVisible(outline.getPathBounds(matchingNodePath));
}
public TreeNode findNextMatchingNode(boolean lookForPrevious) {
try {
Pattern searchPattern = Pattern.compile(searchPatternTextField.getText());
boolean currentMatchFound = false;
TreeNode previousMatch = null;
for (int i = 0; i < outline.getRowCount(); i++) {
TreeNode node = (TreeNode) outline.getValueAt(i, 0);
if (node == renderData.getCurrentMatch()) {
currentMatchFound = true;
if (previousMatch != null && lookForPrevious) {
return previousMatch;
}
} else if (searchPattern.matcher(node.toString()).find()) {
if (renderData.getCurrentMatch() == null || (currentMatchFound && !lookForPrevious)) {
return node;
}
previousMatch = node;
}
}
} catch (PatternSyntaxException ex) {
}
return null;
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
TreeNode node = findNextMatchingNode(e.isShiftDown());
if (node != null) {
showMatchingNode(node);
}
treeMdl.nodeChanged(treeMdl.getRoot());
}
}
});
关于java - 排序后,如何在 Netbeans swing 大纲(树表)中保持搜索结果一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54476528/
我正在尝试对每个条目有多个值的关联数组进行排序。 例如 [0] => stdClass Object ( [type] => node [sid] => 158 [score] => 0.059600
我在 mysql 中有“日期”列以这种格式保存日期 2014 年 9 月 17 日(日-月-年) 我需要对它们进行升序排序,所以我使用了这个命令: SELECT * FROM table ORDER
我目前正在将 MySQL 存储过程重写为 MS SQL 存储过程,但遇到了问题。 在 MySQL 存储过程中,有一个游标,它根据最近的日期 (effdate) 选择一个值并将其放入变量 (thestt
我想要 gwt r.QuestionId- 排序。但是我得到未排序的 QuestionId 尽管我提到了 QuestionId ASC 的顺序。 SELECT r.QuestionId,
我有一个关于在 scandir 函数中排序的基本问题。到目前为止,我阅读了 POSIX readdir 的手册页,但没有找到有关订购保证的具体信息。 但是当我遍历大目录(无法更改,只读)时,我在多个系
基本上我必须从 SQL 数据库中构建项目列表,但是用户可以选择对 7 个过滤器的任意组合进行过滤,也可以选择要排序的列以及按方向排序。 正如您可以想象的那样,这会以大量不同的组合进行编码,并且数据集非
我有两张 table 。想象第一个是一个目录,包含很多文件(第二个表)。 第二个表(文件)包含修改日期。 现在,我想选择所有目录并按修改日期 ASC 对它们进行排序(因此,最新的修改最上面)。我不想显
我想先根据用户的状态然后根据用户名来排序我的 sql 请求。该状态由 user_type 列设置: 1=活跃,2=不活跃,3=创始人。 我会使用此请求来执行此操作,但它不起作用,因为我想在“活跃”成员
在 C++ 中,我必须实现一个“类似 Excel/Access”(引用)的查询生成器,以允许对数据集进行自定义排序。如果您在 Excel 中使用查询构建器或 SQL 中的“ORDER BY a, b,
我面临这样的挑战: 检索按字段 A 排序的文档 如果字段 B 存在/不为空 . 否则 按字段排序 C. 在 SQL 世界中,我会做两个查询并创建一个 UNION SELECT,但我不知道如何从 Mon
我想对源列表执行以下操作: map 列表 排序 折叠 排序 展开 列表 其中一些方法(例如map和toList)是可链接的,因为它们返回非空对象。但是,sort 方法返回 void,因为它对 List
我制作了一个用于分析 Windows 日志消息编号的脚本。 uniq -c 数字的输出很难预测,因为根据数字的大小会有不同的空白。此时,我手动删除了空白。 这是对消息进行排序和计数的命令: cat n
我有以下词典: mydict1 = {1: 11, 2: 4, 5: 1, 6: 1} mydict2 = {1: 1, 5: 1} 对于它们中的每一个,我想首先按值(降序)排序,然后按键(升序)排序
我刚刚开始使用泛型,目前在对多个字段进行排序时遇到问题。 案例: 我有一个 PeopleList 作为 TObjectList我希望能够通过一次选择一个排序字段,但尽可能保留以前的排序来制作类似 Ex
有没有办法在 sql 中组合 ORDER BY 和 IS NULL 以便我可以在列不为空时按列排序,但如果它为null,按另一列排序? 最佳答案 类似于: ORDER BY CASE WHEN
我有一个包含 2 列“id”和“name”的表。 id 是常规的自动增量索引,name 只是 varchar。 id name 1 john 2 mary 3 pop 4 mary 5 j
场景 网站页面有一个带有分页、过滤、排序功能的表格 View 。 表中的数据是从REST API服务器获取的,数据包含数百万条记录。 数据库 REST API 服务器 Web 服务器 浏览器 问
假设我有一本字典,其中的键(单词)和值(分数)如下: GOD 8 DONG 16 DOG 8 XI 21 我想创建一个字典键(单词)的 NSArray,首先按分数排序,然后按字
如何在 sphinx 上通过 sql 命令选择前 20 行按标题 WEIGHT 排序,接下来 20 行按标题 ASC 排序(总共 40 个结果),但不要给出重复的标题输出。 我尝试了这个 sql 命令
我有一个奇怪的问题,当从 SQLite 数据库中选择信息并根据日期排序时,返回的结果无效。 我的SQL语句是这样的: Select pk from usersDates order by dateti
我是一名优秀的程序员,十分优秀!