I'm using a JList to hold chat data for my chat program.
It uses a custom list renderer to render a custom JPanel object as the element type.
This JPanel contains two JLabels (anchored to the top, for name and time), and a JTextArea (anchored to the bottom, for chat message).
It looks like this:
Everything works great, but I want to add a hide/show feature.
Using a previously programmed PopupMenu handler, I have a popup appear when you right click on an element.
When you click hide (or show, it's a toggle) then it should minimize the element like so...
The only problem is... it doesn't update the JList cell size as you can see the large empty region where the text used to be.
However, when I type another message...
The JList fixes the cell size completing the 'hide' operation.
My question is how do you get the JList to revalidate/repaint/etc programmatically.
And don't think I haven't tried all the obvious solutions...
public void setHidden(boolean hidden) {
// this is in the custom JPanel class
System.out.println("Initial: " + this.getPreferredSize());
// TextArea is the JTextArea which we set invisible when we want to hide it.
TextArea.setVisible(!hidden); // TextArea is a variable btw
this.invalidate();
this.validate();
this.repaint();
System.out.println("After: " + this.getPreferredSize());
container.revalidate();
}
/*
* This is what the above printlns show when you hide, then show the element.
*
* Initial: java.awt.Dimension[width=176,height=38]
* After: java.awt.Dimension[width=176,height=20]
* Initial: java.awt.Dimension[width=176,height=20]
* After: java.awt.Dimension[width=176,height=38]
*/
public void revalidate() {
// container.revalidate() ^^^
// list is the list containing the chat elements
list.invalidate();
list.validate();
list.repaint();
}
The custom JPanel class uses a GroupLayout to render the components.
Do you guys have any knowledge on how to programmically cause a JList to revalidate its cell sizes?
... besides the methods that I've posted? :)
Solution:
After searching method after method and testing if they would solve my problem, I found that executing this code after a hide/show operation would cause the cell height (and width) to be recalculated and without any unwanted visual 'flicker' of the JList.
list.setFixedCellHeight(0);
list.setFixedCellWidth(0);
list.setFixedCellHeight(-1);
list.setFixedCellWidth(-1);
Without seeing any code, I can only guess: the most probable reason is that you're doing the hide under the feet of the list, that is without its model notifying its listeners. The list's ui delegate caches the cell size deep inside, which is cleared on receiving ListEvents
This is job for JTable
with two Columns (Chat
and Boolean
) in the TableModel
and with visible Chat
Column only, the trick is by using by implement RowFilter where you set as parameter to the second column only String "false"
(Object
in the JTable
with Boolean
is possible filtering with returns value in the String "true" / "false"
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With