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);
    }

}

 


 

 

相关文章
|
Java 开发工具 开发者
IDEA插件开发.01之简单入门
闲着没事,动手实现一个简单idea插件。
256 1
IDEA插件开发.01之简单入门
|
数据可视化 Java
《IntelliJ IDEA 插件开发》第二节:开发摸鱼看书的侧边栏窗体
一、说明 二、需求目的 三、案例开发 1. 工程结构 2. 创建 UI 窗体 3. ToolWindow 工具框 4. Configurable 配置框 5. 配置 plugin.xml 四、插件测试 五、总结 六、系列推荐
1017 0
《IntelliJ IDEA 插件开发》第二节:开发摸鱼看书的侧边栏窗体
|
easyexcel 程序员 数据库
easyExcel的使用小结
今天带来的是esayExcel的简单使用小结,一个高效的Excel的处理框架
|
Java
JTable设置列宽、自动调整
下面這個方法 你可以用來設置列寬,在你需要的地方調用一下就可以了 Java code public void FitTableColumns(JTable myTable) {               //設置table的列寬隨內容調整         JTableHeader header = myTable.getTableH
2471 0
|
3天前
|
弹性计算 安全 API
访问控制(RAM)|云上安全使用AccessKey的最佳实践
集中管控AK/SK的生命周期,可以极大降低AK/SK管理和使用成本,同时通过加密和轮转的方式,保证AK/SK的安全使用,本次分享为您介绍产品原理,以及具体的使用步骤。
101779 0
|
4天前
|
SQL 关系型数据库 分布式数据库
Doodle Jump — 使用Flutter&Flame开发游戏真不错!
用Flutter&Flame开发游戏是一种什么体验?最近网上冲浪的时候,我偶然发现了一个国外的游戏网站,类似于国内的4399。在浏览时,我遇到了一款经典的小游戏:Doodle Jump...
|
11天前
|
弹性计算 运维 安全
访问控制(RAM)|云上程序使用临时凭证的最佳实践
STS临时访问凭证是阿里云提供的一种临时访问权限管理服务,通过STS获取可以自定义时效和访问权限的临时身份凭证,减少长期访问密钥(AccessKey)泄露的风险。本文将为您介绍产品原理,以及具体的使用步骤。
151031 4