Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
245 views
in Technique[技术] by (71.8m points)

java - JTable filter - replace foreign characters

this code below works for filtering JTable until I use english alphabet. It is also not case-sensitive. My goal is to filter white spaces and foreign characters. I need to replace characters in needle and in haystack somehow, for example ?,?,?,?,y,á replace with c,l,t,z,y,a. Does anybody have experience or working code for my request? Thanks in advance.

import javax.swing.RowFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class Home extends javax.swing.JFrame {
  DefaultTableModel model;
  TableRowSorter sorter;

  public Home() {
    initComponents();
    model = (DefaultTableModel) jTable1.getModel();
    model.setRowCount(0);
    String data[] = {"?ing","?amg","búng","wámg","fáng","raňk","moňk","pú?k","?ank","dung","puck","rig","an da da","ku nd ada","c ic inada"};
    for(int i=0;i<data.length;i++) {
      model.addRow(new Object[] {
        data[i]
      });
    }
    sorter = new TableRowSorter<TableModel>(model);
    jTable1.setRowSorter(sorter);
  }

  private void initComponents() {///}                        

  private void jTextField1KeyReleased(java.awt.event.KeyEvent evt) {                                        

    String text = jTextField1.getText();
    if(text.length() == 0) {
      sorter.setRowFilter(null);
    } else {
      sorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
    }
  }                                       

  public static void main(String args[]) {///}

  // Variables declaration - do not modify                     
  private javax.swing.JLabel jLabel1;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JTable jTable1;
  private javax.swing.JTextField jTextField1;
  // End of variables declaration                   
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

As @mKorbel pointed out:

  • Don't use KeyListener (bad approach) but DocumentListener instead to listen for text field's text changes.
  • The TableModel still contains the text with foreign characters, so you should take this fact into account when you apply your filter.

Having said that, this is what I'd do:

  • Have a method to apply a filter on your table based on a string.
  • Attach a DocumentListener to the text field in order to call that method.
  • Use Normalizer, as already suggested, in order to attach a row filter to the table's row sorter that takes into account both the original entry text value and its normalized string representation.

Example

Here's an MCVE to play with.

import java.awt.BorderLayout;
import java.text.Normalizer;
import javax.swing.BorderFactory;
import javax.swing.DefaultRowSorter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

/**
 * @author dic19
 */
public class Demo {

    private JTable table;
    private JTextField textField;

    private void createAndShowGui() {

        textField = new JTextField(20);
        textField.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void removeUpdate(final DocumentEvent e) {
                Demo.this.filterTable(textField.getText());
            }

            @Override
            public void insertUpdate(final DocumentEvent e) {
                Demo.this.filterTable(textField.getText());
            }

            @Override
            public void changedUpdate(final DocumentEvent e) {
                Demo.this.filterTable(textField.getText());
            }
        });

        String[] header = new String[] {"Foreign text", "English text"};
        DefaultTableModel model = new DefaultTableModel(header, 0) {
            @Override
            public Class<?> getColumnClass(int columnIndex) {
                return String.class;
            }
        };

        model.addRow(new Object[]{"?ing", "wamg"});
        model.addRow(new Object[]{"?amg", "bung"});
        model.addRow(new Object[]{"búng", "sing"});
        model.addRow(new Object[]{"wámg", "camg"});

        table = new JTable(model);
        table.setAutoCreateRowSorter(true);

        JPanel filterPanel = new JPanel();
        filterPanel.add(new JLabel("Filter text:"));
        filterPanel.add(textField);

        JPanel content = new JPanel(new BorderLayout(8, 8));
        content.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
        content.add(filterPanel, BorderLayout.PAGE_START);
        content.add(new JScrollPane(table), BorderLayout.CENTER);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(content);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

    }

    private void filterTable(final String query) {

        RowFilter<TableModel, Integer> filter = null;

        if (query.length() > 0) {
            filter = new RowFilter<TableModel, Integer>() {
                @Override
                public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {

                    // Normalize the query string.
                    String normalizedQuery = Normalizer.normalize(query, Normalizer.Form.NFD);
                    normalizedQuery = normalizedQuery.replaceAll("[^\x00-\x7F]", "");

                    for (int i = 0; i < entry.getValueCount(); i++) {
                       // Get both the string value and its normalized string
                       String stringValue = entry.getStringValue(i);
                       String normalizedStringValue = Normalizer.normalize(stringValue, Normalizer.Form.NFD);
                       normalizedStringValue = normalizedStringValue.replaceAll("[^\x00-\x7F]", "");

                       // Two cases need to be evaluated here:
                       // 1. The normalized string value contains the normalized query string.
                       // 2. The string value contains the query string.
                       if (normalizedStringValue.contains(normalizedQuery) || stringValue.contains(query)) {
                           return true;
                       }
                   }
                   return false;
                }

            };
        }
        ((DefaultRowSorter)table.getRowSorter()).setRowFilter(filter);
    }

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

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...