aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes JtableHeader with two separate listeners, one for each component : classic label and extra checkbox Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "JtableHeader with two separate listeners, one for each component : classic label and extra checkbox " Watch "JtableHeader with two separate listeners, one for each component : classic label and extra checkbox " New topic
Author

JtableHeader with two separate listeners, one for each component : classic label and extra checkbox

Alain Pignon
Greenhorn

Joined: Jun 21, 2009
Posts: 5
Hi

I add below yHeader class as my custom JTableHeader.

This class allows to have both, inside the same column header, the classic default Jlabel header with the up/down arrow to sort columns and an extra checkbox.
The extra checkbox I need in header is to control whether rowfilter.setSortable applies or not on column for filter feature.
The up/down arrow is provided by DefaultTableCellHeaderRenderer class for sort feature as I have also a TableRowSorter.
Actually MyHeader is a JPanel which includes checkbox and label.

The main problem is that I do not succeed to have distinct listener, one for the label and one for the checkbox.
Even basic check/uncheck on checbox does not work.
It seems that the basic sort column listener applies to the whole Header Jpanel (checbox + label).
I want to reduce its action down to label surface and free the checbox surface for its own listener when mouse click on it.

Please do you have any idea to apply a separate listener to MyHeader checkbox.

Thank you for your help.

Best regards.

Alain



public class MyHeader extends javax.swing.JPanel implements javax.swing.table.TableCellRenderer {

public MyHeader() {}
private boolean isFirstCall=true ;
private boolean[] isColCheckBoxCreated ;

public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int col)
{
if ( isFirstCall ) // on first call initialize array isColCheckBoxCreated
{
isFirstCall = false ;
isColCheckBoxCreated = new boolean[table.getColumnCount()] ;
for (int i_col = 0; i_col < table.getColumnCount(); i_col++) {
isColCheckBoxCreated[i_col]=false;
}
}

if ( ! isColCheckBoxCreated[col] ) // to instance only ONE checkbox in header
{
isColCheckBoxCreated[col] = true ;

JCheckBox checkBox = new JCheckBox("",true);
/*
// This checkbox listener does nor work
checkBox.addActionListener ( new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.out.println("addActionListener ON CHEKBOX");
}
} ) ;
*/

this.add(checkBox);
System.out.println("HERE IS CREATED CHEKBOX row="+row+", col="+col+"<");
}

JLabel c = (JLabel) table.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(table,value,isSelected,hasFocus,row,col) ;
this.add(c);

// Here Maybe a solution to catch mouse click in header but on which component ? checkbox or label ?
table.getTableHeader().addMouseListener(new MouseAdapter() {
public void mouseClicked (MouseEvent e)
{
if (mousePressed) {
mousePressed=false;
System.out.println("myHeaderListener mouseClicked on " + e.getComponent());

PointerInfo pointerInfo = MouseInfo.getPointerInfo();
Point point = pointerInfo.getLocation();
System.out.println("AT POINT ABSOLUTE "+ point.toString());
Point ptrelatif = e.getPoint();
System.out.println("AT POINT RELATIVE "+ ptrelatif.toString());
}
}
public void mouseExited (MouseEvent e) { }
public void mouseReleased (MouseEvent e) { }
public void mouseEntered (MouseEvent e) { }
public void mousePressed (MouseEvent e) { }
});

return this;
}
}


Craig Wood
Ranch Hand

Joined: Jan 14, 2004
Posts: 1535
do you have any idea to apply a separate listener to MyHeader checkbox
You'll probably need an editor for your table column.
table > getColumnModel > getColumn > get/setEditor
They're messy to put together. For a recent example see reply 6 in Adding JButton to a JTable.
Alain Pignon
Greenhorn

Joined: Jun 21, 2009
Posts: 5
Hi

Thank you for your answer and the link you indicate. I'll try CellEditor asap.

I wanted also to add that there may be another solution by adding a table mouse listener as I did in code above at bottom.
I can get the mouse position when click in JTableHeader without disturbing the sort listener on label component.

But in this case, the problem is that event component is the whole JTableHeader and I cannot know whether the checbox was clicked ot the label was clicked.
I did not succeed to go down inside to sub-component checkbox or label.
If I could, it would be a solution to manually change checbox state and execute any relevant statements.

So, if this solution is applied, the question is :

How can I know which java component I clicked with mouse ? Maybe using mouse position as input ?

Thanks for help.
Best regards.
Alain
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19760
    
  20

Alain, please Use Code Tags.

Alain Pignon wrote:How can I know which java component I clicked with mouse ? Maybe using mouse position as input ?

How about getSource()? Although in JTable, JTableHeader, JList etc that will return the actual component, not the component returned by the renderers / editors. These components all have methods to convert a Point to a row / column though.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Alain Pignon
Greenhorn

Joined: Jun 21, 2009
Posts: 5
Hello Rob,

Thank you for your hint about event.getSource(). I tried it.

Unfortunately, I found no difference between outputs of


They both return exactly the same thing : JTableHeader.
Maybe I applied it wrong ?

I'll try other hints.
Thanks very much!

Regards.
Alain.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19760
    
  20

If you would have read the rest of my post you would have seen I already told you this would happen, and how you could retrieve the column for the point.
Alain Pignon
Greenhorn

Joined: Jun 21, 2009
Posts: 5
Hi Rob,

Sorry, I read a bit fast your answer and I missed a part of it.
I agree, I can retrieve the Jtable column and row from the point.
But the question is that in column header, there are the classic header label plus an extra checkbox
and I do not know which one was clicked...

Thank you again for your help.

Regards.
Alain
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19760
    
  20

Can I conclude from this that you are returning a custom component with both a check box and a label? Is this some Container like a JPanel?

Either way, it takes a bit more code, but you can translate the point to a point relative to the column header itself, get a renderer component, and using those calculate whether or not you are clicking on the check box. If you're lucky and have a JPanel with a JCheckBox and a JLabel, you can possibly use the JPanel's getComponentAt method (although I've found out this sometimes returns null for renderers); if you're not, you'll have to retrieve the JCheckBox from the panel, get its bounds and check for the point:
Alain Pignon
Greenhorn

Joined: Jun 21, 2009
Posts: 5
Hi Rob,

Sorry for answering so late. I had long problem with my laptop.

This post just to thank you for yout last advices.
I followed them and it works great.

Thanks again.
Alain
 
Don't get me started about those stupid light bulbs.
 
subject: JtableHeader with two separate listeners, one for each component : classic label and extra checkbox