Runtime alignment of JComponents + chaining to RowFilters
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 respec开发者_Go百科tive 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
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.
精彩评论