zoukankan      html  css  js  c++  java
  • 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.
    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);
        }
    
    }


     

  • 相关阅读:
    【洛谷 2212】浇地Watering the Fields
    【洛谷 2504】聪明的猴子
    【洛谷 1991】无线通讯网
    【洛谷 3366】最小生成树_Prim
    Spark RDD中两种算子之一:常见Action算子小结
    Spark学习之路Spark之RDD
    Linux系统之pssh系列工具的使用
    MapReduce shuffle过程详解
    批量计算和流式计算
    关于IDEA破解后无法启动问题
  • 原文地址:https://www.cnblogs.com/softidea/p/4613881.html
Copyright © 2011-2022 走看看