Inserterting JLabel into JComboBox - java

http://prntscr.com/1gpdqe
Sorry for the link it's my first time in this forum.
Can anyone please help me?
I've been trying to make an image and a text show together in one line on a JComboBox, after searching on sites, I could not find a solution to my problem.
The JLabel above the JLabel works but the JLabel in the JComboBox doesn't.

Maybe this example will sort things out:
On getListCellRendererComponent I used Label + 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;
}
}
}

Don't insert a JLabel into a JComboBox. Use a ListCellRenderer instead. Read Providing a Custom Renderer

Related

Display the selection of the combo Box in the Selection panel's text field

I am trying to display the selection of the combo Box in the Selection panel's text field
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Department extends JFrame {
private static final long serialVersionUID = 1L;
public static final String Art = "Art";
public static final String Biology = "Biology";
public static final String Chemistry = "Chemistry";
public static final String Computer_Science = "Computer_Science";
public static final String Economics = "Economics";
public static final String History = "History";
public static final String Music = "Music";
public static final String Philosophy = "Philosophy";
public static final String Physics = "Physics";
public static final String Psycholgy = "Psychology";
public static final String Psychology = "Psychology";
//constructor
public Department() {
setSize(700, 150);
setLocationRelativeTo(null);
setVisible(true);// making the frame visible
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Banner Self Service For Brahmbhatt");
TermPanel();
}
//400 width and 500 height
//private method with components
private void TermPanel() {
//base panel
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.setSize(700, 190);
panel.setBackground(Color.darkGray);
JPanel selectionPanel = new JPanel();
selectionPanel.setSize(10, 10);
selectionPanel.setLayout(new GridLayout(1, 1));
JTextField zodiacSign = new JTextField(10);
//adding the instructions for creating the birthday panel
JPanel birthdayPanel = new JPanel();
//uSING Grid layout
birthdayPanel.setLayout(new GridLayout(1,1));
birthdayPanel.add(new JLabel("Select A Department: "));
birthdayPanel.setBackground(new Color(250, 230, 230));
String[] choices = { "","Art","Biology",
"Chemistry","Computer_Science","Economics","English", "History", "Music",
"Mathematics", "Philosophy", "Physics", "Psychology"};
//Creating a comboBox
final JComboBox<String> cb = new JComboBox<String>(choices);
cb.setVisible(true);
birthdayPanel.add(cb);
panel.add(birthdayPanel);
getContentPane().add(panel);
JTextField textField = null;
//Panels for the selection term field
zodiacSign.setEnabled(true);//so that no one can use it as input field
zodiacSign.setEditable(true);//so that no one can edit the zodiac sign
selectionPanel.add(zodiacSign); // adding the zodiacsign textfield to panel
zodiacSign.setMaximumSize(new Dimension(1000, 500)); //setting minimu
dimensions for the zodiac panel
zodiacSign.setMinimumSize(new Dimension(500, 150)); //setting minimum
dimensions for the zodia
selectionPanel.setBorder(BorderFactory.createTitledBorder("Your Selection
is"));
selectionPanel.setBackground(new Color(250, 230, 230));
panel.add(selectionPanel);
// Adds an action listener
cb.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent event)
{
JComboBox cb = (JComboBox) event.getSource();
Object selected = cb.getSelectedItem();
textField.setText((String) cb.getSelectedItem());
}
});
getContentPane().add(panel);
}
}
You didn't post your other code, so I guess you forgot to add the listener to the JComboBox.
If this method is declared in an ActionListener object, you can do this to add this listener to your JComboBox
JComboBox cb = new JComboBox(); //sample declaration
cb.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//do your stuff here
}
});

JComboBox with JTable as ListCellRenderer component

I am currently working on a JComboBox component where I want to have a JTable inside of a ComboBox for a drop down selection. I have extended the ListCellRenderer and I have the table inside of the popup.
I want to present it two different ways. The first as a label of a bound column of the selected row when the popup is not visible. The second is to show the table with a JScrollPane when the popup is visible.
Unfortunately, When I do this the popup is being shrunk to the row height of the list which only leaves room for the columns of the table.
If I just use the scrollpane I can see the full table but then when the popup is not visible I see the table inside the combobox which is not what I want.
How can I set the height such that the table can fit while still being able to show the label only when the popup is not visible?
Below is a minimal example that compiles and runs:
import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListCellRenderer;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
public class TableComboBoxMain {
public static void main(String[] args) {
JTableComboBox<Employee> combo = new JTableComboBox<>();
combo.addItem(new Employee("April",3));
//combo.setMaximumRowCount(10);
combo.setRenderer(new TableListCellRenderer(combo));
JFrame frame = new JFrame("Test Table Combo Box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(combo);
frame.pack();
frame.setVisible(true);
}
public static class Employee{
String name;
int nr;
public Employee(String name, int number ){
this.name =name;
this.nr = number;
}
}
public static class JTableComboBox<E> extends JComboBox<E> implements ListSelectionListener{
#Override
public void valueChanged(ListSelectionEvent e) {System.out.println("Row selected"+e.getFirstIndex());
this.setSelectedIndex(e.getFirstIndex());
}
}
public static class TableListCellRenderer extends JScrollPane implements ListCellRenderer{
JTable table;
JTableComboBox combo;
boolean mouseListenerAdded;
public TableListCellRenderer(JTableComboBox combo){
this.combo=combo;
DefaultTableModel model = new DefaultTableModel();
String[] cols1 = new String[]{"1","2","3","4"};
String[] cols2 = new String[]{"Mark","John","April","Mary"};
model.addColumn("Nr", cols1);model.addColumn("Name",cols2);
table = new JTable(model);table.setShowGrid(true);table.setGridColor(Color.gray);
this.getViewport().add(table);
}
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if(!mouseListenerAdded){
list.addMouseListener(this.getListener());
mouseListenerAdded = true;
}//If this is uncommented then the BasicComboPopup size is always no more than 1 row?!!
if(!combo.isPopupVisible()){
Employee emp = (Employee) value;
return new JLabel(emp.name);
}else
return this;
}
public MouseAdapter getListener(){
MouseAdapter adapter = new MouseAdapter(){
#Override
public void mousePressed(MouseEvent e) {
if(combo.isPopupVisible()){
System.out.println("MouseClicked over list");
int row = table.rowAtPoint(e.getPoint());
if(row>0){
table.setRowSelectionInterval(row-1, row-1);
ListDataEvent event = new ListDataEvent(combo,ListDataEvent.CONTENTS_CHANGED,row-1,row-1);
combo.contentsChanged(event);
}
}
}
};
return adapter;
}
}
}
So I found a solution to the problem. I am not finished yet because there are a few interactions I still want to have:
I want to be able to move columns
I want to be able have popup menu for columns
I want to be able to scroll vertically with the mouse
I wanted to post the solution in case anyone else wants a starting point example. I will update my answer as I solve these additional issues.
Below is the test class:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.table.DefaultTableModel;
public class TableComboBoxMain {
public static void main(String[] args) {
JTableComboBox<String> combo = new JTableComboBox<>();
combo.addItem("");
BasicComboBoxUI ui = new BasicComboBoxUI(){
#Override
protected ComboPopup createPopup() {
return new BasicComboPopup( comboBox ){
#Override
protected int getPopupHeightForRowCount(int maxRowCount) {
return 100;
}
#Override
protected JScrollPane createScroller() {
JScrollPane sp = new JScrollPane( list,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED );
sp.getHorizontalScrollBar().setFocusable( false );
return sp;
}
};
}
};
combo.setUI(ui);
combo.setRenderer(new TableListCellRenderer(combo));
JFrame frame = new JFrame("Test Table Combo Box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(combo);
frame.pack();
frame.setVisible(true);
}
public static class Employee{
String name;
int nr;
public Employee(String name, int number ){
this.name =name;
this.nr = number;
}
}
public static class JTableComboBox<E> extends JComboBox<E> implements ListSelectionListener{
#Override
public void valueChanged(ListSelectionEvent e) {
System.out.println("Row selected"+e.getFirstIndex());
this.setSelectedIndex(e.getFirstIndex());
}
}
public static class TableListCellRenderer extends DefaultListCellRenderer{
JTable table;
JTableComboBox combo;
JPanel renderer = new JPanel();
JPanel colHeader = new JPanel();
JScrollPane scroll = new JScrollPane();
boolean mouseListenerAdded;
public TableListCellRenderer(JTableComboBox combo){
this.combo=combo;
DefaultTableModel model = new DefaultTableModel();
String[] cols1 = new String[]{"1","2","3","4","5","6"};
String[] cols2 = new String[]{"Mark","John","April","Mary","Joe","Jack"};
model.addColumn("Nr", cols1);model.addColumn("Name",cols2);
table = new JTable(model);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
colHeader.add(table.getTableHeader());
renderer.setLayout(new BorderLayout());
renderer.add(colHeader, BorderLayout.NORTH);
renderer.add(table,BorderLayout.CENTER);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
scroll.getViewport().add(table);
}
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
list.setFixedCellHeight(table.getRowHeight()*(table.getRowCount()+1)+10);
list.setFixedCellWidth(table.getPreferredSize().width);
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(!mouseListenerAdded){
list.addMouseListener(this.getListener());
mouseListenerAdded = true;
}
if(!combo.isPopupVisible()){
label.setText("Select...");
if(table.getSelectedRowCount()>0)
label.setText(""+table.getModel().getValueAt(table.getSelectedRow(),1));
return label;
}
return scroll;
}
public MouseAdapter getListener(){
MouseAdapter adapter = new MouseAdapter(){
#Override
public void mousePressed(MouseEvent e) {
if(combo.isPopupVisible()){
System.out.println("MouseClicked over list");
int row = table.rowAtPoint(e.getPoint());
if(row>0){
table.setRowSelectionInterval(row-1, row-1);
ListDataEvent event = new ListDataEvent(combo,ListDataEvent.CONTENTS_CHANGED,row-1,row-1);
combo.contentsChanged(event);
}
}
}
};
return adapter;
}
}
}
The key parts of the solution is that in order to have the table and the features of a table that you would want in a popup is you need to override the UI. Specifically you need to override the createPopup on BasicComboBoxUI, getPopupHeightForRowCount and createScroller on BasicComboPopup. Lastly, when implementing getListCellRenderingComponent you have set a fixed height and width that matches the tables preferred height and width. This will allow the main scroller of the popup to act as the scrollpane for the table.

custom JList Cell Renderer - Cell Selection?

Good day.
I'm pretty new to CellRenderer and stuff and I am still reading a lot about it. Right now, I'm stuck with something I'm not sure how to work. I was able to put a JPanel inside my JList by setting it's CellRenderer to a custom one. But here is the million dollar question: How can I interact with the controls?
I mean, I want to be able to right click into the cell that contains my jPanel,
Right click to show some actions, and Highlight the selected row.
How can I achieve this?
heres is my code:
import java.awt.CardLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class cellTest extends JPanel{
JLabel label;
public cellTest(){
buildInterface();
}
private void buildInterface(){
label = new JLabel();
setLayout(new CardLayout());
add(label);
}
public void setText(String text){
String pre = "<html><body style='width: 200px;'>";
label.setText(pre+text);
}
}
Second Part:
import Read.Medicine_Cell;
import java.awt.CardLayout;
import java.awt.Component;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
public class testjava {
public static void main(String args[]){
JFrame jf = new JFrame();
jf.setSize(500, 500);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(new CardLayout());
JList list = new JList();
DefaultListModel dlm = new DefaultListModel();
dlm.addElement("This is a test");
dlm.addElement("I wanna know if it works");
dlm.addElement("Pardon if im not that good yet");
dlm.addElement("or my problem is basic");
list.setModel(dlm);
list.setCellRenderer(new MyCellRenderer());
jf.add(new JScrollPane(list));
jf.show();
}
static class MyCellRenderer extends DefaultListCellRenderer{
final cellTest cellx = new cellTest();
#Override
public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean hasFocus){
final String text = (String) value;
cellx.setText(text);
return cellx;
}
}
}

How to get clicks on a button in a JLayeredPane in a JList

I have a button in a JLayeredPane in a JList so I can overlay icon buttons on each row on mouse over. However, the buttons are not accepting mouse clicks. The code is below. Nothing is output when clicking on anything. If I add a mouse listener to the JList, that will be called.
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JList;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
public class TestListLayered
{
public static class LayeredListCellRenderer extends DefaultListCellRenderer
{
#Override
public Component getListCellRendererComponent(final JList list, final Object value, final int index,
final boolean isSelected, final boolean cellHasFocus)
{
final JLayeredPane pane = new JLayeredPane();
final JLabel label = (JLabel) super.getListCellRendererComponent(list, value.toString(), index, isSelected,
cellHasFocus);
label.setHorizontalAlignment(SwingConstants.RIGHT);
label.setBounds(0, 0, 100, 20);
pane.add(label, JLayeredPane.DEFAULT_LAYER);
final JButton edit = new JButton("e");
final FontMetrics fontMetrics = edit.getFontMetrics(edit.getFont());
final int height2 = (int) (1.5 * fontMetrics.getHeight());
edit.setBounds(0, 0, (int) (1.5 * fontMetrics.stringWidth("e")), height2);
edit.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
System.out.println("button");
}
});
pane.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(final MouseEvent e)
{
System.out.println("layeredpane");
}
});
pane.add(edit, JLayeredPane.PALETTE_LAYER);
pane.setPreferredSize(new Dimension(-1, height2));
pane.setBorder(new LineBorder(Color.blue));
return pane;
}
}
public static void main(final String[] args)
{
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final JList<String> l = new JList<String>(new String[] { "item 1", "item 2" });
l.setCellRenderer(new LayeredListCellRenderer());
f.add(l);
f.pack();
f.setVisible(true);
}
}
First, I just want to say, this is very weird...
Basically, you should add a MouseListener to the JList. When it's clicked, you need to find the cell bounds of the selected row, convert the mouse point into a local context for the cell renderer and then test to see if the mouse clicked within the bounds of the button...
What you do after that is up to you.
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class TestListLayered {
public static class LayeredListCellRenderer extends DefaultListCellRenderer {
private JButton edit = new JButton("e");
#Override
public Component getListCellRendererComponent(final JList list, final Object value, final int index,
final boolean isSelected, final boolean cellHasFocus) {
final JLayeredPane pane = new JLayeredPane();
final JLabel label = (JLabel) super.getListCellRendererComponent(list, value.toString(), index, isSelected,
cellHasFocus);
label.setHorizontalAlignment(SwingConstants.RIGHT);
label.setBounds(0, 0, 100, 20);
pane.add(label, JLayeredPane.DEFAULT_LAYER);
final FontMetrics fontMetrics = edit.getFontMetrics(edit.getFont());
final int height2 = (int) (1.5 * fontMetrics.getHeight());
edit.setBounds(0, 0, (int) (1.5 * fontMetrics.stringWidth("e")), height2);
pane.add(edit, JLayeredPane.PALETTE_LAYER);
pane.setPreferredSize(new Dimension(-1, height2));
pane.setBorder(new LineBorder(Color.blue));
return pane;
}
protected void buttonClicked(Point p) {
System.out.println(edit.contains(p));
}
}
public static void main(final String[] args) {
new TestListLayered();
}
public TestListLayered() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JList<String> l = new JList<String>(new String[]{"item 1", "item 2"});
l.setCellRenderer(new LayeredListCellRenderer());
f.add(new JScrollPane(l));
l.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
int index = l.locationToIndex(e.getPoint());
if (index > -1) {
Rectangle bounds = l.getCellBounds(index, index);
LayeredListCellRenderer cellRenderer = (LayeredListCellRenderer) l.getCellRenderer();
Component renderComp = cellRenderer.getListCellRendererComponent(l, l.getModel().getElementAt(index), index, false, false);
renderComp.setBounds(bounds);
Point local = new Point(e.getPoint());
local.x -= bounds.x;
local.y -= bounds.y;
cellRenderer.buttonClicked(local);
}
}
});
f.pack();
f.setVisible(true);
}
});
}
}
I'd just like to say, I agree with camickr, it would be better to use a 2 column JTable...
A renderer is not a real component. It is just a painting of a component. So the button will not respond to clicks.
Not sure I understand what you are trying to do, but maybe you can use a two column JTable. Because a table supports an editor it does respond to mouse clicks. Table Button Column can help you here.

How to add icon near arrow icon for JComboBox

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
Thanks for your very detail explanation. Actually I will combine DefaultListCellRenderer and add the icon to the combo box like following code
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?
To change how a component renders, you generally work with what are called Renderers.
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.
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.
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:

Categories