想从jlist的单元格里直接输入数据
一开始我是用一个继承JTextField来实现渲染器
可是连显示都显示不出来
怎么做才能实现在单元格里就可以输入数据

解决方案 »

  1.   

    可以参考下面这个方法(转):
    一、绘制器的工作原理
    不管是JList还是JComboBox,它们都用到了ListCellRenderer,因为JComboBox本身就是由一个下拉式的JList和TextField组成的. 在这里,它们使用了callback的机制。callback的一是种常见的方式是在A类中调用B类中的方法,在A类中先要登记一个(也可以是多个)B类的实例引用,在需要调用时再通过该实例来调用它的内部方法.这样的机制在很多的设计模式中都有用到,如Observer等.还有AWT的事件机制也用到了callback. 要实现callback,通常将B类设计成一个能被callback的接口.在JList的绘制器中,swing提供了一个ListCellRenderer接口,
    public interface ListCellRenderer {
        Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus);
    }
    这个接口只提供一个方法,我们只要实现了这个接口,并将它的实例引用传给JList,就可以将JList替换成不同的样式了.看一下ListCellRenderer是如何工作的,在绘制JList的每个Cell之前,它会去调用getListCellComponent( ,得到一个Component,并
    将这个Component绘制在正确的位置.因为getListCellComponent( 返回的是Component,所以我们几乎可以扩展任意一个Component,来改变JList,JComboBox等的外观.二、制作自已的绘制器
    我们现在要想让JList中显示一组学生名单,同时每个名单前显示该学生的图标.如下图所示我们先来想一想,Swing中有什么组件既可以显示图标也可以显示文字? JLabel.对了。我们就用JLabel作为JList的绘制器, 看看我扩展的JLabel类,它实现了ListCellRenderer接口:
            /* 可以显示图标的ListCell绘制器 */
            public class IconListItemRenderer extends JLabel implements ListCellRenderer
            {
                private Border
                    selectedBorder = BorderFactory.createLineBorder(Color.blue,1),
                    emptyBorder = BorderFactory.createEmptyBorder(1,1,1,1);            public Component getListCellRendererComponent(
                            JList list,
                            Object value,
                            int index,
                            boolean isSelected,
                            boolean cellHasFocus)
                    {                IconListItem item = (IconListItem)value;
                    this.setIcon(item.getIcon());
                    this.setText(item.getText());                if ( isSelected  setBorder (selectedBorder);
                    else setBorder(emptyBorder);
                    return this;
                }
            }大家看到,getListCellRendererComponent方法会传入几个参数,我们就用它传入的几个参数设置JLabel的外观:图标与文字。在这个类中,我们用一个IconListItem接收调用者传过来的value,
            IconListItem item = (IconListItem) value;
    IconListItem是我另外定义好的一个类,它用来存放每一个List Item的值,
            import javax.swing.*;
            public class IconListItem
            {
                Icon icon;
                String text;
                public IconListItem(Icon icon, String text)
                {
                    this.icon = icon;
                    this.text = text;
                }
                public Icon getIcon() { return icon;}
                public String getText() { return text;}
                public void setIcon(Icon icon){ this.icon = icon;}
                public void setText(String text){ this.text = text; }
            }这样的话,我就可以用getIcon()和getText()方法取得每个List Item的值了,
            IconListItem item = (IconListItem) value;
            this.setIcon(item.getIcon());
            this.setText(item.getText());至此,我们就可以用以下方法方便的更换JList的外观了,
            JList list = new JList();
            list.setCellRenderer(new IconListItemRenderer());  file://安装我们自订的cellRenderer
            DefaultListModel listModel = new DefaultListModel();
            list.setModel(listModel);
            IconListItem item = new IconListItem(new ImageIcon(...),"John";
            listModel.addElement(item);    // 为List增加Item
            ...由于JComboBox也有一个下拉式清单,所以它的清单也是用ListCellRenderer来绘制的,所以我们也可以将这个IconListItemRenderer给它用:
            JComboBox list = new JComboBox();
            list.setRenderer(new IconListItemRenderer());  //装我们自订的cellRenderer
            DefaultComboBoxModel comboModel = new DefaultComboBoxModel();
            list.setModel(comboModel);
            IconListItem item = new IconListItem(new ImageIcon(...),"John";
            comboModel.addElement(item);    // 为List增加Item
            ...注意,JComboBox安装绘制器时是用setRenderer()方法,JList是用setCellRenderer()方法,名字稍有不同.以上大家看到的是可显示一个图标的List, 下面我们再看一个可显示CheckBox的List是如何实现的,以下是例图:代码实现:
            import javax.swing.*;
            import java.awt.*;
            import javax.swing.border.*;
            import java.awt.event.*;
            /* 可以显示CheckBox的ListCell绘制器 */
            public class CheckListItemRenderer extends JCheckBox implements ListCellRenderer
            {
                public Component getListCellRendererComponent(
                            JList list,
                            Object value,
                            int index,
                            boolean isSelected,
                            boolean cellHasFocus)
                {
                    CheckListItem item = (CheckListItem)value;
                    this.setSelected(item.getCheck());
                    this.setText(item.getText());
                    this.setFont(list.getFont());
                    this.setEnabled(list.isEnabled());
                    return this;
                }
            }
    同样这个绘制器中用一个CheckListItem存放每个List Item的值:
            public class CheckListItem
            {
                boolean check;
                String text;
                public CheckListItem(boolean check, String text)
                {
                    this.check = check;
                    this.text = text;
                }
                public boolean getCheck() { return check; }
                public void setCheck(boolean _check) { check = _check; }
                public String getText() { return text; }
                public void setText(String _text) { text = _text; }
            }
    这个绘制器的用法同IconListItemRenderer一样,不多讲了.三、让自订的绘制器响就鼠标事件
    使用以上的CheckListItemRenderer时,大家会发现,虽然List中可以显示CheckBox了,但是用鼠标点击时,没有反应! 现在我就来解决这个问题.要澄清的是,ListCellRenderer本身是只返回一个组件用来绘制一个单元格,不能对用户动作作出反应。为些我们必须在JList上下功夫.JList有一个addMouseListener()方法可以为自身安装一个鼠标监听器,在这里,我实现了一个MouseAdapter,并让它对mousePressed作出响应:
            class CheckListMouseListener extends MouseAdapter
            {
                  public void mousePressed(MouseEvent e) {
                    JList list = (JList) e.getSource();
                    int index = list.locationToIndex(e.getPoint());
                    CheckListItem item = (CheckListItem)list.getModel().getElementAt(index);
                    item.setCheck(! item.getCheck());
                    Rectangle rect = list.getCellBounds(index, index);
                    list.repaint(rect);
                }
            }
    使用时, 用addMouseListener(new CheckListMouseListener())就行了.除了包含CheckBox的JList外,许多情况下,我们需要为自制的绘制器加上动作响应,如我们要实现一个可编辑的JList, 除了要扩展JTextField及实现ListCellRenderer之外,还要写一个鼠标监听器和键盘监听器,当双击时,JList变成可编辑状态,当回车时,还原成不可编辑状态.具体的实现过程,我就不详叙了,留给大家作练习.
      

  2.   

    让textfield可编辑应该是让它获取焦点吧,看下我下面的代码,不成功 private class TextRenderer extends JTextField implements ListCellRenderer { @Override
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
    boolean cellHasFocus) {
    Classes c = (Classes)value;
    setText(c.toString());
    Color bgColor = index % 2 == 0 ? bgc1 : bgc2;
                setBackground(isSelected ? selectedColor : bgColor);
    setBorder(null);
    setFont(isSelected ? selectedFont : font);
    if(edit){
    requestFocus();
    }
    edit = false;
    return this;
    }

    }