I'm trying to highlight all rows in a JList which have been "matched" with data elsewhere, and disable that row.
When I debug, I can see the correct data is set within cbNameIsMatched. However, what happens instead is that after I create the first match, each row I select in the JList is highlighted instead of the one with the "matched" index. The setEnabled
is also setting for all items from the end of the list up to where I click in the list.
class MyListCellRenderer extends JLabel implements ListCellRenderer
{
public MyCopybookListCellRenderer()
{
setOpaque(false);
}
@Override
public Component getListCellRendererComponent(JList paramList, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
setText(value.toString());
if(isSelected)
{
setOpaque(true);
}
else
{
setOpaque(false);
}
if(cbNameIsMatched[index]==2)
{
setBackground(Color.YELLOW);
setEnabled(false);
}
myList.repaint();
return this;
}
You would do better extending DefaultListCellRenderer
over JLabel
as the former already takes care of everything and all you have to do is change the specific things you need. It gives you a "safety net" for the cases you didn't touch.
public class GetterText extends JFrame {
GetterText() {
JList<String> list = new JList<>(new String[]{"AAAA", "BBBB", "CCCC", "DDDD"});
list.setCellRenderer(new MyListCellRenderer());
getContentPane().add(list);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
private class MyListCellRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
label.setOpaque(isSelected); // Highlight only when selected
label.setOpaque(true); // Highlight always
if(index == 2) { // I faked a match for the second index, put you matching condition here.
label.setBackground(Color.YELLOW);
label.setEnabled(false);
}
return label;
}
}
public static void main(String[] args) {
new GetterText();
}
}
Edit: elaboration on the use of super
super
gives a reference to the superclass which you can use to call its methods. When overriding a method of the superclass, calling that superclass's method means "do what you did before", or, "retain the implementation". This is good because you start from a point where everything works as the default and what you have left to do is tweak specific behaviors without the need to take care for all the others.
In this case, if you return label
after
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
you would get the default behavior because it is the one being used by the extending DefaultListCellRenderer
. The arguments are the same in order to get the same result as the superclass would give. Then I go on to change this default JLabel
. What you do is create a new JLabel
with no default behavior. Note that I "cheat" here by knowing that the Component
returned by DefaultListCellRenderer.getListCellRendererComponent
is a JLabel
.