Create JList with 3 Items: Checkbox, Image and Text - java

I have added an image and text into a JList. Now I want to add a checkbox but I don't know how to make it. Can I, for example, create a new class with the 3 items: Checkbox, Image and Text?
public Component getListCellRendererComponent(JList list, Object value,int index,boolean isSelected, boolean cellHasFocus)
{
ProfItems item = (ProfItems) value;
this.setText(item.getName());
this.setIcon(item.getBild());
//Sample 08: Draw Background for Selected Item
if (isSelected)
{
setBackground(Color.YELLOW);
setForeground(Color.BLACK);
}
//Sample 09: Reset the Background for Un-Selected Item
if (!isSelected)
{
setBackground(Color.WHITE);
setForeground(Color.BLACK);
}
//Sample 10: Draw a Border to Show Focussed Item
if (cellHasFocus)
{
setBorder(BorderFactory.createLineBorder(Color.ORANGE));
}
else
{
setBorder(BorderFactory.createEmptyBorder());
}
return this;
}

Related

Buttons in table cell can't be pressed

I'm using Java Swing to make a table with buttons I can use to be actions based on the row.
I am using a custom cell renderer to try rendering multiple buttons in a table cell. I have managed to cobble together something that does what I want visually but the buttons don't actually function. They simply don't fire and don't react visually to clicks or mouse overs. Looking for a way to make the buttons react and actually fire their actions.
Cell renderer class:
public class ButtonsCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
JPanel panel;
public ButtonsCell() {
this.updateData(Collections.emptyList());
}
private void updateData(List<JButton> buttons) {
this.panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
for(JButton button : buttons) {
button.setMargin(new Insets(-2, 0, -2, 0));
this.panel.add(button);
}
}
private void updateData(List<JButton> buttons, boolean isSelected, JTable table) {
this.updateData(buttons);
if (isSelected) {
this.panel.setBackground(table.getSelectionBackground());
}else{
this.panel.setBackground(table.getBackground());
}
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
this.updateData((List<JButton>)value, isSelected, table);
return panel;
}
public Object getCellEditorValue() {
return null;
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
this.updateData((List<JButton>)value, isSelected, table);
return panel;
}
}
Visually, this produces:

Java GUI with JTable

I am displaying data in JTable through mouse event in JList. I want to know how I would change the font color of specific data after the user click in JLIst, and Here is Photo for the desired result
list.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
int solutionindex =list.getSelectedIndex();
if(solutionindex==0) {
for (int i=0;i<table.getRowCount();i++) {
for (int j=0;j<table.getColumnCount();j++) {
table.setValueAt(b.charAt(i, j), i,j);
}// end of second for loop
}// end of for loop
}
else {
for (int i=0;i<table.getRowCount();i++) {
for (int j=0;j<table.getColumnCount();j++) {
table.setValueAt(solutions.get(solutionindex1).getBoard().charAt(i, j), i,j);
}// end of second for loop
}// end of for loop
}
table.setDefaultRenderer(String.class, new DefaultTableCellRenderer(){
#Override
public java.awt.Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column) {
java.awt.Component c = super.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column);
c.setForeground(Color.red);
return c;
}
});
Use a ListSelectionModel instead of a MouseListener on the JList. (The JList will somewhere along the line be using the MouseListener to change state. Does it happen before or after you listener is fired? Depends. May change on implementation and even at runtime (which is really confusing).)
Switch the object in the table [model] from Character to be of a new type containing both the text and the foreground colour. In the table cell renderer, cast the cell object to the correct type, and use its colour in setForeground.

TableCellRenderer sets color to many cells and not just one

I have a JTable, that I want I want to be able to change the color of a single cell that is clicked on.
Here is a simplified version of my code:
public class TableFrame extends JFrame {
public TableFrame() {
JTable table = new JTable(8, 8);
table.setGridColor(Color.BLACK);
table.setDefaultRenderer(CustomCellRenderer.class, new CustomCellRenderer());
getContentPane().add(table);
}
public class CustomCellRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (hasFocus) {
l.setBackground(Color.red);
l.setText("Hello");
}
return l;
}
}
}
When I click a certain cell, I expect it to change color to red and add "Hello" to it. It changes the text, but for some weird reason, it changes the color of all the cells after it? And when I click an uncolored cell, it does the same, but not always in an organised way if that makes sense? Like, it won't color all the cells after it, but maybe some that are just above and leave others blank..
It's really weird and makes no sense whatsoever. What is happening??
Having dug around the DefaultTableCellRenderer class a bit, when you call setBackground on the JLabel component, which is backing the DefaultTableCellRenderer, it is storing the value you use...
public void setBackground(Color c) {
super.setBackground(c);
unselectedBackground = c;
}
When the cell is painted again, it's this value (unselectedBackground) which is been used to repaint the cell in "default" mode...
if (isSelected) {
//...
} else {
Color background = unselectedBackground != null
? unselectedBackground
: table.getBackground();
if (background == null || background instanceof javax.swing.plaf.UIResource) {
Color alternateColor = DefaultLookup.getColor(this, ui, "Table.alternateRowColor");
if (alternateColor != null && row % 2 != 0) {
background = alternateColor;
}
}
super.setForeground(unselectedForeground != null
? unselectedForeground
: table.getForeground());
super.setBackground(background);
}
This means, the moment you use setBackground and pass it Color.RED, the DefaultTableCellRenderer assumes that this becomes the default color for ALL unselected cells.
The only choice you have is to reset the background color manually, for example...
public class CustomCellRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (hasFocus) {
l.setBackground(Color.red);
l.setText("Hello");
} else if (!isSelected) {
l.setBackground(table.getBackground());
}
return l;
}
}
Also, you should really be using something more like...
table.setDefaultRenderer(Object.class, new CustomCellRenderer());
to register the cell renderer, as it's the Class type returned by TableModel#getColumnClass which determines which cell renderer is used ;)
Since the OP only wants help with the rendered and not with the data... here goes (assuming there is a function called hasBeenClicked(row,column) method available to determine whether the cell has been visited yet.
public class CustomCellRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (hasBeenClicked(row,column)) {
l.setBackground(Color.red);
l.setText("Hello");
} else {
// reset the label to white background
l.setBackground(Color.white);
l.setText("Hello");
}
return l;
}
}
}
Also note that the registration of the renderer should be
table.setDefaultRenderer(Object.class, new CustomCellRenderer());
Since we want all columns to have this renderer (renderers are registered against the class of the column in the model).
I tested with the below as the hasBeenClicked method.
public boolean hasBeenClicked(int row, int column){
return (row%2==0 && column%2==0);
}
Just implement your own tracking of whether a cell has been clicked or not and you should be good to go. Remember that you should not use the renderer to track the clicks, use some kind of listener instead.

JComboBox: change one selection item to italic

I want to change one selection item in existing jcombobox (items are already added) to italic? Is there any way to do that?
I hope this one helps you :)
You just have to add the ListCellRenderer to your ComboBox.
class MyComboBoxRenderer extends JLabel
implements ListCellRenderer {
. . .
public ComboBoxRenderer() {
setOpaque(true);
setHorizontalAlignment(CENTER);
setVerticalAlignment(CENTER);
}
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
//Get the selected index. (The index param isn't
//always valid, so just use the value.)
int selectedIndex = ((Integer)value).intValue();
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
//Set the icon and text. If icon was null, say so.
ImageIcon icon = images[selectedIndex];
String pet = petStrings[selectedIndex];
setIcon(icon);
if (icon != null) {
setText(pet);
setFont(list.getFont()); //HERE YOU ALSO HAVE TO SET THE COLOR OR SOMETHING LIKE THAT
} else {
setUhOhText(pet + " (no image available)",
list.getFont());
}
return this;
}
. . .
}

Get all selected index of Checkbox

I am a beginner to Java Swing. I have a table with 3 columns. The first column has only check boxes. I wanted to get the index of all the selected items of the check box and store it in an ArrayList. How can I accomplish this?
have a look at this,
http://www.java2s.com/Code/Java/Swing-JFC/SwingCheckBoxDemo.htm
If you want to return all selected items, you can use List or Set for this.
Post the code what you have. I may assist...
As you use a JTable you are using a TableCellRenderer for the "checkbox column". As long you add check boxes to column 1 you "know" in which row the checkbox is created. As you know the row(=index) you can register an action to collect together the checked boxes index.
(from scratch)
public class MyRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, final int row, int column) {
if (column != 1) {
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
JCheckBox cb = new JCheckBox();
cb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
list.add(row); // whatever list is ...
}
});
return cb;
}
}

Categories