java jlist 设置高度,Java Swing:JList与ListCellRenderer选择的项目高度不同

I'm making a custom ListCellRenderer. I know that you can have different dimensions for each individual cell. But now I want to have a different dimension for the selected cell. Somehow, the JList is caching the dimension for each individual cell the first time it has to calculate bounds for each cell.

This is my code:

public class Test {

static class Oh extends JPanel {

public Oh() {

setPreferredSize(new Dimension(100, 20));

}

protected void paintComponent(Graphics g) {

super.paintComponent(g);

g.setColor(Color.WHITE);

g.fillRect(0, 0, getWidth(), getHeight());

}

}

static class Yeah extends JPanel {

private boolean isSelected;

public Yeah(boolean isSelected) {

setPreferredSize(new Dimension(100, 100));

this.isSelected = isSelected;

}

protected void paintComponent(Graphics g) {

super.paintComponent(g);

//setSize(100, 100); // doesn't change the bounds of the component

//setBounds(0, 0, 100, 100); // this doesn't do any good either.

if (isSelected) g.setColor(Color.GREEN);

else g.setColor(Color.BLACK);

g.fillRect(0, 0, getWidth(), getHeight());

}

}

public static void main(String[] args) {

JFrame f = new JFrame();

f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

f.setSize(800, 500);

Vector ints = new Vector();

for (int i = 0; i < 100; i++) {

ints.add(i);

}

JList list = new JList(ints);

list.setCellRenderer(new ListCellRenderer() {

public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {

if (isSelected || ((Integer) value) == 42) return new Yeah(isSelected);

else return new Oh();

}

});

//list.setPrototypeCellValue(null);

//list.setFixedCellHeight(-1);

f.add(new JScrollPane(list));

f.setVisible(true);

}

}

In the comments you can see what I've already tried.

I've already searched quite long and found a lot of useless articles, some of them touch the ListCellRenderer/dynamic height thing, but they only work because the height stays the same for the individual cells. My heights are changing, so how do I do this?

解决方案

Thanks to Rastislav Komara I've been able to solve this quite easily:

I've created an inner class that extends BasicListUI and created public method that is called on ListSelectionListener.valueChanged:

private class MyRenderer implements ListCellRenderer {

public int listSelectedIndex = -1;

public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,

boolean cellHasFocus) {

if (index == listSelectedIndex)

return new Yeah(isSelected);

else

return new Oh();

}

}

MyRenderer lcr = new MyRenderer();

private class MyListUI extends BasicListUI {

public void triggerUpdate() {

lcr.listSelectedIndex = list.getSelectedIndex();

updateLayoutState();

list.revalidate();

}

}

The updateLayoutState method is normally triggered when the JList height changes.

The only "insane" thing I'm doing here is that my renderer needs to know what the selected index is. This is because the updateLayoutState method doesn't use the selected index in it's height calculations.

Somehow using list.getSelectedIndex() inside getListCellRendererComponent doesn't work well.

Edit:

Check also the anser by nevster and kleopatra, they look way smarter, try them first...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值