0

I have a JTable with 3 columns and the second column has ImageIcons. I want to filter that column only by the name of the image, but there is a problem: the content of that column is the full path of the image and if I enter a word/letter which is in the path, I receive all records.

For example

This is my jTabel with getColumnClass: enter image description here

and this is without getColumnClass: enter image description here

If I enter "resource" in Enter value field nothing changes, because all cells have this content.

Is there any method to filter only by image name without extension (e.g. orange, vodafone, cosmote)?

Below is my code :

package main;

import javax.swing.DefaultCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

@SuppressWarnings("serial")
public class PhoneBook extends JFrame {

        private JPanel panel1;
        private static ImageIcon frameIcon = new ImageIcon("resources/appIcons/icon.png");
        private JComboBox<String> comboBox;
        private JComboBox<String> filterColumnBox;     
        private MyTableModel model;
        private static ArrayList<String> phoneNumberList = new ArrayList<String>();    
        private String filterValue;
        private int sortColumn;

        public PhoneBook(String group) {

        setDesign(group);        
    }

        /**
         * Set column filter
         */
    private void setColumnIndex() {
        try
        {
                if(filterColumnBox.getSelectedItem().equals("Name")) {
                        sortColumn = 0;
                }
                else if(filterColumnBox.getSelectedItem().equals("Operator")) {
                        sortColumn = 1;
                }
                else {
                        sortColumn = 2;  
                }

                System.out.println("Functia setColumnIndex: " + filterColumnBox.getSelectedItem() + " " + sortColumn);
        } catch (Exception e)
        {
                System.out.println("Exceptie: " + e.getMessage());
        }
    }

    /**
     *  Add phone numbers to ComboBox
     * @param cbColumn
     */
        private void comboBoxColumn(TableColumn cbColumn) {  

                getNumbers();

                comboBox = new JComboBox<String>();
        for (String c : phoneNumberList) {
                comboBox.addItem(c);
        }
        cbColumn.setCellEditor(new DefaultCellEditor(comboBox));

        DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
        renderer.setToolTipText("Click for numbers");
        cbColumn.setCellRenderer(renderer);
        }

        /**
         * Get phone number and add into phoneNumberList
         */
        public void getNumbers() {
                phoneNumberList.add("0733333333");
                phoneNumberList.add("0744444444");
        }

        /**
         * Extends AbstractTableModel for table model
         */
    class MyTableModel extends AbstractTableModel {
        private String[] columnNames = {"Name",
                                        "Operator",
                                        "Numbers"};
        private Object[][] data = {
                    {"Kathy Smith", new ImageIcon("resources/opIcons/orange.png"), "0733333331"},
                    {"John Doe", new ImageIcon("resources/opIcons/vodafone.png"), "0733333332"},
                    {"Sue Black", new ImageIcon("resources/opIcons/vodafone.png"), "0733333333"},
                    {"Jane White", new ImageIcon("resources/opIcons/cosmote.png"), "0733333334"},
                    {"Jane White", new ImageIcon("resources/opIcons/cosmote.png"), "0733333335"},
                    {"Jane White", new ImageIcon("resources/opIcons/cosmote.png"), "0733333336"},
                    {"Joe Brown", new ImageIcon("resources/opIcons/orange.png"), "0733333337"}
        };

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

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

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

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

        /*public Class<?> getColumnClass(int column) {
            Class<?> returnValue;
            if ((column >= 0) && (column < getColumnCount())) {
                System.out.println("Functia getColumnClass: " + column);
              returnValue = getValueAt(0, column).getClass();
            } else {
              returnValue = Object.class;
            }
            return returnValue;
          }*/

        //For editable fields (ComboBox)
        public boolean isCellEditable(int row, int col) {
            if (col < 2) {
                return false;
            } else {
                return true;
            }
        }      

        //For changing values in ComboBox
        public void setValueAt(Object value, int row, int col) {  
            data[row][col] = value;
            fireTableCellUpdated(row, col);          
        }      
    }  

    /**
     * GUI design
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
        private void setDesign(String group) {

        setTitle("Phone Book Application - " + group);         
        setSize(600, 500);
        setIconImage(frameIcon.getImage());

        model = new MyTableModel();
        final JTable table = new JTable(model);
        table.setPreferredScrollableViewportSize(new Dimension(500, 200));
        table.setFillsViewportHeight(false);

        final TableRowSorter<MyTableModel> sorter = new TableRowSorter<MyTableModel>(model);
        table.setRowSorter(sorter);

        //Table row height
        table.setRowHeight(35);


        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //Render last column

        comboBoxColumn(table.getColumnModel().getColumn(2));

        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[]{600, 0};
                gridBagLayout.rowHeights = new int[]{280, 220, 0};
                gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
                gridBagLayout.rowWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
                setLayout(gridBagLayout);

        GridBagConstraints gbc_scrollPaneTable = new GridBagConstraints();
                gbc_scrollPaneTable.insets = new Insets(0, 0, 5, 0);
                gbc_scrollPaneTable.fill = GridBagConstraints.BOTH;
                gbc_scrollPaneTable.gridx = 0;
                gbc_scrollPaneTable.gridy = 0;

        add(scrollPane, gbc_scrollPaneTable);

        JScrollPane scrollPaneInfo = new JScrollPane();
                GridBagConstraints gbc_scrollPaneInfo = new GridBagConstraints();
                gbc_scrollPaneInfo.fill = GridBagConstraints.BOTH;
                gbc_scrollPaneInfo.gridx = 0;
                gbc_scrollPaneInfo.gridy = 1;
                add(scrollPaneInfo, gbc_scrollPaneInfo);

                panel1 = new JPanel();
                scrollPaneInfo.setViewportView(panel1);
                GridBagLayout gbl_panel = new GridBagLayout();
                gbl_panel.columnWidths = new int[]{150, 100, 100, 100, 150, 0};
                gbl_panel.rowHeights = new int[]{25, 25, 25, 25,25, 25,25, 25,20};
                gbl_panel.columnWeights = new double[]{1.0, 1.0, Double.MIN_VALUE};
                gbl_panel.rowWeights = new double[]{1.0, 1.0, 1.0, 1.0, 1.0, 1.0, Double.MIN_VALUE};

                panel1.setLayout(gbl_panel);

        JLabel filterColumnLbl = new JLabel("Choose a column");
        GridBagConstraints gbc_filterColumnLbl = new GridBagConstraints();
        //gbc_filterColumnLbl.fill = GridBagConstraints.VERTICAL;
        gbc_filterColumnLbl.anchor = GridBagConstraints.WEST;
        gbc_filterColumnLbl.insets = new Insets(5, 15, 0, 0);
        gbc_filterColumnLbl.gridx = 0;
        gbc_filterColumnLbl.gridy = 0;    
                panel1.add(filterColumnLbl, gbc_filterColumnLbl);


                String[] columnName = { "Name", "Operator", "Numbers" };
            filterColumnBox = new JComboBox(columnName);
        GridBagConstraints gbc_filterColumnBox = new GridBagConstraints();
        //gbc_filterColumnBox.fill = GridBagConstraints.VERTICAL;
        gbc_filterColumnBox.anchor = GridBagConstraints.WEST;
        gbc_filterColumnBox.insets = new Insets(5, 15, 0, 0);
        gbc_filterColumnBox.gridx = 1;
        gbc_filterColumnBox.gridy = 0;        
                panel1.add(filterColumnBox, gbc_filterColumnBox);              

        JLabel filterValueLbl = new JLabel("Enter value");
        GridBagConstraints gbc_filterValueLbl = new GridBagConstraints();
        //gbc_filterValueLbl.fill = GridBagConstraints.VERTICAL;
        gbc_filterValueLbl.anchor = GridBagConstraints.WEST;
        gbc_filterValueLbl.insets = new Insets(5, 15, 0, 0);
        gbc_filterValueLbl.gridx = 0;
        gbc_filterValueLbl.gridy = 1;        
                panel1.add(filterValueLbl, gbc_filterValueLbl);

        final JTextField filterValueTxt = new JTextField();
        GridBagConstraints gbc_filterValueTxt = new GridBagConstraints();
        //gbc_filterValueTxt.fill = GridBagConstraints.VERTICAL;
        gbc_filterValueTxt.anchor = GridBagConstraints.WEST;
        gbc_filterValueTxt.insets = new Insets(5, 15, 0, 0);
        gbc_filterValueTxt.gridx = 1;
        gbc_filterValueTxt.gridy = 1;        
                panel1.add(filterValueTxt, gbc_filterValueTxt);
                filterValueTxt.setColumns(10);


        JButton filterBtn = new JButton("Apply filter");
        GridBagConstraints gbc_filterBtn = new GridBagConstraints();
        //gbc_filterValueTxt.fill = GridBagConstraints.VERTICAL;
        gbc_filterBtn.anchor = GridBagConstraints.WEST;
        gbc_filterBtn.insets = new Insets(5, 15, 0, 0);
        gbc_filterBtn.gridx = 0;
        gbc_filterBtn.gridy = 2;        
        filterBtn.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                if(!filterValueTxt.getText().equals("")) {
                         filterValue = filterValueTxt.getText();
                         setColumnIndex();
                     if(sortColumn == 1) {
                        filterValue = filterValue.toLowerCase();
                         System.out.println("Operator: " +  filterValue.toLowerCase());
                     }
                     if (filterValue.length() == 0) {                
                       sorter.setRowFilter(null);
                     } else {
                       System.out.println("Apply listener" + filterValue + " "+filterValue.length() + " sort: "+ sortColumn );
                       sorter.setRowFilter(RowFilter.regexFilter(filterValue, sortColumn));
                     }
                }              
                else {
                        JOptionPane.showMessageDialog(null, "Enter a value!");
                }              
              }
                });
                panel1.add(filterBtn, gbc_filterBtn);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // important
        pack();
        setVisible(true); // important

    }
}
Tharif
  • 13,794
  • 9
  • 55
  • 77
icode03
  • 106
  • 8
  • use local variables instead of loading Icon each time when XxxRenderer repaints JTables view – mKorbel May 21 '15 at 15:04
  • 3
    *"Filter jTable by ImageIcon column"* That's very counter intuitive. So, the user has to know the *name* of the image to get a filter for that column? Why not put the name in a column beside it, then filter on that? Otherwise I'd offer a filter that presents the images themselves for user selection as opposed to the file *names* of the images. – Andrew Thompson May 21 '15 at 16:43
  • 2
    1) Do what @AndrewThompson said, but as a technical solution, just prepend the shared path to the typed string. 2) Paste an [MCVE](http://stackoverflow.com/help/mcve) instead of linking to your full code. – user1803551 May 22 '15 at 04:48
  • BTW - have you tried filtering on 'Joe' then bringing back the entire list? I cannot find how to do that - using the code as is. If the text field is empty, it is best to return the entire (unfiltered) list. BTW - it is good you followed the advice of @user1803551 and posted code, but an MCVE needs a `main(string[])` to run it. One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556) (though those images will not have the 'nice' string names seen in your example). – Andrew Thompson May 22 '15 at 08:25
  • You filter is case-sensitive, slightly odd. – user1803551 May 22 '15 at 08:38
  • "*Is there any method to filter only by image name without extension (e.g. orange, vodafone, cosmote)?*" Seems like it already does. If I type `cos` or `ora` it filters correctly. – user1803551 May 22 '15 at 09:22

1 Answers1

0

Maybe you could include the path in the regex you want to filter with? Like:

String path = "resources\/opIcons\/";
RowFilter.regexFilter("^"+path+".*"+filterValue+".*$", sortColumn)
Eric Leibenguth
  • 4,167
  • 3
  • 24
  • 51