I would like to create JComboBox
control similar with the URL textbox of Firefox. Does anyone know how to customize the textfield of the JComboBox
. I want to add some icons on the ALIGN.HORIZONTAL_RIGHT
near the arrow button of the JComboBox
我想创建类似于Firefox的URL文本框的JComboBox控件。有谁知道如何自定义JComboBox的文本字段。我想在JComboBox的箭头按钮附近的ALIGN.HORIZONTAL_RIGHT上添加一些图标
Thanks for your very detail explanation. Actually I will combine DefaultListCellRenderer
and add the icon to the combo box like following code
感谢您的详细解释。实际上我将组合DefaultListCellRenderer并将图标添加到组合框,如下面的代码
import java.awt.Dimension;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Main extends JFrame {
public Main() {
// Create icon "C"
JButton jb = new JButton("C");
jb.setMargin(new Insets(0, 0, 0, 0));
jb.setBounds(245, 2, 18, 18);
// Create combo box
String[] languages = new String[]{"Java", "C#", "PHP"};
JComboBox jc = new JComboBox(languages);
// jc.setEditable(true);
jc.add(jb);
getContentPane().add(jc);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(300, 58));
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
final Main main = new Main();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
main.setVisible(true);
}
});
}
}
But when I put jc.setEditable(true)
; the combo editor hided my icon. I'm thinking another way to simulate Firefox awesome bar. Do you have any idea for this?
但是当我把jc.setEditable(true);组合编辑隐藏了我的图标。我正在考虑另一种模拟Firefox真棒的方法。你对此有什么想法吗?
2 个解决方案
#1
Here is completed example that demonstrate it:
以下是完成示例演示:
package com.demo.combo.icon;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ShowConboWithIcons extends JFrame {
private static final long serialVersionUID = 1L;
private static final ImageIcon INFO_ICON = new ImageIcon("info.png");
private static final ImageIcon NONE_ICON = new ImageIcon("none.png");
public final String NONE_STR = "None";
private final String INFO_STR = "Info";
private JComboBox comboBox;
private JPanel topPanel;
private String[] str_arr = null;
public ShowConboWithIcons(String[] str_arr) {
this.str_arr = str_arr;
}
public void createGUI(){
setMinimumSize(new Dimension(100,100));
setTitle("Demo");
setLocation(200, 200);
topPanel = new JPanel();
getContentPane().add(topPanel, BorderLayout.CENTER);
Map<Object, Icon> icons = new HashMap<Object, Icon>();
icons.put(NONE_STR, NONE_ICON);
icons.put(INFO_STR, INFO_ICON);
comboBox = new JComboBox();
comboBox.setRenderer(new IconListRenderer(icons));
comboBox.addItem("None");
for(String val : str_arr){
comboBox.addItem(val);
}
topPanel.add(comboBox);
super.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
String[] str_arr = {"A", "B", "C", "D", "E"};
ShowConboWithIcons T = new ShowConboWithIcons(str_arr);
T.createGUI();
T.setVisible(true);
}
class IconListRenderer extends DefaultListCellRenderer{
private static final long serialVersionUID = 1L;
private Map<Object, Icon> icons = null;
public IconListRenderer(Map<Object, Icon> icons){
this.icons = icons;
}
@Override
public Component getListCellRendererComponent(JList list, Object value, int index,boolean isSelected, boolean cellHasFocus)
{
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
// Get icon to use for the list item value
Icon icon = icons.get(value);
if(!value.toString().equals(NONE_STR)){
icon = icons.get(INFO_STR);
}
// Set icon to display for value
label.setIcon(icon);
return label;
}
}
}
Preview:
#2
To change how a component renders, you generally work with what are called Renderer
s.
要更改组件的呈现方式,通常使用所谓的渲染器。
For combobox, look at how to create a custom combobox renderer. Just a quick glance, but for your case, a simple configuration of DefaultListCellRenderer
may be enough, since you can set the JLabel
properties to position the text to the image. If not, just extend from it.
对于组合框,请查看如何创建自定义组合框渲染器。只需快速浏览一下,但对于您的情况,DefaultListCellRenderer的简单配置可能就足够了,因为您可以设置JLabel属性以将文本定位到图像。如果没有,只需从中扩展即可。
Remember also that you have to set a model that includes the icon so that the combobox renderer can get it - might want to do a custom ComboBoxModel
too, depending on your data object.
还要记住,您必须设置一个包含图标的模型,以便组合框渲染器可以获取它 - 可能也想要自定义ComboBoxModel,具体取决于您的数据对象。
#1
Here is completed example that demonstrate it:
以下是完成示例演示:
package com.demo.combo.icon;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ShowConboWithIcons extends JFrame {
private static final long serialVersionUID = 1L;
private static final ImageIcon INFO_ICON = new ImageIcon("info.png");
private static final ImageIcon NONE_ICON = new ImageIcon("none.png");
public final String NONE_STR = "None";
private final String INFO_STR = "Info";
private JComboBox comboBox;
private JPanel topPanel;
private String[] str_arr = null;
public ShowConboWithIcons(String[] str_arr) {
this.str_arr = str_arr;
}
public void createGUI(){
setMinimumSize(new Dimension(100,100));
setTitle("Demo");
setLocation(200, 200);
topPanel = new JPanel();
getContentPane().add(topPanel, BorderLayout.CENTER);
Map<Object, Icon> icons = new HashMap<Object, Icon>();
icons.put(NONE_STR, NONE_ICON);
icons.put(INFO_STR, INFO_ICON);
comboBox = new JComboBox();
comboBox.setRenderer(new IconListRenderer(icons));
comboBox.addItem("None");
for(String val : str_arr){
comboBox.addItem(val);
}
topPanel.add(comboBox);
super.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
String[] str_arr = {"A", "B", "C", "D", "E"};
ShowConboWithIcons T = new ShowConboWithIcons(str_arr);
T.createGUI();
T.setVisible(true);
}
class IconListRenderer extends DefaultListCellRenderer{
private static final long serialVersionUID = 1L;
private Map<Object, Icon> icons = null;
public IconListRenderer(Map<Object, Icon> icons){
this.icons = icons;
}
@Override
public Component getListCellRendererComponent(JList list, Object value, int index,boolean isSelected, boolean cellHasFocus)
{
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
// Get icon to use for the list item value
Icon icon = icons.get(value);
if(!value.toString().equals(NONE_STR)){
icon = icons.get(INFO_STR);
}
// Set icon to display for value
label.setIcon(icon);
return label;
}
}
}
Preview:
#2
To change how a component renders, you generally work with what are called Renderer
s.
要更改组件的呈现方式,通常使用所谓的渲染器。
For combobox, look at how to create a custom combobox renderer. Just a quick glance, but for your case, a simple configuration of DefaultListCellRenderer
may be enough, since you can set the JLabel
properties to position the text to the image. If not, just extend from it.
对于组合框,请查看如何创建自定义组合框渲染器。只需快速浏览一下,但对于您的情况,DefaultListCellRenderer的简单配置可能就足够了,因为您可以设置JLabel属性以将文本定位到图像。如果没有,只需从中扩展即可。
Remember also that you have to set a model that includes the icon so that the combobox renderer can get it - might want to do a custom ComboBoxModel
too, depending on your data object.
还要记住,您必须设置一个包含图标的模型,以便组合框渲染器可以获取它 - 可能也想要自定义ComboBoxModel,具体取决于您的数据对象。