我有一个JList
并且我添加了一个 as 的实例ListCellRenderer
作为 as 的单元格渲染JList
器
myList.setCellRenderer(new ListItemPanel());
这myList
是JList
带有类型的列表模型String
。实施ListItemPanel
如下。
public class ListItemPanel<E> extends javax.swing.JPanel implements ListCellRenderer<E>{
public Component getListCellRendererComponent(JList<? extends E> list, E value, int index, boolean isSelected, boolean cellHasFocus) {
nameLabel.setText(value.toString());
if(isSelected){
setBackground(Color.YELLOW);
setPreferredSize(new Dimension(list.getWidth(), 40));
}else{
setBackground(Color.PINK);
setPreferredSize(new Dimension(list.getWidth(), 18));
}
return this;
}
}
使用上面的代码,我期望在JList
. 但只有颜色变化正在发生。项目的高度list
似乎是18
在开始。当我更改18
为其他值时,项目的高度会更改为该值。但是选择项目时不会发生任何更改。
nameLabel
是一个JLabel
即上JPanel
。
我尝试重新验证和重新绘制list
,JPanel
和nameLabel
. setPreferredSize
并在JPanel
和中都使用了该方法JLabel
。
但是选择时没有任何东西改变项目的高度list
。希望有人可以提供帮助..!
编辑
我需要的是在选择时更改项目的高度。在这里,它讨论的是根据其中的文本更改每个项目的高度。但是在那里,添加文本后,高度是固定的。那不是我需要的。。
谢谢大家的关注。。
SSCCE 问题
import javax.swing.*;
import java.awt.*;
public class A extends javax.swing.JFrame {
private DefaultListModel<String> myListModel = new DefaultListModel<>();
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JList myList;
public A(){
//Setting the GUI
jScrollPane1 = new javax.swing.JScrollPane();
myList = new javax.swing.JList();
myList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane1.setViewportView(myList);
add(jScrollPane1);
setSize(300,400);
setLocationRelativeTo(null);
//Add model, renderer and elements to the list
myList.setModel(myListModel);
myList.setCellRenderer(new ListItemPanel());
myListModel.addElement("ABCD");
myListModel.addElement("1234567890");
myListModel.addElement("q121we34rt56yu7");
myListModel.addElement("ABC 123 #$%");
myListModel.addElement("11 11 22 22 33 33");
myListModel.addElement("321 ewq A1");
}
//Execute the program
public static void main(String[] args) throws Exception{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new A().setVisible(true);
}
});
}
}
//Customized ListCellRenderer
class ListItemPanel<E> extends javax.swing.JPanel implements ListCellRenderer<E>{
private javax.swing.JLabel nameLabel;
public ListItemPanel() {
nameLabel = new javax.swing.JLabel();
setLayout(new BorderLayout());
add(nameLabel);
}
public Component getListCellRendererComponent(JList<? extends E> list, E value, int index, boolean isSelected, boolean cellHasFocus) {
nameLabel.setText(value.toString());
if(isSelected){
setBackground(Color.YELLOW);
setPreferredSize(new Dimension(list.getWidth(), 40)); //If selected, set the height to 40
}else{
setBackground(Color.PINK);
setPreferredSize(new Dimension(list.getWidth(), 18)); //If not selected, set the height to 18
}
return this;
}
}
回答问题
在setFixedCellHeight()
方法上,据说,
...通过应用 getPreferredSize ...在 ListUI 中计算单元格高度。
所以,如果值可以在里面改变ListUI
,我的任务是可能的..
这些值存储在一个变量中cellHeights
,正如我在源代码中看到的那样,该变量只更新一次。因此,我更改了我的代码,以便cellHeights
每次选择一个项目时都会更改。
SSCCE 的答案
import javax.swing.*;
import java.awt.*;
import javax.swing.plaf.basic.BasicListUI;
public class A extends javax.swing.JFrame {
private DefaultListModel<String> myListModel = new DefaultListModel<>();
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JList myList;
public A(){
//Setting the GUI
jScrollPane1 = new javax.swing.JScrollPane();
myList = new javax.swing.JList();
myList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane1.setViewportView(myList);
add(jScrollPane1);
setSize(300,400);
setLocationRelativeTo(null);
//Add model, renderer and elements to the list
myList.setModel(myListModel);
myList.setCellRenderer(new ListItemPanel());
myList.setUI(new BasicListUI() { //Update UI of JList
@Override
protected void paintCell(Graphics g, int row, Rectangle rowBounds, ListCellRenderer cellRenderer, ListModel dataModel, ListSelectionModel selModel, int leadIndex) {
Object value = dataModel.getElementAt(row);
boolean cellHasFocus = list.hasFocus() && (row == leadIndex);
boolean isSelected = selModel.isSelectedIndex(row);
ListItemPanel rendererComponent = (ListItemPanel)cellRenderer.getListCellRendererComponent(list, value, row, isSelected, cellHasFocus);
int x = rendererComponent.getH();
if(x != cellHeights[row]){
cellHeights[row] = x; //Change the height of the selected item
myList.repaint(); //Though repaint is called here, it will actualy be effected after this function call
}
super.paintCell(g, row, rowBounds, cellRenderer, dataModel, selModel, leadIndex);
}
});
myListModel.addElement("ABCD");
myListModel.addElement("1234567890");
myListModel.addElement("q121we34rt56yu7");
myListModel.addElement("ABC 123 #$%");
myListModel.addElement("11 11 22 22 33 33");
myListModel.addElement("321 ewq A1");
}
//Execute the program
public static void main(String[] args) throws Exception{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new A().setVisible(true);
}
});
}
}
//Customized ListCellRenderer
class ListItemPanel<E> extends javax.swing.JPanel implements ListCellRenderer<E>{
private int h; //This variable is used to store the height of the component
private javax.swing.JLabel nameLabel;
public ListItemPanel() {
nameLabel = new javax.swing.JLabel();
setLayout(new BorderLayout());
add(nameLabel);
}
public Component getListCellRendererComponent(JList<? extends E> list, E value, int index, boolean isSelected, boolean cellHasFocus) {
nameLabel.setText(value.toString());
if(isSelected){
setBackground(Color.YELLOW);
h = 40; //If selected, set the height to 40
}else{
setBackground(Color.PINK);
h = 18; //If not selected, set the height to 18
}
return this;
}
public int getH(){
return h;
}
}