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

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.

Related

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);
}
}

Delete highlighting in JComboBox

When a JComboBox is just made and added and all the background of the selected item is just normal and white:
(ignore the enormous spacing after the text)
When I then open the list and hover my cursor over an item, that item get's highlighted, all normal, nothing wrong with it.
But the problem now is that the highlighting stays once I've clicked on an item:
So my question is:
How can I make the highlighting go away?
Preferably without doing difficult with packages from the community or overloading or whatever.
If I'm right it has to be in the 'root' of the action listener of the combo box?
So:
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == comboBox)
{
// code to delete the highlighting
}
}
The highlighting is done by the default renderer for the combo box.
See the section from the Swing tutorial on Providing Custom Renderers for an example of providing your own custom renderer. You will just want a renderer that doesn't change the background/foreground depending on the selected value.
To make it easier for people with a similar problem, here is the code for the renderer I wrote:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class ComboBoxRenderer extends JLabel implements ListCellRenderer
{
private boolean colorSet;
private Color selectionBackgroundColor;
public ComboBoxRenderer()
{
setOpaque(true);
setHorizontalAlignment(LEFT);
setVerticalAlignment(CENTER);
colorSet = false;
selectionBackgroundColor = Color.red; // Have to set a color, else a compiler error will occur
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
// Check if color is set (only runs the first time)
if(!colorSet)
{
// Set the list' background color to original selection background of the list
selectionBackgroundColor = list.getSelectionBackground();
// Do this only one time since the color will change later
colorSet = true;
}
// Set the list' background color to white (white will show once selection is made)
list.setSelectionBackground(Color.white);
// Check which item is selected
if(isSelected)
{
// Set background color of the item your cursor is hovering over to the original background color
setBackground(selectionBackgroundColor);
}
else
{
// Set background color of all other items to white
setBackground(Color.white);
}
// Do nothing about the text and font to be displayed
setText((String)value);
setFont(list.getFont());
return this;
}
}
Edit: Previous code didn't seem to work as properly, code updated and should work all fine now

Scrollbars inside a JTable cell

I am trying to display HTML text inside a JTable's cell but the scrollbars arent showing up at all. Below is my code...
public class TableCellTextRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
final JTextPane jtextPane = new JTextPane();
JScrollPane scrollPane = new JScrollPane(jtextPane);
scrollPane.setPreferredSize(new Dimension(350,350));
scrollPane.setVisible(true);
jtextPane.setEditable(false);
jtextPane.setAutoscrolls(true);
jtextPane.setContentType("text/html");
jtextPane.setText(myHtmlText);
jtextPane.setVisible(true);
jtextPane.setPreferredSize(new Dimension(350,350));
//this setViewPort has no effect
scrollPane.setViewportView(jtextPane);
jtextPane.setVisible(true);
scrollPane.setAutoscrolls(true);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
JPanel jpanel = new JPanel();
jpanel.setVisible(true);
jpanel.setPreferredSize(new Dimension(360, 360));
jpanel.add(scrollPane);
return jpanel;
}
}
The scroll bars appear, but the scrolling handles dont appear. Can you please tell me what I am missing?
The table looks like this:
I'm afraid this is not going to work the way you'd want it to. The way JTables work is by obtaining a renderer component to draw the cell once, then cache it. In simplest terms, the component you're returning is basically just used to draw the cell, but it does not work the way normal components do - for instance, it does not receive events. You can use a cell editor (which will receive events), but the user would have to select the cell manually.
There are a couple of tricks you can use by installing custom mouse listeners, but this stuff will get very complicated. It'd probably be better to ask yourself if you're really looking for a JTable (as opposed to a custom layout), or if it would perhaps be possible to embed a JavaFX table.

Adding a JScrollPane component to a JTable column

I'm trying to add scrolling capabilities to a certain column in my JTable. I've implemented a custom TableCellRenderer component and I can see the scroll pane inside the table just fine, but I am not able to scroll it. I've tried implementing TableCellEditor as well and didn't have any luck.
public Component getTableCellEditorComponent(JTable arg0, Object arg1,
boolean arg2, int arg3, int arg4) {
return scrollPane;
}
Does anyone have any ideas how to make those cells which contain a scrollPane scrollable?
With TableCellRenderer it's not possible to add any scrolling behaviour, as it does not receive any events and only draws the component.
It is possible - however - to accomplish this by using a custom TableCellEditor with getTableCellEditor being:
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
JTextArea area = new JTextArea();
area.setLineWrap(true);
area.setText((String) value);
JScrollPane pane = new JScrollPane(area);
return pane;
}
Additionally, you have to control the editing behaviour of your CellEditor. To make the cell editable and scrollable always, isCellEditable should look like this:
public boolean isCellEditable(EventObject anEvent) {
return true;
}
Personally, I find this solution to be more of a hack than anything, though.
Also, this should only be for testing. You really do have to implement a better editing behaviour in my opinion.
A Renderer just paints the cells. I believe you need to implement a TableCellEditor to scroll.
As an alternative, consider placing a single scroll pane in a separate container and updating it's view in your selection listener.

Java List set Background of list item

How does one change the background color of a Java AWT List item? By that I mean a single item in a AWT List, not the whole thing.
You'll need a custom renderer. That is, if you're using Swing. It's better to stick with the Swing components and not the awt gui components.
JList
...
setCellRenderer(new MyCellRenderer());
...
class MyCellRenderer extends DefaultListCellRenderer
{
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
Color bg = <calculated color based on value>;
setBackground(bg);
setOpaque(true); // otherwise, it's transparent
return this; // DefaultListCellRenderer derived from JLabel, DefaultListCellRenderer.getListCellRendererComponent returns this as well.
}
}
Since Java AWT List inherits from Component, use Component's setBackground(Color c) method.
List coloredList = new List(4, false);
Color c = new Color(Color.green);
coloredList.add("Hello World")
coloredList.setBackground(c);
List now has a color green.
Been a while since I have worked with AWT, but can't you just use setBackground(Color)? List is a subclass of java.awt.Component.

Categories