llm0528
2009-07-24 22:47
浏览 235
已采纳

关于JComboBox的一个问题

[size=large]本人很菜,想写一个登陆框,其中用户名的JComboBox下拉项目上想添加一个button来实现删除不需要的用户名。现在关键不知道用什么方法写,因为用户名的ComboBox是可编辑的,所以不能使用setRenderer()方法
,最好哪位高人能发一下实际代码就最好了!

下面的代码是使用 setRenderer实现的,但是当选择后,显示的是对象字符串,大家可以运行下看看效果,然后注释掉下面的标记再运行看看~ [/size]

[code="java"]class ComplexCellRenderer implements ListCellRenderer {
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();

public Component getListCellRendererComponent(JList list, Object value,
        int index, boolean isSelected, boolean cellHasFocus) {
    Font theFont = null;
    Color theForeground = null;
    Icon theIcon = null;
    String theText = null;

    JLabel renderer = (JLabel) defaultRenderer
            .getListCellRendererComponent(list, value, index, isSelected,
                    cellHasFocus);

    if (value instanceof Object[]) {
        Object values[] = (Object[]) value;
        theFont = (Font) values[0];
        theForeground = (Color) values[1];
        theIcon = (Icon) values[2];
        theText = (String) values[3];
    } else {
        theFont = list.getFont();
        theForeground = list.getForeground();
        theText = "";
    }
    if (!isSelected) {
        renderer.setForeground(theForeground);
    }
    if (theIcon != null) {
        renderer.setIcon(theIcon);
    }
    renderer.setText(theText);
    renderer.setFont(theFont);
    return renderer;
}

}

public class Test2 {
public static void main(String args[]) {
Object elements[][] = {
{ new Font("Helvetica", Font.PLAIN, 20), Color.RED,
new MyIcon(), "A" },
{ new Font("TimesRoman", Font.BOLD, 14), Color.BLUE,
new MyIcon(), "A" },
{ new Font("Courier", Font.ITALIC, 18), Color.GREEN,
new MyIcon(), "A" },
{ new Font("Helvetica", Font.BOLD | Font.ITALIC, 12),
Color.GRAY, new MyIcon(), "A" },
{ new Font("TimesRoman", Font.PLAIN, 32), Color.PINK,
new MyIcon(), "A" },
{ new Font("Courier", Font.BOLD, 16), Color.YELLOW,
new MyIcon(), "A" },
{ new Font("Helvetica", Font.ITALIC, 8), Color.DARK_GRAY,
new MyIcon(), "A" } };

    JFrame frame = new JFrame("Complex Renderer");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    ListCellRenderer renderer = new ComplexCellRenderer();
    JComboBox comboBox = new JComboBox(elements);
    comboBox.setEditable(true); //标记
    comboBox.setRenderer(renderer);
    frame.add(comboBox, BorderLayout.NORTH);

    frame.setSize(300, 200);
    frame.setVisible(true);
}

}

class MyIcon implements Icon {

public MyIcon() {
}

public int getIconHeight() {
    return 20;
}

public int getIconWidth() {
    return 20;
}

public void paintIcon(Component c, Graphics g, int x, int y) {
    g.setColor(Color.RED);
    g.drawRect(0, 0, 25, 25);
}

}[/code]
[b]问题补充:[/b]
感谢楼下的朋友,可是这里又有一个问题了,我该如何控制它的尺寸呢?我通过setPopupSize来控制,可是我只想修改它的宽度,因为item是动态加入的所以不可能将高度设死。还望帮忙解答下,谢谢!

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • hunterli0408 2009-07-25 03:20
    已采纳

    建议lz还是换一种方式来实现吧,不要使用JComboBox了。
    JComboBox的能力非常有限,他最大的缺陷在于,编程人员无法控制弹出的下拉列表。说白了,就是无法在弹出的列表上添加鼠标及鼠标移动事件,也无法获得列表上当前被激活的项目(不是指文本框中显示的项目,而是指当前列表中处于鼠标下方的那个项目),至少现在为止,我还没有发现。

    其实lz的需求非常简单,很多web页面上都有类似的功能。最常见的实现方式是,用户的鼠标移动到列表中的某一项时,点击键盘上的Delete键,这时列表中的那一项被删除。

    要实现这个功能,不用JComboBox,而是用自定义控件的话,就会变得很简单。所需的无非就是三个控件的连协:JTextField,JButton,JPopupMenu。

    样例代码如下,写的匆忙,lz将就着看看。
    功能:
    1.点击按钮,弹出列表
    2.点击列表项,列表项的内容反映到JTextField中。
    3.鼠标移到列表的某一项,同时点击键盘的Delete键时,对应列表项删除。
    [code="java"]
    package test;

    import java.awt.Dimension;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JMenuItem;
    import javax.swing.JPopupMenu;
    import javax.swing.JTextField;

    public class Test2 extends JFrame{

    private JPopupMenu popup = new JPopupMenu("JPopupMenu");
    private JTextField textField = new JTextField();
    private JButton button = new JButton("");
    
    public Test2() {
    
        this.setTitle("JPopupMenuDemo");
        this.setSize(300, 300);
        this.setLocationRelativeTo(null);
        this.setLayout(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    
        String[] items = {"AAAAAAAA", "BBBBBBBB", "DDDDDDDD", "EEEEEEEE"};
    
        for(int i = 0; i < 4; i++) {
            JMenuItem item = new JMenuItem(items[i]);
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JMenuItem sim = (JMenuItem)e.getSource();
                    textField.setText(sim.getText());
                }
            });
            popup.add(item);
        }
    
        textField.setSize(100, 30);
        textField.setLocation(10, 10);
        this.add(textField);
    
        button.setSize(15, 30);
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(popup.getSubElements().length != 0) {
                    popup.show(Test2.this, 15, 70);
                    popup.requestFocus();
                }
            }
        });
        button.setLocation(110, 10);
        this.getContentPane().add(button);
    
        popup.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if(popup.isVisible() && popup.hasFocus()) {
                    if(e.getKeyCode() == KeyEvent.VK_DELETE) {
                        Dimension popupSize = popup.getSize();
                        int itemCount = popup.getSubElements().length;
                        int itemWidth = popupSize.width/itemCount;
    
                        Point mousePos = popup.getMousePosition();
                        if(mousePos != null) {
                            int index = mousePos.y/itemWidth;
                            System.out.println("Remove:" + index);
                            popup.remove(index);
                            popup.pack();
                            Test2.this.validate();
                            Test2.this.repaint();
                            if(popup.getSubElements().length != 0) {
                                popup.requestFocus();
                            } else {
                                popup.setVisible(false);
                            }
                        }
    
                    }
                }
            }
        });
    
        this.setVisible(true);
    }
    public static void main(String args[]) {
        new Test2();
    }
    

    }
    [/code]

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • hunterli0408 2009-07-27 02:11

    我的代码里面也没有把高度设死呀,只要列表的每一行的宽度相同就可以,高度会动态的取出来的。
    如果lz觉得这种计算方式有不方便的地方的话,也可以通过其他方式实现。
    比如,往每一个列表项(JMenuItem)上添加鼠标事件,不过这种方式没有试过,不知道好不好用。还可以使用JList或JPanel+JTable来替代JPopupMenu,以加强控制力度等等。
    BasicComboBoxUI这个类好像也可以定制JComboBox。
    实现的方式是多种多样的,关键是尝试。

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题