Фильтр JTable - заменить иностранные символы

этот код ниже работает для фильтрации JTable, пока я не использую английский алфавит. Он также не чувствителен к регистру. Моя цель - отфильтровать пробелы и иностранные символы. Мне нужно как-то заменить символы в игле и в стоге сена, например č,ľ,ť,ž,ý,á заменить на c,l,t,z,y,a. У кого-нибудь есть опыт или рабочий код для моего запроса? Заранее спасибо.

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                   
}

person mesnicka    schedule 22.12.2014    source источник
comment
Вы читали официальный учебник Oracle Как использовать таблицы - фильтрация и сортировка для примера рабочего кода, не так ли ...   -  person mKorbel    schedule 22.12.2014
comment
Я читаю больше, чем учебник. К сожалению, мой уровень Java очень низок, и я не нашел решения своей проблемы в учебнике.   -  person mesnicka    schedule 22.12.2014
comment
(Я читал больше, чем учебник.) Пример рабочего кода использует DocumentListener для JTextField вместо (ваше неправильное решение, никогда не использовать для JTextComponents) KeyListener, начните там   -  person mKorbel    schedule 22.12.2014


Ответы (3)


Как отметил @mKorbel:

  • Не используйте KeyListener (плохой подход), а вместо этого DocumentListener для слушайте изменения текста текстового поля.
  • TableModel по-прежнему содержит текст с иностранные символы, поэтому вы должны учитывать этот факт при применении фильтра.

Сказав это, я бы сделал следующее:

  • Имейте метод для применения фильтра к вашей таблице на основе строки.
  • Прикрепите DocumentListener к текстовому полю, чтобы вызвать этот метод.
  • Используйте Normalizer, как уже предлагалось, чтобы присоединить фильтр строк к сортировщику строк таблицы, который учитывает как исходное текстовое значение записи, так и его нормализованное строковое представление.

Пример

Вот MCVE, с которым можно поиграть.

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();
            }
        });
    }

}
person dic19    schedule 22.12.2014
comment
Это именно то, что я себе представлял. Большое спасибо! - person mesnicka; 22.12.2014

Вы можете использовать java.text.Normalizer.

Например :

  String plain = "č,ľ,ť,ž,ý,á";
  plain = Normalizer.normalize(plain, Normalizer.Form.NFD);
  String clean = plain.replaceAll("[^\\x00-\\x7F]", "");
  System.out.println(clean);
  // Will output c,l,t,z,y,a

Первые шаги заменяют символ:

U+010D LATIN SMALL LETTER C WITH CARON

По своей «разложившейся форме»:

U+0063 LATIN SMALL LETTER C
U+030C COMBINING CARON

Второй шаг удаляет все символы, отличные от ascii.

person obourgain    schedule 22.12.2014
comment
Я знаю, как использовать это для иглы (строка из JTextField). Но как я могу применить это к стогу сена (строкам из JTable)? - person mesnicka; 22.12.2014
comment
но в модели хранятся символы в виде č,ľ,ť,ž,ý,á, здесь не так - person mKorbel; 22.12.2014
comment
1+ для использования нормализатора и очистки символов, отличных от ASCII. Очень полезно. - person dic19; 22.12.2014

Как я могу применить это к строкам из JTable?

Примените подход, показанный здесь в пользовательском TableCellRenderer, как обсуждалось здесь.

person trashgod    schedule 22.12.2014