2012-10-08 23 views
2

我想要一个ComboBox显示一些不同的线条样式,如实线,虚线,虚线等。Java Swing:如何渲染具有不同线条样式的组合框?

如何创建一个自定义渲染来完成此操作?

谢谢大家。

+1

你有什么试过的?您可以使用JPanel作为渲染器并在面板中画线,或者可以使用代表每行的ImageIcons并使用DefaultListCellRenderer的子类。 –

+0

嗨JB Nizet,你能提供一些行代码作为例子吗? –

+0

是:http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html#renderer –

回答

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(); 
      } 
     }); 
    } 
} 
+0

@ Guillaume Polet 精彩,伟大的工作,非常感谢! –

1

看看这个answer,我给了一个定制的JComboBox编辑器。在该解决方案中,我扩展了BasicComboBoxEditor类,修改了编辑组件,并在setEditor()中使用了该实例。

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

+2

您确实不应该使用UI委托代码来执行此任务。这就是[ComboBoxEditor](http://docs.oracle.com/javase/7/docs/api/javax/swing/ComboBoxEditor.html)和[ListCellRenderer](http://docs.oracle.com/javase/) 7/docs/api/javax/swing/ListCellRenderer.html)接口。以这种方式使用类似'BasicComboBoxRenderer'的东西可能会危及应用程序的外观和感觉 – MadProgrammer