views:

22

answers:

2

Hello everybody.

I'm currently working on a rather complex application. My job is to build parts of the GUI.
The main area is derived for JTable and contains all application relevant data. There are a few elements on top of the Table, that allow the user to control the way the data is shown in the table.
The options relevant to the task at hand are:

  • Changing of number of columns,
  • Independently changing of width of columns (not by means of JTableHeader) and
  • Entering one filter term per column to select specific rows of the data.

The main goal in this szenario is to create a Component (probably JTextField) for every column in the current viewsetting, which is accuratly aligned with that column (although it changes size at runtime).

First question:

The alignment doesn't work. I can't get the width of the TextFields to match the width of the columns.
How do i get it to work?

Second problem:

I want the individual filters to be chained. That is, if the user decides to enter more then one filter string, all of them should be evaluated for their respective columns and only the rows that match all filters should be shown. So far the input in a second TextField delets the first filter (which is working decently using RowFilter.regexFilter).
How do i get this to work?

Please let me know, which code snippets could be useful to you and i will be glad to post them.

Thanks in advance for any help given.

Regards, DK

A: 

I can't get the width of the TextFields to match the width of the columns

This example should get you started:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class TableFilterRow extends JFrame implements TableColumnModelListener
{
    private JTable table;
    private JPanel filterRow;

    public TableFilterRow()
    {
        table = new JTable(3, 5);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane );
        table.getColumnModel().addColumnModelListener( this );

        //  Panel for text fields

        filterRow = new JPanel( new FlowLayout(FlowLayout.CENTER, 0 , 0) );

        for (int i = 0; i < table.getColumnCount(); i ++)
            filterRow.add( new JTextField("" + i) );

        columnMarginChanged( new ChangeEvent(table.getColumnModel()) );
        getContentPane().add(filterRow, BorderLayout.NORTH);
    }

    //  Implement TableColumnModelListener methods
    //  (Note: instead of implementing a listener you should be able to
    //  override the columnMarginChanged and columMoved methods of JTable)

    public void columnMarginChanged(ChangeEvent e)
    {
        TableColumnModel tcm = table.getColumnModel();
        int columns = tcm.getColumnCount();

        for (int i = 0; i < columns; i ++)
        {
            JTextField textField = (JTextField)filterRow.getComponent( i );
            Dimension d = textField.getPreferredSize();
            d.width = tcm.getColumn(i).getWidth();
            textField.setPreferredSize( d );
        }

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                filterRow.revalidate();
            }
        });
    }

    public void columnMoved(TableColumnModelEvent e)
    {
        Component moved = filterRow.getComponent(e.getFromIndex());
        filterRow.remove(e.getFromIndex());
        filterRow.add(moved, e.getToIndex());
        filterRow.validate();
    }

    public void columnAdded(TableColumnModelEvent e) {}
    public void columnRemoved(TableColumnModelEvent e) {}
    public void columnSelectionChanged(ListSelectionEvent e) {}

    public static void main(String[] args)
    {
        JFrame frame = new TableFilterRow();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}

only the rows that match all filters should be shown

Read the JTable API and follow the link to the Swing tutorial on "How to Use Tables" where you will find the TableFilterDemo. You can easily modify the code to use "and" filters. The code would be something like:

// rf = RowFilter.regexFilter(filterText.getText(), 0);
List<RowFilter<Object,Object>> filters = new ArrayList<RowFilter<Object,Object>>(2);
filters.add(RowFilter.regexFilter(filterText.getText(), 0));
filters.add(RowFilter.regexFilter(filterText.getText(), 1));
rf = RowFilter.andFilter(filters);

This examples shares a single text field looking for the same string in multiple columns. You would obviously use your individual text fields.

camickr
Thanks for your help so far. I'm going to try out your solutions shortly.
DeKay
A: 

Hello again.

Your solution for the "and" filters works just fine. Thank you for that.

Regarding the alignment problem:
I ran your example and it works well, but only as long as you don't have any vertical scrollbar. In the context of my application that is hardly ever the case. So i would appreciate it, if you could modify your code to cover this case too.

Anyway, thank you again for your effort.

Regards, DK

DeKay