4

I have a table containing some data. When i search a text in the textField, the look of the table, changes and the textFields disappears. I dont know why, I dont know If I'm doing it right

enter image description here

enter image description here

here's my whole code..

package test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.BadLocationException;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.RowFilter;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class test3 extends JFrame {

private JPanel contentPane;
private JTable table;

private TableModel tableModel;
private JTextField textField;
private String textForSearch;
private TableRowSorter<TableModel> sorter;
/**
 * Launch the application.
 */
public static void main(String[] args) {

/**
 * Create the frame.
 */
public test3() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 346);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setBounds(63, 52, 305, 191);
    contentPane.add(scrollPane);

    String columns [] = {
             "First Name", "Last Name", "Middle Name"   
        };
    String data[][] = new String [3][3];
    data [0][0] = "denise";
    data [0][1] = "alyson";
    data [0][2] = "berania";
    data [1][0] = "denden";
    data [1][1] = "pelesco";
    data [1][2] = "pogi";
    data [2][0] = "ryan";
    data [2][1] = "ewan";
    data [2][2] = "santos";

    tableModel = new DefaultTableModel(data, columns);

    table = new JTable(tableModel);
    scrollPane.setViewportView(table);

    sorter = new TableRowSorter<TableModel>(tableModel);
    table.setRowSorter(sorter);
    textField = new JTextField();
    textField.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            textForSearch = textField.getText();
            if(textForSearch.length()==0){
                sorter.setRowFilter(null);
            }else{
                sorter.setRowFilter(RowFilter.regexFilter("(?i)" + textForSearch));
            }

            for(int i =0;i<table.getColumnCount();i++){
                table.getColumnModel().getColumn(i).setCellRenderer(getRenderer());
            }
        }
    });
    textField.setBounds(262, 21, 86, 20);
    contentPane.add(textField);
    textField.setColumns(10);
}

   private TableCellRenderer getRenderer() {
        return new TableCellRenderer() {


            @Override
            public Component getTableCellRendererComponent(JTable arg0, Object arg1, boolean arg2, boolean arg3, int arg4, int arg5) {
                if(arg1 != null){
                    textField.setText(arg1.toString());
                    String string = arg1.toString();
                    if(string.contains(textForSearch)){
                        int indexOf = string.indexOf(textForSearch);
                        try {
                            textField.getHighlighter().addHighlight(indexOf,indexOf+textForSearch.length(),new javax.swing.text.DefaultHighlighter.DefaultHighlightPainter(Color.RED));
                        } catch (BadLocationException e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    textField.setText("");
                    textField.getHighlighter().removeAllHighlights();
                }
                return textField;
            }
        };
    }
}
dens14345
  • 192
  • 1
  • 4
  • 17
  • there are two ways override [TableModel](http://stackoverflow.com/questions/16814512/tablecellrenderer-and-how-to-refresh-cell-background-without-using-jtable-repain) or to build [Html syntax at runtime](http://stackoverflow.com/a/16740520/714968), :-) you can call it as repainting bug – mKorbel Aug 28 '14 at 06:11
  • [to see my specisics question about](http://stackoverflow.com/questions/6410839/highlights-substring-in-the-tablecells-which-is-using-for-jtable-filetering) – mKorbel Aug 28 '14 at 06:13

2 Answers2

3

I would strongly suggest a slightly differrent approach:

Instead of getRender() to return an anonymous TableCellRender(), extend your code a bit more to extend a JLable to be returned so you could freely change properties such as setBackground(), setForeground() etc with much more freedom.

Here you will find more info: http://docs.oracle.com/javase/7/docs/api/javax/swing/table/TableCellRenderer.html

public class DefaultTableCellRenderer extends JLabel implements TableCellRenderer {

}

Here is a full example for a JList which applies the same for JTable by changing to the appropiate interfaces: (focus on the last two if - else)

public class ThumbnailCellRenderer extends JLabel implements ListCellRenderer {

    private static final Color HIGHLIGHT_COLOR = new Color(0,0,128);

    public ThumbnailCellRenderer() {
        this.setOpaque(true);
        this.setIconTextGap(12);
    }
    @Override
    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
        // COMPLETE BODY
        Photo photo = (Photo)value;
        ImageIcon thumbnail = photo.getThumbnail();
        if(thumbnail != null) {
            this.setToolTipText("Double Click for Slideshow - "+photo.getName());
            this.setIcon(thumbnail);
            this.setText(photo.getCaption()+" - "+Utilities.getReadableDateAndTime(photo.getTime()));
        } else {
            this.setIcon(Icons.IMAGEREMOVED_ICON.get());
            this.setText(photo.getCaption()+" - "+Utilities.getReadableDateAndTime(photo.getTime())+" - Physical Image Removed");
        }
        if(isSelected) {
            setBackground(HIGHLIGHT_COLOR);
            setForeground(Color.WHITE);
        } else {
            setBackground(Color.WHITE);
            setForeground(Color.black);
        }
        return this;
    }

}

Finally, you would just add the renderer as you are doing in your MainFrame code.

I hope that helps.

Fer
  • 460
  • 2
  • 4
  • 17
2
  1. You are using you search text field as table cell renderer. This makes all cells look like text fields and your search text field disappear from its original location.
  2. You are setting cell renderer ActionListener inside ActionListener. This makes #1 happen after you try to search something.
NiematojakTomasz
  • 2,433
  • 20
  • 23
  • 1
    +1, for point 1) a component can only have a single parent, so you need to create a new JTextField to be used as the renderer for the table. You should also use setBorder(null) on this text field so it looks better. 2) The renderer should be assigned to the table when you create the table, not in the ActionListener. – camickr Aug 28 '14 at 00:17