Swing不丑系列:JComboBox(一)

2014-11-24 00:38:46 · 作者: · 浏览: 2

一直都是一只菜鸟..不管别人怎么说.
一直认为Swing不丑..所以打算这段时间写个Swing不丑系列(献丑了)

\-------------------------->>>>>>\


话说JComboBox 默认外观确实不是太好看..在由于本人有时实在太贱.就是想要它好看...所以..这不..又折腾了..
其实这个ComboBox 刚开始想改变外观 只考虑到renderer 毕竟swing上所有的界面 显示全靠renderer来控制..
所以 着手写ComboBoxRenderer. 总是觉的 JComboBox 似乎不太好搞定 因为它不但有显示框 还有小键头.
还有弹出的List 还有ScrollBar..等等.. 似乎不那么好搞...不过Swing是强大的 ..只要你能想到..就可以做到.


那么我们要做几件事.
1: 重载JComboBox 并且设置面板透明
2: 新建renderer 实现ListCellRenderer接口
3: 重载BasicComboBoxUI

1.重载JComboBox 并且设置面板透明 设置renderer 以及设置 ui
public class IComboBox extends JComboBox{

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
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

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