JCombox-阿里云开发者社区

开发者社区> developerguy> 正文

JCombox

简介: A component that combines a button or editable field and a drop-down list. The user can select a value from the drop-down list, which appears at the user's request.
+关注继续查看

 

A component that combines a button or editable field and a drop-down list.
The user can select a value from the drop-down list, which appears at the user's request.
If you make the combo box editable, then the combo box includes an editable field into which the user can type a value. 

 

话说JComboBox 默认外观确实不是太好看..在由于本人有时实在太贱.就是想要它好看...所以..这不..又折腾了..

其实这个ComboBox 刚开始想改变外观 只考虑到renderer 毕竟swing上所有的界面 显示全靠renderer来控制..

所以 着手写ComboBoxRenderer. 总是觉的 JComboBox 似乎不太好搞定 因为它不但有显示框 还有小键头.

还有弹出的List 还有ScrollBar..等等.. 似乎不那么好搞...不过Swing是强大的 ..只要你能想到..就可以做到.

那么我们要做几件事.

1: 重载JComboBox 并且设置面板透明

2: 新建renderer 实现ListCellRenderer接口

3: 重载BasicComboBoxUI

1.重载JComboBox 并且设置面板透明 设置renderer 以及设置 ui

package swing.combox.customize;

import java.awt.Dimension;
import java.util.Vector;

import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;

public class IComboBox extends JComboBox {
    private static final long serialVersionUID = 1L;

    public IComboBox() {
        super();
        init();
    }

    public IComboBox(ComboBoxModel model) {
        super(model);
        init();
    }

    public IComboBox(Object[] items) {
        super(items);
        init();
    }

    public IComboBox(Vector items) {
        super(items);
        init();
    }

    private void init() {
        setOpaque(false);
        setUI(new IComboBoxUI());
        setRenderer(new IComboBoxRenderer());
        // setBackground(XUtil.defaultComboBoxColor);
    }

    public Dimension getPreferredSize() {
        return super.getPreferredSize();
    }
}

 

2.新建renderer 实现ListCellRenderer接口.注意.这里的ComboBoxRenderer它是控制combobox弹出的List 并非控制JComboBox的 注意 他实现的是ListCellRenderer

package swing.combox.customize;

import java.awt.Color;
import java.awt.Component;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

public class IComboBoxRenderer implements ListCellRenderer {

    private DefaultListCellRenderer defaultCellRenderer = new DefaultListCellRenderer();

    public IComboBoxRenderer() {
        super();
    }

    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {

        JLabel renderer = (JLabel) defaultCellRenderer.getListCellRendererComponent(
                list, value, index, isSelected, cellHasFocus);
        if (isSelected) {
            // renderer.setBackground(XUtil.defaultComboBoxBoundsColor);
            renderer.setForeground(Color.WHITE);
        } else {
            renderer.setBackground(Color.WHITE);
        }
        // list.setSelectionBackground(XUtil.defaultComboBoxColor);
        list.setBorder(null);
        // renderer.setFont(XUtil.defaultComboBoxFont);
        renderer.setHorizontalAlignment(JLabel.CENTER);
        return renderer;
    }
}

 

3.重载BasicComboBoxUI .sure 这里当然要注意.因为他是JComboBox的绘制机制

这里包括ComboBox右边的那个箭头的Button.(我们已经通过重写 createArrowButton 来改变这个Button);

至于弹出的List ,it in here, look it ..createPoput(); it create ComboPopup.(不好意思 最近在学英文 总是那么顺口来那么几句.)

这里存在一个ScrollPane 它包含了List.并且我们重写ScrollPane的paintBorder方法 来让我们画出List的Border

package swing.combox.customize;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;

public class IComboBoxUI extends BasicComboBoxUI {

    private JButton arrow;
    private boolean boundsLight = false;
    private static final int ARCWIDTH = 15;
    private static final int ARCHEIGHT = 15;

    public IComboBoxUI() {
        super();
    }

    protected JButton createArrowButton() {
        arrow = new JButton();
        // arrow.setIcon(XUtil.defaultComboBoxArrowIcon);
        arrow.setRolloverEnabled(true);
        // arrow.setRolloverIcon(XUtil.defaultComboBoxArrowIcon_Into);
        arrow.setBorder(null);
        // arrow.setBackground(XUtil.defaultComboBoxColor);
        arrow.setOpaque(false);
        arrow.setContentAreaFilled(false);
        return arrow;
    }

    public void paint(Graphics g, JComponent c) {
        hasFocus = comboBox.hasFocus();
        Graphics2D g2 = (Graphics2D) g;
        if (!comboBox.isEditable()) {
            Rectangle r = rectangleForCurrentValue();
            // 重点:JComboBox的textfield 的绘制 并不是靠Renderer来控制 这点让我很吃惊.

            // 它会通过paintCurrentValueBackground来绘制背景

            // 然后通过paintCurrentValue();去绘制JComboBox里显示的值

            paintCurrentValueBackground(g2, r, hasFocus);
            paintCurrentValue(g2, r, hasFocus);
        }

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        int width = (int) this.getPreferredSize(c).getWidth()
                + arrow.getWidth() - 2;
        int height = 0;
        int heightOffset = 0;
        if (comboBox.isPopupVisible()) {
            heightOffset = 5;
            height = (int) this.getPreferredSize(c).getHeight();
            // arrow.setIcon(XUtil.defaultComboBoxArrowIcon_Into);
        } else {
            heightOffset = 0;
            height = (int) this.getPreferredSize(c).getHeight() - 1;
            // arrow.setIcon(XUtil.defaultComboBoxArrowIcon);
        }
        if (comboBox.isFocusable()) {
            g2.setColor(new Color(150, 207, 254));
        }
        g2.drawRoundRect(0, 0, width, height + heightOffset, ARCWIDTH, ARCHEIGHT);
    }

    public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus) {
        Font oldFont = comboBox.getFont();
        // comboBox.setFont(XUtil.defaultComboBoxFont);

        super.paintCurrentValue(g, bounds, hasFocus);
        comboBox.setFont(oldFont);
    }

    public Dimension getPreferredSize(JComponent c) {
        return super.getPreferredSize(c);
    }

    public boolean isBoundsLight() {
        return boundsLight;
    }

    public void setBoundsLight(boolean boundsLight) {
        this.boundsLight = boundsLight;
    }

    protected ComboPopup createPopup() {
        ComboPopup popup = new BasicComboPopup(comboBox) {
            protected JScrollPane createScroller() {
                JScrollPane sp = new JScrollPane(list,
                        ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                        ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
                sp.setHorizontalScrollBar(null);
                return sp;
            }

            // 重载paintBorder方法 来画出我们想要的边框..

            public void paintBorder(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setColor(new Color(150, 207, 254));
                g2.drawRoundRect(0, -arrow.getHeight(), getWidth() - 1, getHeight() + arrow.getHeight() - 1, 0, 0);
            }
        };
        return popup;
    }
}

 

ok. 那么到这里 ComboBox这块已经end 但是似乎还有个问题存在 那就是createPopup 方法里的ScrollPane的滚动条还是有点丑.

so。.next 我们搞定 it.

1:继承 ScrollBar 并且 setUI();

2:继承 BasicScrollBarUI 我们来G出我们的效果.

paintThumb 绘制scrollbar里拖动的小box 我们先画个边框 and draw two Orange line.

paintTrack 绘制scrollbar里小box的轨迹.也就是那个啥(术语怎么说来着?拖拽滑块?).

注意:我们首先将Graphics设置透明后 在去画面板 然后立刻把Graphics设置为不透明..

这样是为了能让我们把轨迹左边边界画出来...

createIncreaseButton draw down arrowButton 小心 千万不要use JButton button = new JButton();

should use BasicArrowButton 不然你将无法click this button 并产生你想要的效果..

你猜的到 createDecreaseButton(); 方法是干什么的..(笨蛋 上面那个Button啦);

package swing.combox.customize;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicScrollBarUI;

public class IScrollBarUI extends BasicScrollBarUI {
    public IScrollBarUI() {
        super();
    }

    protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
        int width = thumbBounds.width;
        int height = thumbBounds.height;
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        g2.translate(thumbBounds.x, thumbBounds.y);
//        g2.setColor(XUtil.defaultComboBoxBoundsColor);
        g2.drawRoundRect(1, 1, width - 2, height - 2, 5, 5);

        g2.setColor(Color.ORANGE);
        g2.drawLine(3, height / 2, width - 4, height / 2);
        g2.drawLine(3, height / 2 + 3, width - 4, height / 2 + 3);
        g2.translate(-thumbBounds.x, -thumbBounds.y);
    }

    protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) {
//        g.setColor(XUtil.defaultComboBoxColor);
        int x = trackBounds.x;
        int y = trackBounds.y;
        int width = trackBounds.width;
        int height = trackBounds.height;
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setComposite(AlphaComposite
                .getInstance(AlphaComposite.SRC_OVER, 0.1f));

        g2.fill3DRect(x, y, width, height, true);
        g2.setComposite(AlphaComposite
                .getInstance(AlphaComposite.SRC_OVER, 1f));
//        g2.setColor(XUtil.defaultComboBoxBoundsColor.brighter());
        g2.fill3DRect(x, y, 1, height + 1, true);
        if (trackHighlight == DECREASE_HIGHLIGHT) {
            paintDecreaseHighlight(g);
        }
        else if (trackHighlight == INCREASE_HIGHLIGHT) {
            paintIncreaseHighlight(g);
        }
    }

    protected JButton createIncreaseButton(int orientation) {
        JButton button = new BasicArrowButton(orientation) {
            public void paint(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
//                g2.setColor(XUtil.defaultComboBoxBoundsColor);
                g2.drawLine(0, 0, 0, getHeight());
                g2.drawLine(0, 0, getWidth(), 0 - 1);
//                g2.drawImage(((ImageIcon) XUtil.defaultComboBoxArrowIcon_Into).getImage(), -1, 0, null);
            }
        };
        button.setOpaque(false);
        return button;
    }

    protected JButton createDecreaseButton(int orientation) {

        JButton button = new BasicArrowButton(orientation) {
            public void paint(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
//                g2.setColor(XUtil.defaultComboBoxBoundsColor);
                g2.drawLine(0, 0, 0, getHeight());
                g2.drawLine(0, getHeight() - 1, getWidth(), getHeight());
//                g2.drawImage(((ImageIcon) XUtil.defaultComboBoxArrowIcon_Into).getImage(), -1, 0, null);
            }
        };
        button.setOpaque(false);
        return button;
    }
}

 

http://blog.chinaunix.net/uid-12888785-id-2384253.html

 

 

http://www.blogjava.net/chensiyu04/archive/2011/03/27/346868.html

http://blog.sina.com.cn/s/blog_4e6d7e6901000bvm.html

http://blog.chinaunix.net/uid-12888785-id-2384254.html

http://www.2cto.com/kf/201103/86224.html

http://blog.csdn.net/bradwoo8621/article/details/1523118

 

http://blog.sina.com.cn/s/blog_4412ae250100062n.html

 

设置JComboBox中JList中元素的ToolTipText需要JComboBox.setRenderer(实现设置ToolTipText的ListCellRenderer);
设置JComboBox的ToolTipText需要JComboBox.addItemListener(new ItemListener()的itemStateChanged方法中调用JComboBox.setToolTipText("tips")

 

package swing.combox;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;

/*2015-6-1*/
public class ComboxDemo extends JFrame {
    private static final long serialVersionUID = 1L;

    public ComboxDemo() {
        this.setLayout(new FlowLayout());
        final JTextField text = new JTextField("test", 10);
        this.add(text);

        String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig", "Tiger", "Lion", "Egg", "Swan", "Goose", "Chinese sturgeon" };
        final JComboBox petList = new JComboBox(petStrings);
        this.add(petList);
        petList.setRenderer(new ListCellRendererImpl1());
        // petList.setRenderer(new ListCellRendererImpl2());
        petList.setPreferredSize(new Dimension(100, 20));
        petList.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                text.setText(petList.getSelectedItem().toString() + ":" + petList.getSelectedIndex());
                petList.setToolTipText(petList.getSelectedItem().toString());
            }
        });
        petList.setSelectedIndex(4);
        // petList.setSelectedItem("Swan");

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ComboxDemo comboBox = new ComboxDemo();
                comboBox.setDefaultCloseOperation(EXIT_ON_CLOSE);
                comboBox.setSize(400, 200);
                comboBox.setVisible(true);
                comboBox.setLocationRelativeTo(null);
            }
        });
    }

}

/**
 * for JList ToolTextTip
 */
class ListCellRendererImpl1 extends JTextField implements ListCellRenderer {
    private static final long serialVersionUID = 1L;

    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        String item = (value == null) ? "" : value.toString();
        setText(item);
        setBorder(null);
        list.setToolTipText("第" + index + "被选中:" + item);
        return this;
    }

}

class ListCellRendererImpl2 extends DefaultListCellRenderer {
    private static final long serialVersionUID = 1L;

    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        JComponent component = (JComponent) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        setToolTipText(value + ":" + index);
        return component;
    }

    @Override
    public void setToolTipText(String text) {
        super.setToolTipText(text);
    }

}

 


 

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
怎么设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程
6907 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
2841 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4478 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
7751 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
5456 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
9424 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
2138 0
+关注
developerguy
A code cleanliness code farmers, A programmer concentrate on elegant design, A want to do with the product architect
1663
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载