java - 更改搜索值时刷新/更新 JTable 中的荧光笔

标签 java swing jtable jtextarea swing-highlighter

更改 JTextField 中的搜索值后,如何刷新 JTable 中的荧光笔?它与 JTextfield 下的 JTextArea 一起工作正常,但我 JTable 不会刷新荧光笔。有什么建议吗??

这是我的代码:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.*;
import javax.swing.text.DefaultHighlighter.DefaultHighlightPainter;

public class BeispielTabelle {
JTextField field;
JTextArea textFeld = new JTextArea("Hello World!");
String input="Stefan";

//Titel der Tabelle
String[] title = {"EINS", "ZWEI", "DREI"}; 

//Tabellendaten
Object[][] playerdata = {       
{"34", "Stefan", "Mein Name ist Stefan"},
{"32", "Dirk", "Ich bin der Dirk"},
{"99", "Patrick", "Ich heisse Patrick"},
{"100", "Anna", "Ich bin die Anna"},};

//TableModel
DefaultTableModel model = new DefaultTableModel(playerdata,title);

//Tabelle erstellen
JTable textTable = new JTable(model);    

public JPanel erstelleTabelle() {               
    JPanel totalGUI = new JPanel();    
    //CellRenderer
    SearchRenderer cellRenderer = new SearchRenderer();


    //Spaltenbreiten festlegen
    textTable.setDefaultRenderer(String.class, cellRenderer);
    textTable.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);
    textTable.getColumnModel().getColumn(1).setCellRenderer(cellRenderer);    
    textTable.getColumnModel().getColumn(2).setCellRenderer(cellRenderer);

    textTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // Autoresizing abschalten, sonst sind alle Spalten gleich breit:
    textTable.getColumnModel().getColumn(0).setPreferredWidth(60);
    textTable.getColumnModel().getColumn(1).setPreferredWidth(60);
    textTable.getColumnModel().getColumn(2).setPreferredWidth(180);       

    //das Ganze scrollbar machen
    JScrollPane scrollPane = new JScrollPane(textTable);

    //TextFeld erstellen
    field = new JTextField();
    field.addActionListener(new ActionListener () {
        @Override
        public void actionPerformed(ActionEvent e) {
            input = field.getText();
            System.out.println(input);
            //updateRowHeights();
            highlightText();
        }
    });        

    totalGUI.add(scrollPane);  
    totalGUI.add(field);
    totalGUI.add(textFeld);        
    return totalGUI;
}

void highlightText() {
    DefaultHighlightPainter yellowPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
    Highlighter highlighter = textFeld.getHighlighter();
    highlighter.removeAllHighlights();      
    String text = textFeld.getText();
    String pattern = input;
    int index = text.indexOf(pattern);      
    while ( index >= 0 ) {
        int len = pattern.length();
        try {
            highlighter.addHighlight(index, index+len, yellowPainter);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
        index = text.indexOf(pattern, index+len);
    }
}

private static void createAndShowGUI() {

    //create main frame
    JFrame mainFrame = new JFrame("");
    BeispielTabelle test = new BeispielTabelle();

    JPanel totalGUI = new JPanel();
    totalGUI = test.erstelleTabelle();
    totalGUI.setLayout(new BoxLayout(totalGUI, BoxLayout.Y_AXIS));

    //visible mode
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainFrame.add(totalGUI); //integrate main panel to main frame
    mainFrame.pack();
    mainFrame.setVisible(true);     
}


public static void main (String[] args) {               

    createAndShowGUI();     

}//main
}//GUI_main

这是我的 SearchRenderer

import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.BadLocationException;

import java.awt.*;

public class SearchRenderer extends JTextArea implements TableCellRenderer {

/**
 * 
 */
private static final long serialVersionUID = 1L;
public SearchRenderer() {}//constructor
BeispielTabelle tabelle = new BeispielTabelle();
String textForSearch=tabelle.input;

@Override
public Component getTableCellRendererComponent (JTable table,
                                                Object value,
                                                boolean isSelected,
                                                boolean hasFocus,
                                                int row,                    
                                                int column ) {  
    this.setText((String) value);
    if(value != null) {
        String string = value.toString();
        if(string.contains(textForSearch)){
            int indexOf = string.indexOf(textForSearch);
            while(indexOf >=0) {
            try {
                      this.getHighlighter().addHighlight(indexOf,indexOf+textForSearch.length(),new javax.swing.text.DefaultHighlighter.DefaultHighlightPainter(Color.GREEN));
            } catch (BadLocationException e) {
                e.printStackTrace();
            }
            indexOf = string.indexOf(textForSearch, indexOf+textForSearch.length());
        }
    }
    } else {
        this.setText("");
        this.getHighlighter().removeAllHighlights();
    }
    return this;
}
}

最佳答案

也许你可以使用JTable#repaint()

enter image description here

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

public final class SearchRendererTest {
  private final JTextField field = new JTextField("Stefan");
  private final SearchRenderer renderer = new SearchRenderer();

  //Titel der Tabelle
  private final String[] title = {"EINS", "ZWEI", "DREI"};

  //Tabellendaten
  private final Object[][] playerdata = {
    {"34", "Stefan", "Mein Name ist Stefan"},
    {"32", "Dirk", "Ich bin der Dirk"},
    {"99", "Patrick", "Ich heisse Patrick"},
    {"100", "Anna", "Ich bin die Anna"},
  };
  private final TableModel model = new DefaultTableModel(playerdata, title);
  private final JTable table = new JTable(model);

  public JComponent makeUI() {
    table.setDefaultRenderer(Object.class, renderer);
    field.getDocument().addDocumentListener(new DocumentListener() {
      @Override public void insertUpdate(DocumentEvent e) {
        fireDocumentChangeEvent();
      }
      @Override public void removeUpdate(DocumentEvent e) {
        fireDocumentChangeEvent();
      }
      @Override public void changedUpdate(DocumentEvent e) {
        /* not needed */
      }
    });
    fireDocumentChangeEvent();

    JPanel sp = new JPanel(new BorderLayout(5, 5));
    sp.add(new JLabel("regex pattern:"), BorderLayout.WEST);
    sp.add(field);
    sp.add(Box.createVerticalStrut(2), BorderLayout.SOUTH);
    sp.setBorder(BorderFactory.createTitledBorder("Search"));

    JPanel p = new JPanel(new BorderLayout(5, 5));
    p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    p.add(sp, BorderLayout.NORTH);
    p.add(new JScrollPane(table));
    return p;
  }

  private void fireDocumentChangeEvent() {
    String pattern = field.getText().trim();
    renderer.setPattern(pattern);
    table.repaint();
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }

  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new SearchRendererTest().makeUI());
    f.pack();
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

class SearchRenderer implements TableCellRenderer {
  private static final Color BACKGROUND_SELECTION_COLOR = new Color(220, 240, 255);
  private final transient Highlighter.HighlightPainter highlightPainter
    = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
  private final JTextField field = new JTextField();
  private String pattern = "";
  private String prev;

  public boolean setPattern(String str) {
    if (str == null || str.equals(pattern)) {
      return false;
    } else {
      prev = pattern;
      pattern = str;
      return true;
    }
  }
  public SearchRenderer() {
    super();
    field.setOpaque(true);
    field.setBorder(BorderFactory.createEmptyBorder());
    field.setForeground(Color.BLACK);
    field.setBackground(Color.WHITE);
    field.setEditable(false);
  }
  @Override public Component getTableCellRendererComponent(
    JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    String txt = Objects.toString(value, "");
    Highlighter highlighter = field.getHighlighter();
    highlighter.removeAllHighlights();
    field.setText(txt);
    field.setBackground(isSelected ? BACKGROUND_SELECTION_COLOR : Color.WHITE);
    if (pattern != null && !pattern.isEmpty() && !pattern.equals(prev)) {
      Matcher matcher = Pattern.compile(pattern).matcher(txt);
      if (matcher.find()) {
        int start = matcher.start();
        int end   = matcher.end();
        try {
          highlighter.addHighlight(start, end, highlightPainter);
        } catch (BadLocationException e) {
          e.printStackTrace();
        }
      }
    }
    return field;
  }
}

关于java - 更改搜索值时刷新/更新 JTable 中的荧光笔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22221587/

相关文章:

java - 当我从 Git Bash 在 VS Code 中执行 pytest 时,本地 pyspark 出现错误

java - swing中的多线程渲染

java - 如何将值从文本字段传递到对象或文件(可序列化文件)?

java - 如何正确使用TableCellRenderer对单元格进行颜色匹配

java - 在Java中从结构化原始文件创建json文件的最简单方法?

java - 使用带有乐观锁定的 JPA 更新 n 条记录

java - 如何区分 Ajax 请求和普通的 Http 请求?

java - 如何使用 SwingX 的荧光笔返回不同的渲染器组件?

java - JTable 无法更改第一列的颜色

java - 自动增量字段不显示在 JTable 首次显示中