Java - 如何显示一个输入对话框,其中包含一个下拉列表,每个项目都有一个图标?
Java - How to show an input dialog having a dropdown list with an icon for each item?
我在我的 swing 应用程序中使用这个 Java 代码来显示一个输入对话框,其中有一个下拉 selection 列表,因此用户可以 select 从中选择一个项目名单:
String[] carModelsArray = { "Honda", "Mitsubishi", "Toyota" };
String selectedValue = (String)JOptionPane.showInputDialog( null, "Select a car model from the list below:", "Car model...",
JOptionPane.QUESTION_MESSAGE,
null,
carModelsArray,
carModelsArray[ 0 ] );
这段代码工作正常,但我想知道我是否也可以为 selection 列表中的每个项目添加一个图标,所以下拉列表 selection 列表将如下所示:
我尝试将此列表中的项目设置为 JLabel 项目,但在下拉列表中呈现时,JLabel 对象全部转换为字符串值,就好像它调用 JLabel.toString() 方法一样为列表中的每个项目获取其值。
那么有没有办法做到这一点?
简短的回答,不是你这样做的方式。长答案,更像是...
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.kaizen.icons.AddIcon;
import org.kaizen.icons.DeleteIcon01;
import org.kaizen.icons.DeleteIcon02;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
DefaultComboBoxModel model = new DefaultComboBoxModel<Car>();
model.addElement(new Car(new AddIcon(16, 16), "Honda"));
model.addElement(new Car(new DeleteIcon01(16, 16), "Mitsubishi"));
model.addElement(new Car(new DeleteIcon02(16, 16), "Tyota"));
JComboBox cb = new JComboBox(model);
cb.setRenderer(new CarListCellRenderer());
int result = JOptionPane.showConfirmDialog(null, cb, "Select a car model from the list below", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
Car car = (Car) cb.getSelectedItem();
}
}
});
}
public static class CarListCellRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
System.out.println(value);
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof Car) {
Car car = (Car) value;
setIcon(car.getIcon());
setText(car.getText());
} else {
setIcon(null);
}
return this;
}
}
public static class Car {
private Icon icon;
private String text;
public Car(Icon icon, String text) {
this.icon = icon;
this.text = text;
}
public Icon getIcon() {
return icon;
}
public String getText() {
return text;
}
}
}
基本上,您需要控制组合框并提供您自己的自定义 ListCellRedender
,它可以提供您想要的输出...
感谢 MadProgrammer 的有用回答,我能够使用他的想法找到解决方案。最终结果如下所示:
这是我使用的代码:
public class MyClass extends JFrame {
private JComboBox inputComboBox = null;
private void button6ActionPerformed() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JPanel inputPanel = createPanel();
int result = JOptionPane.showConfirmDialog(null, inputPanel, "Car model...", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
System.out.println( (String)inputComboBox.getSelectedItem() );
}
}
});
}
private JPanel createPanel() {
CellConstraints cc = new CellConstraints();
//1. Create JPanel :
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new FormLayout(
new ColumnSpec[] {
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13))
},
new RowSpec[] {
new RowSpec(Sizes.dluY(13)),
FormFactory.LINE_GAP_ROWSPEC,
new RowSpec(Sizes.dluY(13)),
FormFactory.LINE_GAP_ROWSPEC,
new RowSpec(Sizes.dluY(13))
}));
//2. Create JLabel :
JLabel inputLabel = new JLabel( "Select a car model from the list below :" );
inputPanel.add( inputLabel, cc.xywh( 1, 1, 15, 1 ) );
//3. Create ComboBox :
DefaultComboBoxModel model = new DefaultComboBoxModel();
model.addElement("Honda");
model.addElement("Mitsubishi");
model.addElement("Toyota");
inputComboBox = new JComboBox( model );
inputComboBox.setRenderer( new ComboBoxRenderer() );
inputPanel.add( inputComboBox, cc.xywh(1, 3, 10, 2 ) );
return inputPanel;
}
}
class ComboBoxRenderer extends JLabel implements ListCellRenderer {
public Component getListCellRendererComponent(
JList list,
Object selectedCarModel,
int selectedModelIndex,
boolean isSelected,
boolean cellHasFocus) {
//1. Set the list item text, icon & styling properties :
String carModel = (String)selectedCarModel;
String iconPath = "/images/" + carModel.toLowerCase() + ".png"; // The icon file should have the same name of the car model.
URL iconURL = getClass().getResource( iconPath );
setText( carModel );
setIcon( new ImageIcon( iconURL ) );
setPreferredSize( new Dimension( list.getWidth(), 30 ) );
//2. Set the selected/deselected list item selection colors :
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
return this;
}
}
我在我的 swing 应用程序中使用这个 Java 代码来显示一个输入对话框,其中有一个下拉 selection 列表,因此用户可以 select 从中选择一个项目名单:
String[] carModelsArray = { "Honda", "Mitsubishi", "Toyota" };
String selectedValue = (String)JOptionPane.showInputDialog( null, "Select a car model from the list below:", "Car model...",
JOptionPane.QUESTION_MESSAGE,
null,
carModelsArray,
carModelsArray[ 0 ] );
这段代码工作正常,但我想知道我是否也可以为 selection 列表中的每个项目添加一个图标,所以下拉列表 selection 列表将如下所示:
我尝试将此列表中的项目设置为 JLabel 项目,但在下拉列表中呈现时,JLabel 对象全部转换为字符串值,就好像它调用 JLabel.toString() 方法一样为列表中的每个项目获取其值。
那么有没有办法做到这一点?
简短的回答,不是你这样做的方式。长答案,更像是...
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.kaizen.icons.AddIcon;
import org.kaizen.icons.DeleteIcon01;
import org.kaizen.icons.DeleteIcon02;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
DefaultComboBoxModel model = new DefaultComboBoxModel<Car>();
model.addElement(new Car(new AddIcon(16, 16), "Honda"));
model.addElement(new Car(new DeleteIcon01(16, 16), "Mitsubishi"));
model.addElement(new Car(new DeleteIcon02(16, 16), "Tyota"));
JComboBox cb = new JComboBox(model);
cb.setRenderer(new CarListCellRenderer());
int result = JOptionPane.showConfirmDialog(null, cb, "Select a car model from the list below", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
Car car = (Car) cb.getSelectedItem();
}
}
});
}
public static class CarListCellRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
System.out.println(value);
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof Car) {
Car car = (Car) value;
setIcon(car.getIcon());
setText(car.getText());
} else {
setIcon(null);
}
return this;
}
}
public static class Car {
private Icon icon;
private String text;
public Car(Icon icon, String text) {
this.icon = icon;
this.text = text;
}
public Icon getIcon() {
return icon;
}
public String getText() {
return text;
}
}
}
基本上,您需要控制组合框并提供您自己的自定义 ListCellRedender
,它可以提供您想要的输出...
感谢 MadProgrammer 的有用回答,我能够使用他的想法找到解决方案。最终结果如下所示:
这是我使用的代码:
public class MyClass extends JFrame {
private JComboBox inputComboBox = null;
private void button6ActionPerformed() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JPanel inputPanel = createPanel();
int result = JOptionPane.showConfirmDialog(null, inputPanel, "Car model...", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
System.out.println( (String)inputComboBox.getSelectedItem() );
}
}
});
}
private JPanel createPanel() {
CellConstraints cc = new CellConstraints();
//1. Create JPanel :
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new FormLayout(
new ColumnSpec[] {
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13)),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
new ColumnSpec(Sizes.dluX(13))
},
new RowSpec[] {
new RowSpec(Sizes.dluY(13)),
FormFactory.LINE_GAP_ROWSPEC,
new RowSpec(Sizes.dluY(13)),
FormFactory.LINE_GAP_ROWSPEC,
new RowSpec(Sizes.dluY(13))
}));
//2. Create JLabel :
JLabel inputLabel = new JLabel( "Select a car model from the list below :" );
inputPanel.add( inputLabel, cc.xywh( 1, 1, 15, 1 ) );
//3. Create ComboBox :
DefaultComboBoxModel model = new DefaultComboBoxModel();
model.addElement("Honda");
model.addElement("Mitsubishi");
model.addElement("Toyota");
inputComboBox = new JComboBox( model );
inputComboBox.setRenderer( new ComboBoxRenderer() );
inputPanel.add( inputComboBox, cc.xywh(1, 3, 10, 2 ) );
return inputPanel;
}
}
class ComboBoxRenderer extends JLabel implements ListCellRenderer {
public Component getListCellRendererComponent(
JList list,
Object selectedCarModel,
int selectedModelIndex,
boolean isSelected,
boolean cellHasFocus) {
//1. Set the list item text, icon & styling properties :
String carModel = (String)selectedCarModel;
String iconPath = "/images/" + carModel.toLowerCase() + ".png"; // The icon file should have the same name of the car model.
URL iconURL = getClass().getResource( iconPath );
setText( carModel );
setIcon( new ImageIcon( iconURL ) );
setPreferredSize( new Dimension( list.getWidth(), 30 ) );
//2. Set the selected/deselected list item selection colors :
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
return this;
}
}