去掉JComboBox选择后的背景色

这段时间项目上需要用 JComboBox,用上发现这个JComboBox真是问题多多,其中一个烦人的问题就是选择一个item后,显示出了一个难看的背景,查找了很多方法,发现其实是在BasicComboBoxUI.paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus )中的多余的调用:

        if( hasFocus && ! isPopupVisible( comboBox ) )
        {
            c.setForeground( listBox.getSelectionForeground() );

            c.setBackground( listBox.getSelectionBackground() );
        }

我开始想在 popupMenuWillBecomeInvisible中用listBox.setSelectionForeground( Color.WHITE ),但是这要用到反射,并且要用setAccessible,一旦SUN以后改了listBox的名字,这会出问题的,心灰意冷之时,忽然想到可以把 JComboBox的ListCellRenderer给它设成透明的,setOpaque(),这样,当选择完成后,不就只画JComboBox的背景了吗?如下是代码:

class TestComboFocus extends javax.swing.JFrame implements javax.swing.event.PopupMenuListener
{
    private javax.swing.JComboBox combo;

    public TestComboFocus( String title )
    {
        super( title );

        combo = new javax.swing.JComboBox( new String[]{ "one person in this city", "two persons in this city" } );

        combo.addPopupMenuListener( this );

        combo.setBackground( java.awt.Color.WHITE ); hideComboFocus( false );

        this.getContentPane().setLayout( new java.awt.FlowLayout() );

        this.getContentPane().add( combo );

        this.setBounds( 100, 100, 400, 300 );

        this.setVisible( true );
    }

    public void popupMenuCanceled( javax.swing.event.PopupMenuEvent e ){}

    public void popupMenuWillBecomeVisible( javax.swing.event.PopupMenuEvent e )
    {
        System.err.println( "popupMenuWillBecomeVisible" );

        hideComboFocus( true );
    }

    public void popupMenuWillBecomeInvisible( javax.swing.event.PopupMenuEvent e )
    {
        System.err.println( "popupMenuWillBecomeInvisible" );

        hideComboFocus( false );
    }

    private final void hideComboFocus( boolean hidden )
    {
        if( combo == null ){ return; }

        javax.swing.ListCellRenderer comp = combo.getRenderer();

        if( comp instanceof javax.swing.JComponent ){ ( (javax.swing.JComponent)comp ).setOpaque( hidden ); }
    }

    public static void main( String[] args ){ new TestComboFocus( "Test ComboFocus" ); }
}

2010.10.19补充,最近研究CellRendererPane,发现这个去掉背景色还有个更好的办法:

将JComboBox设置为可编辑,将里面的Editor(其实就是JTextField)设置为不可编辑,设置选择颜色为白色,如下:

public class TestComboFocus2 extends javax.swing.JFrame
{
    private javax.swing.JComboBox combo;

    public TestComboFocus2( String title )
    {
        super( title );

        this.getContentPane().setLayout( new java.awt.FlowLayout() );

        this.getContentPane().add( combo = new javax.swing.JComboBox( new String[]{ "one person in this city", "two persons in this city" } ) );

        this.setBounds( 100, 100, 400, 300 );

        this.setVisible( true );

        this.disableFocusBackground( combo );
    }

    private void disableFocusBackground( javax.swing.JComboBox combo )
    {
        if( combo == null ){ return; }

        java.awt.Component comp = combo.getEditor().getEditorComponent();

        if( comp instanceof javax.swing.JTextField )
        {
            javax.swing.JTextField field = (javax.swing.JTextField)comp;

            field.setEditable( false );

            field.setSelectionColor( field.getBackground()/*java.awt.Color.WHITE*/ );

            combo.setEditable( true );
        }
    }

    public static void main( String[] args ){ new TestComboFocus2( "Test ComboFocus2" ); }
}

class NoBackgroundComboBoxUI extends javax.swing.plaf.basic.BasicComboBoxUI
{
    protected java.awt.Rectangle rectangleForCurrentValue()
    {
        java.awt.Rectangle rect = super.rectangleForCurrentValue();

        //The root cause is that this method return an invalid Rectangle, so it limited the bounds of Graphics

        return rect;
    }
}





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值