gpt4 book ai didi

java - 突出显示用于 JTable 过滤的表单元格中的子字符串

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:16:30 24 4
gpt4 key购买 nike

如何同步输入到 JTextField 中的文本(然后通过 DocumentListenerString 传递给 RowFilter)如果包含与 JTextField/Document 中的字符串值相同的 TableCell

然后在同步 TableCell(s)

中突出显示(意味着更改文本 Color.Red)相同的文本

我知道通过使用一些 hack 是可能的

1/通过使用 getTableCellRendererComponent

2/使用prepareRenderer

还有其他可能正确的方法吗

JTable教程中的一点修改代码

import java.awt.*;
import java.util.regex.PatternSyntaxException;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class TableFilterSorter extends JPanel {

private boolean DEBUG = false;
private static final long serialVersionUID = 1L;

public TableFilterSorter() {
super(new BorderLayout(5, 5));
final JTextField filterCpText = new JTextField();
filterCpText.setFont(new Font("Serif", Font.BOLD, 28));
filterCpText.setForeground(Color.BLUE);
filterCpText.setBackground(Color.LIGHT_GRAY);
JPanel filterCpPanel = new JPanel();
filterCpPanel.setLayout(new BorderLayout(5, 5));
filterCpPanel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
filterCpPanel.setBackground(Color.LIGHT_GRAY);
filterCpPanel.setPreferredSize(new Dimension(300, 30));
filterCpPanel.add(filterCpText, BorderLayout.CENTER);
add(filterCpPanel, BorderLayout.NORTH);
final JTable table = new JTable(new MyTableModel());
table.setPreferredScrollableViewportSize(new Dimension(500, 160));
table.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane, BorderLayout.CENTER);
TableModel myTableModel = table.getModel();
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(myTableModel);
table.setRowSorter(sorter);
filterCpText.getDocument().addDocumentListener(new DocumentListener() {

private void searchFieldChangedUpdate(DocumentEvent evt) {
String text = filterCpText.getText();
if (text.length() == 0) {
sorter.setRowFilter(null);
table.clearSelection();
} else {
try {
sorter.setRowFilter(RowFilter.regexFilter("(?i)" + text, 4));
table.clearSelection();
} catch (PatternSyntaxException pse) {
JOptionPane.showMessageDialog(null, "Bad regex pattern",
"Bad regex pattern", JOptionPane.ERROR_MESSAGE);
}
}
}

@Override
public void insertUpdate(DocumentEvent evt) {
searchFieldChangedUpdate(evt);
}

@Override
public void removeUpdate(DocumentEvent evt) {
searchFieldChangedUpdate(evt);
}

@Override
public void changedUpdate(DocumentEvent evt) {
searchFieldChangedUpdate(evt);
}
});
}

private class MyTableModel extends AbstractTableModel {

private static final long serialVersionUID = 1L;
private String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
private Object[][] data = {
{"Mary", "Campione", "Snowboarding", new Integer(5), false},
{"Alison", "Huml", "Rowing", new Integer(3), true},
{"Kathy", "Walrath", "Knitting", new Integer(2), false},
{"Sharon", "Zakhour", "Speed reading", new Integer(20), true},
{"Philip", "Milne", "Pool", new Integer(10), false},
{"Mary", "Campione", "Snowboarding", new Integer(5), false},
{"Alison", "Huml", "Rowing", new Integer(3), true},
{"Kathy", "Walrath", "Knitting", new Integer(2), false},
{"Sharon", "Zakhour", "Speed reading", new Integer(20), true},
{"Philip", "Milne", "Pool", new Integer(10), false},};

@Override
public int getColumnCount() {
return columnNames.length;
}

@Override
public int getRowCount() {
return data.length;
}

@Override
public String getColumnName(int col) {
return columnNames[col];
}

@Override
public Object getValueAt(int row, int col) {
return data[row][col];
}

@Override
public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}

@Override
public boolean isCellEditable(int row, int col) {
if (col < 2) {
return false;
} else {
return true;
}
}

@Override
public void setValueAt(Object value, int row, int col) {
if (DEBUG) {
System.out.println("Setting value at " + row + "," + col
+ " to " + value + " (an instance of " + value.getClass() + ")");
}
data[row][col] = value;
fireTableCellUpdated(row, col);
if (DEBUG) {
System.out.println("New value of data:");
printDebugData();
}
}

private void printDebugData() {
int numRows = getRowCount();
int numCols = getColumnCount();
for (int i = 0; i < numRows; i++) {
System.out.print(" row " + i + ":");
for (int j = 0; j < numCols; j++) {
System.out.print(" " + data[i][j]);
}
System.out.println();
}
System.out.println("--------------------------");
}
}

private static void createAndShowGUI() {
JFrame frame = new JFrame("TableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TableFilterSorter newContentPane = new TableFilterSorter();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.setLocation(150, 150);
frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
createAndShowGUI();
}
});
}
}

最佳答案

JXTable 可以通过 Highlighter 做到这一点 - 示例请参见 swinglabs-demos(搜索演示中的 MatchingTextHighlighter) - Painter 应用了背景高亮。

您可以在渲染器的某处手动执行类似的操作。如果使用 JLabel 作为 renderingComponent,您基本上必须找到需要背景突出显示的文本部分并为该区域绘制背景(下面是用于查找区域的代码片段,来自演示示例的 c&p)。或者,您可能会考虑使用 JTextField 作为渲染组件:优点是内置了 Highlighter(来自 javax.swing.text),缺点是文本组合作为渲染器的常见问题 ;-)

/**
* Finds the rectangles that contain rendered characters that match the
* pattern.
*
* @param object an optional configuration parameter. This may be null.
* @param width width of the area to paint.
* @param height height of the area to paint.
* @return a <code>List</code> of <code>Rectangle</code>s marking characters
* to highlight
*/
protected List<Rectangle> findHighlightAreas(JLabel object, int width,
int height) {
String text = object.getText();

insets = object.getInsets(insets);

viewR.x = 0 + insets.left;
viewR.y = 0 + insets.bottom;
viewR.width = width - insets.right;
viewR.height = height - insets.top;

// Reset the text and view rectangle x any y coordinates.
// These are not set to 0 in SwingUtilities.layoutCompoundLabel
iconR.x = iconR.y = 0;
textR.x = textR.y = 0;

FontMetrics fm = object.getFontMetrics(object.getFont());
String clippedText = SwingUtilities.layoutCompoundLabel(object, fm,
text, object.getIcon(), object.getVerticalAlignment(), object
.getHorizontalAlignment(), object
.getVerticalTextPosition(), object
.getHorizontalTextPosition(), viewR, iconR, textR,
object.getIconTextGap());

int xOffset = calculateXOffset(object, viewR, textR);

String textToSearch = clippedText;
// Check to see if the text will be clipped
if (!object.getText().equals(clippedText)) {
// TODO There has to be a better way that assuming ellipses
// are the last characters of the text
textToSearch = clippedText.substring(0, clippedText.length() - 3);
}

return createHighlightAreas(textToSearch, fm, xOffset, height);
}

/**
* Creates the rectangles that contain matched characters in the given text.
*
* @param text the text to search
* @param fm the font metrics of the rendered font
* @param xOffset the x offset at which text rendering starts
* @param height the height of painted highlights
* @return a <code>List</code> of highlight areas to paint
*/
protected List<Rectangle> createHighlightAreas(String text, FontMetrics fm,
int xOffset, int height) {
SearchPredicate predicate = (SearchPredicate) getHighlightPredicate();
Matcher matcher = predicate.getPattern().matcher(text);

List<Rectangle> highlightAreas = null;
int startFrom = 0;
while (startFrom < text.length() && matcher.find(startFrom)) {
if (highlightAreas == null) {
highlightAreas = new ArrayList<Rectangle>();
}

int start = matcher.start();
int end = matcher.end();

if (start == end) {
// empty matcher will cause infinite loop
break;
}

startFrom = end;

int highlightx;
int highlightWidth;

if (start == 0) {
// start highlight from the start of the field
highlightx = textR.x + xOffset;
} else {
// Calculate the width of the unhighlighted text to
// get the start of the highlighted region.
String strToStart = text.substring(0, start);
highlightx = textR.x + fm.stringWidth(strToStart) + xOffset;
}

// Get the width of the highlighted region
String highlightText = text.substring(start, end);
highlightWidth = fm.stringWidth(highlightText);

highlightAreas.add(new Rectangle(highlightx, 0, highlightWidth,
height));
}

if (highlightAreas == null) {
highlightAreas = Collections.emptyList();
} else {
coalesceHighlightAreas(highlightAreas);
}
return highlightAreas;
}

/**
* Joins highlight rectangles that mark adjacent horizontal areas into
* single rectangles. This is useful to renderers that vary horizontally,
* such a horizontal gradient - the gradient will not restart when there are
* two adjacent highlight areas.
*
* @param highlightAreas a <code>List</code> of <code>Rectangle</code>s.
*/
protected void coalesceHighlightAreas(List<Rectangle> highlightAreas) {
Collections.sort(highlightAreas, X_AXIS_RECTANGLE_COMPARATOR);

int i = 0;
while (i < highlightAreas.size() - 1) {
Rectangle r1 = highlightAreas.get(i);
Rectangle r2 = highlightAreas.get(i + 1);

if (r1.x + r1.width == r2.x) {
r1.width += r2.width;
highlightAreas.remove(i + 1);
} else {
i++;
}
}
}

/**
* Calculates the x offset of highlights based on component orientation and
* text direction.
*
* @param component the renderer component
* @param viewR the view rectangle of the renderer component
* @param textR the text rectangle of the renderer component
* @return the number of pixels to offset the highlight from the left edge
* of the component
*/
protected int calculateXOffset(JLabel component, Rectangle viewR,
Rectangle textR) {
int horizAlignment = component.getHorizontalAlignment();
boolean leftToRight = component.getComponentOrientation()
.isLeftToRight();

if (horizAlignment == SwingConstants.LEFT
|| (horizAlignment == SwingConstants.LEADING && leftToRight)
|| (horizAlignment == SwingConstants.TRAILING && !leftToRight)) {
return 0;
} else if (horizAlignment == SwingConstants.RIGHT
|| (horizAlignment == SwingConstants.TRAILING && !leftToRight)
|| (horizAlignment == SwingConstants.LEADING && leftToRight)) {
return viewR.width - textR.width;
} else if (horizAlignment == SwingConstants.CENTER) {
return (viewR.width - textR.width) / 2;
}
throw new AssertionError("Unknown horizonal alignment "
+ horizAlignment);
}

关于java - 突出显示用于 JTable 过滤的表单元格中的子字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6410839/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com