2

我想要一个 ComboBox 显示一些不同的线条样式,例如实线、点线、虚线等。

如何创建自定义渲染来完成此任务?

谢谢大家。

4

2 回答 2

6

这样做的好方法是使用 CustomRenderer。您可以使用预定义的图像或动态绘制线条笔触。以下是后一种选项的示例:

import java.awt.BasicStroke;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.UnsupportedLookAndFeelException;

public class TestComboBox {

    private static enum LineType {

        PLAIN {
            @Override
            public Stroke getStroke() {
                return new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 1.0f, new float[] { 1.0f }, 1);
            }
        },
        DOTTED {
            @Override
            public Stroke getStroke() {
                return new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 1.0f, new float[] { 0.1f, 5.0f }, 1);
            }

        },
        DASHED {
            @Override
            public Stroke getStroke() {
                return new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 1.0f, new float[] { 3.0f, 3.0f }, 1);
            }

        };
        public abstract Stroke getStroke();
    }

    public class LineRenderer extends JPanel implements ListCellRenderer {
        private LineType value;

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            if (value instanceof LineType) {
                setLineType((LineType) value);
            } else {
                setLineType(null);
            }
            return this;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            if (value != null) {
                g2d.setStroke(value.getStroke());
                g.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
            }

        }

        private void setLineType(LineType value) {
            this.value = value;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(50, 20);
        }

    }

    protected void initUI() {
        final JFrame frame = new JFrame(TestComboBox.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel(new GridBagLayout());
        final JComboBox comboBox = new JComboBox(LineType.values());
        comboBox.setRenderer(new LineRenderer());
        comboBox.setSelectedItem(null);
        comboBox.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        JOptionPane.showMessageDialog(comboBox, "You have selected " + comboBox.getSelectedItem());
                    }
                });
            }
        });
        panel.add(comboBox);
        frame.add(panel);
        frame.setSize(300, 100);
        frame.setVisible(true);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestComboBox().initUI();
            }
        });
    }
}
于 2012-10-08T21:24:13.090 回答
1

看看我为自定义编辑器提供的这个答案。JComboBox在那个解决方案中,我扩展了BasicComboBoxEditor类,修改了编辑组件并在setEditor().

同样,您可以根据需要扩展BasicComboBoxRenderer、修改渲染组件的边框,然后使用setRenderer()将它的新实例设置为您的JComboBox.

于 2012-10-08T19:45:05.867 回答