好吧,所以我认为我的问题源于对jlist是实际上在做什么的根本性缺乏。
我有一个简单的示例类MyList
。
package test;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
public class MyList extends JList<String> {
public MyList(Vector<String> myStrings){
super(myStrings);
this.setCellRenderer(new ListCellRenderer<String>(){
@Override
public Component getListCellRendererComponent(
JList<? extends String> list, String value, int index,
boolean isSelected, boolean cellHasFocus) {
String myString = value.toString();
return new JLabel(myString+" (idx "+index+")");
}
});
this.addMouseListener(new MouseAdapter(){
@Override
public void mousePressed(MouseEvent e) {
MyList p = (MyList) e.getSource();
Component c = p.findComponentAt(e.getX(), e.getY());
System.out.println("am clicking on "+c.getClass()+" in "+p.getClass());
}
});
}
public static void main(String[] args){
Vector<String> myStrings = new Vector<String>();
myStrings.addAll(Arrays.asList("str 1","str 2","str 3"));
MyList mine = new MyList(myStrings);
JFrame myFrame = new JFrame();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setSize(500, 500);
myFrame.add(mine);
myFrame.setVisible(true);
}
}
单击列表中任何JLabel
的输出是相同的:
am clicking on class test.MyList in class test.MyList
我希望它是:
am clicking on class javax.swing.JLabel in class test.MyList
我认为这与ListCellRenderer的工作方式有关,但我不确定。为什么我从p.findComponentAt(e.getX(), e.getY());
回来的组件是Jlabel?这里发生了什么?
为什么我没有从p.findcomponentat(e.getx(),e.gety())返回的组件;jlabel?这里发生了什么?
jlists和jtables付出了额外的努力,以有效地显示大量信息,同时最小化开销。他们这样做的一种方法是通过渲染器显示信息。您在Jlist中看到的不是真正的Jlabels,而是Jlabels的图像(或任何用作渲染器的组件)。JLIST使用相同的渲染器为列中的每个元素创建图像。因此,假设您有一个带有1000个项目的JLIST,而不是创建1000个Jlabels,而是仅创建一个项目,使用它来创建Jlabel映像,然后显示图像。因此,您要点击的是真正的Jlist,而不是Jlabel。
要进一步测试,请尝试使用jtextfield作为渲染器,您会很快发现单元格不像jtextfield,并且您无法编辑它显示的信息。
<</p> <</p>