JComboBox with text and ImageIcon - java

Good morning, please,could you mind helping me in determining why this ListCellRenderer class not setting the image icon at combobox cells:
here's the ListCellRenderer class:
class MyComboRendere implements ListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = new JLabel();
label.setOpaque(true);
label.setText(value.toString());
label.setIcon(new ImageIcon("/pics/Color-icon.png"));
if (isSelected)
if (index == 0)
label.setBackground(Color.RED);
else if (index == 1)
label.setBackground(Color.GREEN);
else
label.setBackground(Color.BLUE);
return label;
}
}
and this is a method to setup the combobox:
public void setComboColor(){
Vector<String> colors=new Vector<>();
comboPanel=new JPanel(new BorderLayout());
colors.add("RED");
colors.add("GREEN");
colors.add("BLUE");
colorCombo=new JComboBox(colors);
colorCombo.setRenderer(new MyComboRendere());
comboPanel.add(colorCombo,BorderLayout.BEFORE_FIRST_LINE);
}

It seems that label.setIcon(new ImageIcon("/pics/Color-icon.png")); doesn't get the actual path of the icon as it always returns null, but it doesn't throw an exception. So I tried to use this:
java.net.URL imgURL = getClass().getResource("/pics/Color-icon.png");
label.setIcon(icon);
and it works properly

"/pics/Color-icon.png"
Does this exist? ImageIcon won't throw any exceptions if it fails to load the image, but will return null.

don't provide FileIO inside XxxRenderer, load all Icons to local variable, test for null value
XxxRenderer firing a lots of event (mouse, keys and internally implemented in API), then you recreated Icon on fly
read Oracle tutorial about JComboBox, try code example about similair issue

Related

Why can't I edit the appearance of this editable jComboBox?

I have this code and MyComboBoxRenderer() seems to not work with it. It has an error in the line with comment written below.
This code is made for autosuggest. So it shows suggestion in a combobox while user types on the textfield.
public test2() {
initComponents();
jComboBox1.setRenderer(new MyComboBoxRenderer1());
jComboBox1.setBackground(new Color(0,0,0,0));
final JTextField textfield = (JTextField) jComboBox1.getEditor().getEditorComponent(); //it has error in this line
textfield.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
comboFilter(textfield.getText());
}
});
}
});
}
Maybe it has something to do with the textfield. My problem is that I wanted to edit the appearance or design of combobox. I want it to inherit the background of the frame. Like transparent. Example are in the pictures.
Here are the pictures. Please click the links below to see it.
It should be something like this
Rather than this one. This is the output of the codes above.
And here is the code I have in my combobox renderer.
public MyComboBoxRenderer1(){
setOpaque(true);
setFont(new Font ("Segoe UI Semibold", Font.PLAIN ,14));
setForeground(Color.WHITE);
}
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
setText(value.toString());
if (isSelected)
{
setBackground(Color.WHITE);
setForeground(Color.BLACK);
}
else {
setBackground(Color.GRAY);
setForeground(Color.WHITE);
}
return this;
}
}
Why is it that the renderer doesn't work with this? And what should I do to make it work? Can anyone help me please? Thank you in advance. :)
EDITED...
I've already set the background transparent. I just need to declare the background of the texfield. XD Yey.
textfield.setBackground(new Color(0,0,0,0));
textfield.setForeground(new Color(255,255,255));
But it left small portion that is still not transparent.
I tried doing an additional comboBox on my frame. But it is without the textfield. And it works just fine!
The upper is the comboBox with textfield, the one I have problem with. The lower is the one w/o textfield, I just tried if the code will work with a normal comboBox. I need to make it look like the lower one.
jComboBox1.setRenderer(new MyComboBoxRenderer1());
jComboBox1.setBackground(new Color(0,0,0,0));
jComboBox2.setRenderer(new MyComboBoxRenderer1());
jComboBox2.setBackground(new Color(0,0,0,0));
It has the same code. But it doesn't work with the other one. Maybe it's because of the textfield again?? :(((
jComboBox1.setBackground(new Color(0,0,0,0));
Don't try to use transparent colors. Swing does not know how to paint transparent colors properly. See: Background With Transparency for more information.
Instead you change the opaqueness of the component:
component.setOpaque( false );
In the case of the combo box you need to worry about the component and the renderer, so you might use:
comboBox.setOpaque(false);
((JLabel)comboBox.getRenderer()).setOpaque(false);
However, this will now cause a problem with the dropdown list. Since the rendering is now transparent you won't see the row selections.
Haven't tested this but a possible solution if to alter the opaqueness of the renderer based on the item being rendered.
The code might be:
public Component getListCellRendererComponent(
JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
setOpaque(index == -1 ? false : true);
// add custom painting here
return this;
}
The -1 indicates the item in the combo box is being rendered as oppose to an item in the list.

Extending Swing JComboBox to remove unwanted border

I spent the last few hours looking for a solution or at least a decent guide about this issue, but found nothing.
I'm implementing a custom Swing Look and Feel for a small GUI of mine. Up until now I've been using the UIManager.put("key", values); method to good success, but I got stuck when it came to properly modify JComboBoxes.
Using this list I managed to get my jComboBoxes really close to what I want them to look like:
I have two issues with this, a major and a minor one:
Major
I want the blue shown border gone.
Minor
I'd really like the black shown border gone.
Apparently no key in the UIDefaults has anything to do with either two borders: they seem somehow hardcoded in the Look and Feel I'm modifying (which should be Metal). I resorted to manually extending the ComboBoxRenderer and managed to come up with this:
package exec.laf.theme;
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class ComboBoxRenderer extends BasicComboBoxRenderer {
private Color background;
private Color selectionBackground;
public ComboBoxRenderer() {
super();
background = UIManager.getColor("ComboBox.background");
selectionBackground = UIManager.getColor("ComboBox.selectionBackground");
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
setText((String) value);
if (isSelected) setBackground(selectionBackground);
else setBackground(background);
return this;
}
}
Where I specify this Renderer every time I create a JComboBox like so:
aComboBox.setRenderer(new ComboBoxRenderer());
obtaining the same look as the non-extended JComboBox.
The problem is that with this extension I can't find a way of touching those borders. Adding setBorder(new EmptyBorder(0, 0, 0, 0)); accomplishes nothing, since it simply adds a border to the listed items.
I checked the source code for javax.swing.plaf.basic.BasicComboBoxRenderer to see if any borders were applied there, but found nothing (the only border there is the one applied to the listed items, that I can override as shown above.
What am I supposed to do? Am I extending the wrong class, or am I missing something else?
The solution I found is:
UIManager.put("ComboBox.borderPaintsFocus", Boolean.TRUE)
This sets a boolean inside the ComboBoxUI that prevents rendering of the focus border, which is the border painted around all buttons when they are focused. Its style is dependent on your look and feel.
To remove the black border of comboBox PopUp,
Object child = comboBox.getAccessibleContext().getAccessibleChild(0);
BasicComboPopup popup = (BasicComboPopup)child;
popup.setBorder(BorderFactory.createEmptyBorder());
If i understoud, your problem is in generally how to use extended class from BasicComboBoxRenderer. So here a simple code to explain you how to use it:
public class RenderComboBox extends BasicComboBoxRenderer {
Color selectedBackground;
Color selectedForground;
Color background;
Color forground;
public RenderComboBox() {
setOpaque(true);
background = new Color(37, 37, 37);
selectedBackground = new Color(93, 93, 93);
forground = Color.WHITE;
selectedForground = forground;
}
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (isSelected) {
setBackground(selectedBackground);
setForeground(selectedForground);
} else {
setBackground(background);
setForeground(forground);
}
setFont(list.getFont());
if (value == null) {
setText("");
} else {
setText(value.toString());
}
return this;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(null);
frame.setPreferredSize(new Dimension(200, 170));
JComboBox<String> combobox = new JComboBox<>();
combobox.setRenderer(new RenderComboBox());
combobox.setBounds(50, 50, 100, 20);
combobox.addItem("TEST");
combobox.addItem("REVERT");
frame.add(combobox);
frame.pack();
frame.setVisible(true);
}
}

Set text size of JComboBox in Swing

I have created a combo-box in java (using Netbeans). I want to set the text size of each item in the list but don't know how to do it. (Preferably I want to use the default font style).
Any idea anyone how to do it?
Code Snippet:
private javax.swing.JComboBox ComboBox_agent = new javax.swing.JComboBox();
ComboBox_agent.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "TCP", "UDP", "Sink", "NULL" }));
Use a list cell rendering component with an appropriate font size. This example uses 20 pixels.
import java.awt.*;
import javax.swing.*;
class ShowFonts {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
GraphicsEnvironment ge = GraphicsEnvironment.
getLocalGraphicsEnvironment();
String[] fonts = ge.getAvailableFontFamilyNames();
JComboBox fontChooser = new JComboBox(fonts);
fontChooser.setRenderer(new FontCellRenderer());
JOptionPane.showMessageDialog(null, fontChooser);
});
}
}
class FontCellRenderer extends DefaultListCellRenderer {
#Override
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
JLabel label = (JLabel)super.getListCellRendererComponent(
list,value,index,isSelected,cellHasFocus);
Font font = new Font((String)value, Font.PLAIN, 20);
label.setFont(font);
return label;
}
}
If you created the JComboBox in Netbeans GUI editor, there is a field for "Font" that allows you to change the size.

How do I insert a JPanel inside a JLabel?

I am writing a custom jlist cell renderer for some kind of filechooser. My problem is that when I read my ImageIcon, it seems it has the dimension (-1,-1), so I can't resize it properly. The picture is a simple texture (wood, metal, etc.).
Then I thought that if I added a JPanel instead of an image, and then adding the image to the panel, I wouldnt even have to resize the picture.
I have 2 possibilities:
Read the ImageIcon from the hard drive so that they dont have dimension -1,-1
Insert a JPanel inside the JLabel.
Here is a preview of my list cells.
Here is my custom renderer, which adds icons to the cells.
class IconListRenderer extends DefaultListCellRenderer {
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) {
// Get the renderer component from parent class
JLabel label =
(JLabel) super.getListCellRendererComponent(list,
value, index, isSelected, cellHasFocus);
ImageIcon icon = (ImageIcon)icons.get(value);
// Set icon to display for value
label.setIcon(icon);
label.setText(value.toString());
return label;
}
}
Just replace the label with the panel.
You can use a JPanel as the rendercomponent instead of the JLabel.

JTable - compound editor focus

I have a custom editor composed of several components. Something like:
class MyCellEditor extends AbstractCellEditor implements TableCellEditor {
JTextArea textArea;
JButton button;
JPanel panel;
MyCellEditor() {
textArea = new JTextArea();
button = new JButton();
panel = new JPanel(new BorderLayout());
panel.add(textArea, BorderLayout.CENTER);
panel.add(button, BorderLayout.EAST);
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
textArea.setText((String) value);
return panel;
}
public Object getCellEditorValue() {
return textArea.getText();
}
}
I want the inner textArea to grab focus when editing starts. It works just fine when I click the cell, but not when I navigate the table with keyboard and start typing in this cell.
How can I fix this?
I had the same problem some time ago and took me ages to find a solution. Tried a lot with focuslistener and stuff, but nothing really seemed to work the way I wanted it to until I found this useful article by Santhosh Kumar.
Its well written and should fix your problem.

Categories