JComboBox custom ListCellRenderer - java

I've a problem with JComboBox custom ListCellRenderer. I want to create a combobox that let choose between 4 colors. I want the combobox shows the color by a "list" of JPanel with desired color a background. I manage to obtain quite what I want, the only problem is that when I click on item, this change color to grey not displaying anymore the original color.
Here the code:
package custom_renderer_combobox;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.JComboBox;
public class gui extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
private Color[] colors={Color.BLACK,Color.blue,Color.cyan,Color.GRAY,Color.green,Color.MAGENTA,Color.ORANGE,Color.RED};
gui(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(new Dimension(400,400));
getContentPane().setLayout(null);
JComboBox<JPanel> comboBox = new JComboBox<JPanel>();
comboBox.setRenderer(new myRenderer());
comboBox.setBounds(36, 59, 211, 20);
getContentPane().add(comboBox);
for(int i=0;i<colors.length;i++){
JPanel temp=new JPanel();
temp.setOpaque(true);
temp.setBackground(colors[i]);
comboBox.addItem(temp);
}
comboBox.repaint();
}
class myRenderer implements ListCellRenderer{
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
return ((JPanel) value);
}
}
}
Here some pic:
image
I think that the problem is in the custom renderer, can someone tell me what would I had to do?

Here is an example for you, how to use renderers and combo boxes
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
/**
* <code>ColorTest</code>.
*/
public class ColorTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ColorTest();
}
});
}
/**
*
*/
public ColorTest() {
JFrame frm = new JFrame("Test");
final JComboBox<ColorData> cmb = new JComboBox<>(ColorData.values());
cmb.setRenderer(new ColorRenderer());
final JPanel p = new JPanel();
p.setOpaque(true);
p.setPreferredSize(new Dimension(200, 100));
ActionListener l = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ColorData cd = (ColorData) cmb.getSelectedItem();
if (cd != null) {
p.setBackground(cd.getColor());
}
}
};
cmb.addActionListener(l);
l.actionPerformed(null); // update current background
frm.add(cmb, BorderLayout.NORTH);
frm.add(p);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private static class ColorRenderer extends BasicComboBoxRenderer {
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof ColorData) {
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.createGraphics();
g.setColor(((ColorData) value).getColor());
g.fillRect(0, 0, 15, 15);
g.dispose();
setIcon(new ImageIcon(img));
}
return this;
}
}
private static enum ColorData {
BLACK("Black", Color.BLACK),
BLUE("Blue", Color.BLUE),
GREEN("Green", Color.GREEN),
RED("Red", Color.RED);
private String name;
private Color color;
private ColorData(String aName, Color aColor) {
name = aName;
color = aColor;
}
public String getName() {
return name;
}
public Color getColor() {
return color;
}
#Override
public String toString() {
return getName();
}
}
}
To add some new colors, you need to add the appropriate constants to the ColorData enum.

to make it a little bit quicker you can create your own JPanel that will take background color in constructor, and will block changing background:
public class ColorPanel extends JPanel {
public ColorPanel(Color color) {
super.setBackground(color);
}
#Override
public void setBackground(Color bg) {
//blocked changing
}
}
and in your code you have to change
JPanel temp = new ColorPanel(colors[i]);
temp.setOpaque(true);
comboBox.addItem(temp);

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
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.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
class ComboTableCellRenderer implements ListCellRenderer, TableCellRenderer {
DefaultListCellRenderer listRenderer = new DefaultListCellRenderer();
DefaultTableCellRenderer tableRenderer = new DefaultTableCellRenderer();
private void configureRenderer(JLabel renderer, Object value) {
if ((value != null) && (value instanceof Color)) {
if (value.equals(Color.red)) {
renderer.setText("0");
} else if(value.equals(Color.orange)) {
renderer.setText("10");
}
else if(value.equals(Color.yellow)) {
renderer.setText("20");
}
else if(value.equals(Color.green)) {
renderer.setText("30");
}
else if(value.equals(Color.white)) {
renderer.setText("N/A");
}
renderer.setBackground((Color)value);
} else {
renderer.setText((String) value);
}
}
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
listRenderer = (DefaultListCellRenderer) listRenderer.getListCellRendererComponent(list, value,
index, isSelected, cellHasFocus);
configureRenderer(listRenderer, value);
return listRenderer;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
tableRenderer = (DefaultTableCellRenderer) tableRenderer.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
configureRenderer(tableRenderer, value);
return tableRenderer;
}
}
class ColorTableModel extends AbstractTableModel {
Object rowData[][] = {
{ "1","","","", Color.red, "30" },
{ "2","","","", Color.red, "30" },
{ "3","","","", Color.red, "30" },
{ "4","","","", Color.red, "30" },
{ "5","","","", Color.red, "30" }, };
String columnNames[] = { "Index","Item","Reason","Image","Marks","Allocated Marks" };
public int getColumnCount() {
return columnNames.length;
}
public String getColumnName(int column) {
return columnNames[column];
}
public int getRowCount() {
return rowData.length;
}
public Object getValueAt(int row, int column) {
return rowData[row][column];
}
public Class getColumnClass(int column) {
return (getValueAt(0, column).getClass());
}
public void setValueAt(Object value, int row, int column) {
rowData[row][column] = value;
}
public boolean isCellEditable(int row, int column) {
return (column != 0);
}
}``
Main.java
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
public class Main {
public static void main(String[] args) {
// TODO code application logic here
Color choices[] = { Color.red, Color.yellow, Color.green, Color.white, Color.orange };
ComboTableCellRenderer renderer = new ComboTableCellRenderer();
JComboBox comboBox = new JComboBox(choices);
comboBox.setRenderer(renderer);
TableCellEditor editor = new DefaultCellEditor(comboBox);
JFrame frame = new JFrame("Editable Color Table");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TableModel model = new ColorTableModel();
JTable table = new JTable(model);
TableColumn column = table.getColumnModel().getColumn(4);
column.setCellRenderer(renderer);
column.setCellEditor(editor);
JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(400, 150);
frame.setVisible(true);
}
}
This code for jtable jcombobox color change according to value change.
This is working 100%
Hope it will work for you!

Related

How to put jbutton into an array to upload image row by row in a jtable?

My image uploading function is totally working. But I cannot upload image row by row. At this moment when I upload a image it will added into whole 5th column. How to put my buttons into an array and upload image in a row by row?
**Note: Button working as a file uploader.
Here is the image
enter image description here
Here is the code :
NewFrame.java
package test4;
import java.awt.Color;
import java.awt.Component;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;
import javax.swing.filechooser.FileSystemView;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
public class NewJFrame extends javax.swing.JFrame {
static String fileoriginal="C:/Users/Praneeth Thisal/Documents/NetBeansProjects/Copyfile/src/copyfile/";
public NewJFrame() {
initComponents();
tablemodel();
}
void tablemodel(){
Color choices[] = { Color.red, Color.yellow, Color.green, Color.white, Color.orange };
ComboTableCellRenderer renderer = new ComboTableCellRenderer();
JComboBox comboBox = new JComboBox(choices);
comboBox.setRenderer(renderer);
TableCellEditor editor = new DefaultCellEditor(comboBox);
TableModel model = new ColorTableModel();
jTable1.setModel(model);
TableColumn column = jTable1.getColumnModel().getColumn(5);
column.setCellRenderer(renderer);
column.setCellEditor(editor);
TableColumn column1 = jTable1.getColumnModel().getColumn(3);
column1.setCellRenderer(new ButtonRenderer());
TableColumn column2 = jTable1.getColumnModel().getColumn(4);
column2.setCellRenderer(new ImageRenderer());
column1.setCellEditor(
new ButtonEditor(new JCheckBox()));
jTable1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
jTable1.getColumnModel().getColumn(0).setPreferredWidth(27);
jTable1.getColumnModel().getColumn(1).setPreferredWidth(120);
jTable1.getColumnModel().getColumn(2).setPreferredWidth(100);
jTable1.getColumnModel().getColumn(3).setPreferredWidth(90);
jTable1.getColumnModel().getColumn(4).setPreferredWidth(90);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null, null, null, null},
{null, null, null, null, null, null},
{null, null, null, null, null, null},
{null, null, null, null, null, null}
},
new String [] {
"Title 1", "Title 2", "Title 3", "Title 4", "Title 5", "Title 6"
}
));
jScrollPane1.setViewportView(jTable1);
getContentPane().add(jScrollPane1, new org.netbeans.lib.awtextra.AbsoluteConstraints(25, 160, 730, 275));
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-795)/2, (screenSize.height-651)/2, 795, 651);
}// </editor-fold>
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
// End of variables declaration
}
class ImageRenderer extends DefaultTableCellRenderer {
JLabel lbl = new JLabel();
ImageIcon icon = new ImageIcon(new ImageIcon(NewJFrame.fileoriginal+"test.jpg").getImage().getScaledInstance(40, 40, Image.SCALE_DEFAULT));
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
lbl.setText((String) value);
lbl.setIcon(icon);
return lbl;
}
}
class ButtonRenderer extends JButton implements TableCellRenderer {
public ButtonRenderer() {
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
value="Upload";
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(UIManager.getColor("Button.background"));
// setText("dsda1");
}
setText((value == null) ? "" : value.toString());
return this;
}
}
/**
* #version 1.0 11/09/98
*/
class ButtonEditor extends DefaultCellEditor {
protected JButton button;
private String label;
private boolean isPushed;
public ButtonEditor(JCheckBox checkBox) {
super(checkBox);
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
});
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
if (isSelected) {
button.setForeground(table.getSelectionForeground());
button.setBackground(table.getSelectionBackground());
} else {
button.setForeground(table.getForeground());
button.setBackground(table.getBackground());
}
label = (value == null) ? "" : value.toString();
//label="DDD";
button.setText("Upload");
isPushed = true;
return button;
}
public Object getCellEditorValue() {
if (isPushed) {
//
JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
int returnValue = jfc.showOpenDialog(null);
// int returnValue = jfc.showSaveDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File selectedFile = jfc.getSelectedFile();
System.out.println(selectedFile.getAbsolutePath());
File source = new File(selectedFile.getAbsolutePath());
try{
NewJFrame.fileoriginal="C:/Users/Praneeth Thisal/Documents/NetBeansProjects/Copyfile/src/copyfile/";
copyFileUsingStream(source, new File(NewJFrame.fileoriginal+"test"+".jpg"));
System.out.println("Done");
NewJFrame nf = new NewJFrame();
nf.setVisible(true);
}
catch(IOException e){
e.printStackTrace();
}
}
// JOptionPane.showMessageDialog(button, label + ": Ouch!");
System.out.println(label + "Uploaded Successfully!!");
}
isPushed = false;
return new String(label);
}
private static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
public boolean stopCellEditing() {
isPushed = false;
return super.stopCellEditing();
}
protected void fireEditingStopped() {
super.fireEditingStopped();
}
}
ComboTableCellRenderer.java
package test4;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
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.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
class ComboTableCellRenderer implements ListCellRenderer, TableCellRenderer {
DefaultListCellRenderer listRenderer = new DefaultListCellRenderer();
DefaultTableCellRenderer tableRenderer = new DefaultTableCellRenderer();
private void configureRenderer(JLabel renderer, Object value) {
if ((value != null) && (value instanceof Color)) {
if (value.equals(Color.red)) {
renderer.setText("0");
} else if(value.equals(Color.orange)) {
renderer.setText("10");
}
else if(value.equals(Color.yellow)) {
renderer.setText("20");
}
else if(value.equals(Color.green)) {
renderer.setText("30");
}
else if(value.equals(Color.white)) {
renderer.setText("N/A");
}
renderer.setBackground((Color)value);
} else {
renderer.setText((String) value);
}
}
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
listRenderer = (DefaultListCellRenderer) listRenderer.getListCellRendererComponent(list, value,
index, isSelected, cellHasFocus);
configureRenderer(listRenderer, value);
return listRenderer;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
tableRenderer = (DefaultTableCellRenderer) tableRenderer.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
configureRenderer(tableRenderer, value);
return tableRenderer;
}
}
class ColorTableModel extends AbstractTableModel {
Object rowData[][] = {
{ "1","","","","", Color.red, "30" },
{ "2","","","","", Color.red, "30" },
{ "3","","","","", Color.red, "30" },
{ "4","","","","", Color.red, "30" },
{ "5","","","","", Color.red, "30" }, };
String columnNames[] = { "Index","Item","Reason","Image","Image 1","Marks","Allocated Marks" };
public int getColumnCount() {
return columnNames.length;
}
public String getColumnName(int column) {
return columnNames[column];
}
public int getRowCount() {
return rowData.length;
}
public Object getValueAt(int row, int column) {
return rowData[row][column];
}
public Class getColumnClass(int column) {
return (getValueAt(0, column).getClass());
}
public void setValueAt(Object value, int row, int column) {
rowData[row][column] = value;
}
public boolean isCellEditable(int row, int column) {
return (column != 0);
}
}

Can't update JComboBox in JTable when value is selected

I would like to have a JTable with JComboBoxes that is always visible. My problem is when I click on a JComboBox and select a value, my JComboBox is not updated.
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class trial extends JFrame {
private ArrayList<JComboBox> comboslist= new ArrayList <JComboBox>();/*list of my
comboboxes*/
public static void main(String[] args) {
trial tr= new trial();
}
public trial(){
this.setSize(new Dimension(600,100));
String[] ColData={"Index","Field Name","Value","Range"};
Object[][] TrowData={ };
DefaultTableModel model = new DefaultTableModel(TrowData, ColData);
final List<TableCellEditor> editors = new ArrayList<TableCellEditor>();
JComboBox combo1= new JComboBox();
combo1.addItem("don");
combo1.addItem("mump");
combo1.setEditable(true);
combo1.setBackground(Color.WHITE);
Object[] rowdata = {"cars","books","chicken","soup"};
model.addRow(rowdata);
DefaultCellEditor dce1 = new DefaultCellEditor(combo1);
editors.add(dce1);
JComboBox combo2= new JComboBox();
combo2.addItem("sop");
combo2.addItem("act");
combo2.setEditable(true);
combo2.setBackground(Color.WHITE);
Object[] rowdata2 = {"goats","cats","salads","dogs"};
model.addRow(rowdata2);
DefaultCellEditor dce2= new DefaultCellEditor(combo2);
editors.add(dce2);
comboslist.add(combo1);
comboslist.add(combo2);
JTable table = new JTable(model)
{
// Determine editor to be used by row
public TableCellEditor getCellEditor(int row, int column)
{
int modelColumn = convertColumnIndexToModel( column );
if (modelColumn == 2)
return editors.get(row);
else
return super.getCellEditor(row, column);
}
};
table.setRowHeight(0, 30);
table.setRowHeight(1, 30);
table.setPreferredScrollableViewportSize(new Dimension(800, 150));
table.setFillsViewportHeight(true);
TableColumn valCol= table.getColumnModel().getColumn(2);
int x=0;
for(JComboBox cb: comboslist ){
valCol.setCellRenderer(new ComboBoxCellRenderer(cb,x++));
}
this.add(table);
this.setVisible(true);
}
private class ComboBoxCellRenderer extends JComboBox implements TableCellRenderer {
private JComboBox combo;
private int idx=0;
private ComboBoxCellRenderer comboRenderer;
public ComboBoxCellRenderer(JComboBox com,int ind)
{
for (int i = 0; i < com.getItemCount(); i++)
{
addItem(com.getItemAt(i));
}
comboRenderer=this;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if(comboslist.get(row).getSelectedItem()!=null)
{
if(isSelected && row==idx)
{
setSelectedItem(comboslist.get(row).getSelectedItem().toString());
comboRenderer.setSelectedItem(comboslist.get(row).getSelectedItem().toString());
}
}else
{
setSelectedItem(value);
}
return this;
}
}
}
You've kinda got in backwards and twisted around. Instead of trying to have a number of combobox editors, you should have one, which is then configured based on the row.
Based on this idea, you could have a single class act as both the renderer and the editor, for example
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractCellEditor;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class Trial extends JFrame {
public static void main(String[] args) {
Trial tr = new Trial();
}
public Trial() {
this.setSize(new Dimension(600, 100));
String[] ColData = {"Index", "Field Name", "Value", "Range"};
Object[][] TrowData = {};
DefaultTableModel model = new DefaultTableModel(TrowData, ColData);
final List<TableCellEditor> editors = new ArrayList<TableCellEditor>();
model.addRow(new String[] {"cars", "books", "chicken", "soup"});
model.addRow(new String[] {"goats", "cats", "salads", "dogs"});
DefaultComboBoxModel model1 = new DefaultComboBoxModel();
model1.addElement("don");
model1.addElement("mump");
DefaultComboBoxModel model2 = new DefaultComboBoxModel();
model2.addElement("sop");
model2.addElement("act");
Map<Integer, ComboBoxModel<String>> models = new HashMap<>(2);
models.put(0, model1);
models.put(1, model2);
JTable table = new JTable(model);
table.setRowHeight(0, 30);
table.setRowHeight(1, 30);
table.setPreferredScrollableViewportSize(new Dimension(800, 150));
table.setFillsViewportHeight(true);
ComboBoxCellRendererEditor rendererEditor = new ComboBoxCellRendererEditor(models);
table.getColumnModel().getColumn(1).setCellRenderer(rendererEditor);
table.getColumnModel().getColumn(1).setCellEditor(rendererEditor);
this.add(table);
this.setVisible(true);
}
private static class ComboBoxCellRendererEditor extends AbstractCellEditor implements TableCellRenderer, TableCellEditor {
private JComboBox<String> comboBox;
private Map<Integer, ComboBoxModel<String>> models;
public ComboBoxCellRendererEditor(Map<Integer, ComboBoxModel<String>> models) {
comboBox = new JComboBox<>();
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
stopCellEditing();
}
});
this.models = models;
}
protected void configure(Object value, int row) {
ComboBoxModel<String> model = models.get(row);
if (model == null) {
model = new DefaultComboBoxModel<>();
}
comboBox.setModel(model);
comboBox.setSelectedItem(value);
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
configure(value, row);
return comboBox;
}
#Override
public Object getCellEditorValue() {
return comboBox.getSelectedItem();
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
configure(value, row);
return comboBox;
}
}
}
adding this piece of code solved everything.
column.setCellRenderer(new TableCellRenderer() {
JComboBox box = new JComboBox();
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
box.removeAllItems();
box.addItem(value.toString());
return box;
}
});

JTable: TableCellEditor not showing selected color

I have a JTable with 3 columns, the first column is a simple text, the other 2 columns are JComboBox. Column Name and Column Email both have a custom TableCellEditor and TableCellRenderer.
Sometimes when I click on a comboBox in a row that is not selected, the cell would not be drawn with the proper selected color (blue).
For illustration purposes, the TableCellRenderer draws pink cells, and TableCellEditor draws orange cells.
JTable returns false for isCellSelected(), more specifically returns false for isRowSelected(), at JTable editCellAt(). However when the renderer calls isCellSelected(), it returns true, so renderer is properly colored.
I can't figure out what's going wrong here.
My SSCCE:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JComponent;
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.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumnModel;
import org.iii.snsi.streamcenter.main.Main;
public class EditorNotSelectedColorFrame {
public JComponent makeUI() {
JTable table = new JTable();
DefaultTableModel model = new DefaultTableModel(new String[]{"COL 1", "COL 2", "COL 3"}, 0);
table.setModel(model);
for (int i = 0; i < 5; i++) {
Object[] row = new Object[3];
row[0] = new MyListItem(new String[]{"item a", "item b", "item c"});
row[1] = new MyListItem(new String[]{"item d", "item e", "item f"});
row[2] = new MyListItem(new String[]{"item g", "item h", "item i"});
model.addRow(row);
}
MyTableCellEditor editor = new MyTableCellEditor(Color.orange, Color.BLACK);
MyTableCellRenderer renderer = new MyTableCellRenderer(Color.pink, Color.BLACK);
TableColumnModel columnModel = table.getColumnModel();
columnModel.getColumn(0).setCellEditor(editor);
columnModel.getColumn(1).setCellEditor(editor);
columnModel.getColumn(2).setCellEditor(editor);
columnModel.getColumn(0).setCellRenderer(renderer);
columnModel.getColumn(1).setCellRenderer(renderer);
columnModel.getColumn(2).setCellRenderer(renderer);
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JScrollPane(table));
return panel;
}
public static void main(String... args) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Windows".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new EditorNotSelectedColorFrame().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
class MyListItem<T> {
private ArrayList<T> items = new ArrayList<>();
private Integer selectedIndex = -1;
public MyListItem(T[] items) {
selectedIndex = -1;
this.items.addAll(Arrays.asList(items));
}
public ArrayList<T> getItems() {
return items;
}
public void setSelectedIndex(Integer selectedIndex) {
this.selectedIndex = selectedIndex;
}
public Integer getSelectedIndex() {
return selectedIndex;
}
}
class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private Color unselectedBackground;
private Color unselectedForeground;
private JMyComboBox comboBox;
private MyListItem myListItem;
public MyTableCellEditor(Color bg, Color fg) {
unselectedBackground = bg;
unselectedForeground = fg;
comboBox = new JMyComboBox(bg, fg);
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
stopCellEditing();
}
});
}
#Override
public Object getCellEditorValue() {
int idx = comboBox.getSelectedIndex();
if (idx > -1) {
myListItem.setSelectedIndex(comboBox.getSelectedIndex());
}
return myListItem;
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
comboBox.removeAllItems();
if (value instanceof MyListItem) {
myListItem = (MyListItem) value;
for (Object item : myListItem.getItems()) {
comboBox.addItem(item.toString());
}
comboBox.setSelectedIndex(myListItem.getSelectedIndex());
} else {
myListItem = null;
}
if (isSelected) {
comboBox.setForeground(table.getSelectionForeground());
comboBox.setBackground(table.getSelectionBackground());
} else {
comboBox.setForeground(unselectedForeground);
comboBox.setBackground(unselectedBackground);
}
return comboBox;
}
}
class MyTableCellRenderer extends DefaultTableCellRenderer {
private Color unselectedBackground;
private Color unselectedForeground;
private JMyComboBox comboBox;
public MyTableCellRenderer(Color bg, Color fg) {
super();
unselectedBackground = bg;
unselectedForeground = fg;
comboBox = new JMyComboBox(bg, fg);
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
comboBox.removeAllItems();
if (value instanceof MyListItem) {
MyListItem cellItem = (MyListItem) value;
for (Object item : cellItem.getItems()) {
comboBox.addItem(item.toString());
}
comboBox.setSelectedIndex(cellItem.getSelectedIndex());
}
if (isSelected) {
comboBox.setForeground(table.getSelectionForeground());
comboBox.setBackground(table.getSelectionBackground());
} else {
comboBox.setForeground(unselectedForeground);
comboBox.setBackground(unselectedBackground);
}
return comboBox;
}
}
class JMyComboBox extends JComboBox<String> {
private MyComboBoxEditor editor = new MyComboBoxEditor();
private MyComboBoxRenderer renderer = new MyComboBoxRenderer();
public JMyComboBox(Color bg, Color fg) {
super();
setEditable(true);
setEditor(editor);
setRenderer(renderer);
editor.setColors(bg, fg);
renderer.setColors(bg, fg);
}
#Override
public void setBackground(Color bg) {
super.setBackground(bg);
if (editor != null) {
editor.setColors(bg, getForeground());
}
}
#Override
public void setForeground(Color fg) {
super.setForeground(fg);
if (editor != null) {
editor.setColors(getBackground(), fg);
}
}
}
class MyComboBoxEditor extends BasicComboBoxEditor {
private JLabel label = new JLabel();
public MyComboBoxEditor() {
super();
label.setOpaque(true);
}
public void setColors(Color background, Color foreground) {
label.setBackground(background);
label.setForeground(foreground);
}
#Override
public void setItem(Object anObject) {
super.setItem(anObject);
label.setText(((JTextField) super.getEditorComponent()).getText());
}
#Override
public Component getEditorComponent() {
return label;
}
}
class MyComboBoxRenderer extends DefaultListCellRenderer {
private Color unselectedBackground;
private Color unselectedForeground;
public void setColors(Color background, Color foreground) {
this.unselectedBackground = background;
this.unselectedForeground = foreground;
}
#Override
public Component getListCellRendererComponent(JList<?> list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (!isSelected) {
if (unselectedBackground != null) {
setBackground(unselectedBackground);
}
if (unselectedForeground != null) {
setForeground(unselectedForeground);
}
}
return this;
}
}

New line in jTable cell

This is how I am adding rows to my jTable, as you can see I tried using \n in zainteresowania but it is being ignored. How can I simple add new line after every record from my List?
for (Osoba a : osoby){
List zainteresowania1 = a.getZainteresowania();
for (Iterator iterator2 = zainteresowania1.iterator(); iterator2.hasNext();){
Zainteresowania nazwa = (Zainteresowania) iterator2.next();
zainteresowania = zainteresowania + (nazwa.getZainteresowanie() + ". " + "\n");
}
model.addRow(new Object[]{a.getImie(), a.getNazwisko(), a.getEmail(), a.getTelefon(), zainteresowania});
zainteresowania = "";
}
Refer Example
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class TestJTableMultiline extends JFrame {
public TestJTableMultiline() {
super("Multi-Line Cell Example");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
DefaultTableModel dm = new DefaultTableModel() {
public Class<String> getColumnClass(int columnIndex) {
return String.class;
}
public boolean isCellEditable(int row, int column) {
return false;
}
};
dm.setDataVector(
new Object[][]{
{"A0, Line1\nA0, Line2\nA0, Line3",
"B0, Line1\nB0, Line2",
"C0, Line1"},
{"A1, Line1",
"B1, Line1\nB1, Line2",
"C1, Line1"},
{"A2, Line1",
"B2, Line1",
"C2, Line1"}
},
new Object[] {"A", "B", "C"});
JTable table = new JTable(dm);
table.setDefaultRenderer(String.class, new MultiLineTableCellRenderer());
TableRowSorter<? extends TableModel> sort = new TableRowSorter<DefaultTableModel>(dm);
table.setRowSorter(sort);
JScrollPane scroll = new JScrollPane(table);
getContentPane().add(scroll);
setLocationByPlatform(true);
setSize(400, 430);
setVisible(true);
}
public static void main(String[] args) {
TestJTableMultiline frame = new TestJTableMultiline();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
public class MultiLineTableCellRenderer extends JTextArea
implements TableCellRenderer {
private List<List<Integer>> rowColHeight = new ArrayList<List<Integer>>();
public MultiLineTableCellRenderer() {
setLineWrap(true);
setWrapStyleWord(true);
setOpaque(true);
}
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(table.getBackground());
}
setFont(table.getFont());
if (hasFocus) {
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
if (table.isCellEditable(row, column)) {
setForeground(UIManager.getColor("Table.focusCellForeground"));
setBackground(UIManager.getColor("Table.focusCellBackground"));
}
} else {
setBorder(new EmptyBorder(1, 2, 1, 2));
}
if (value != null) {
setText(value.toString());
} else {
setText("");
}
adjustRowHeight(table, row, column);
return this;
}
/**
* Calculate the new preferred height for a given row, and sets the height on the table.
*/
private void adjustRowHeight(JTable table, int row, int column) {
//The trick to get this to work properly is to set the width of the column to the
//textarea. The reason for this is that getPreferredSize(), without a width tries
//to place all the text in one line. By setting the size with the with of the column,
//getPreferredSize() returnes the proper height which the row should have in
//order to make room for the text.
int cWidth = table.getTableHeader().getColumnModel().getColumn(column).getWidth();
setSize(new Dimension(cWidth, 1000));
int prefH = getPreferredSize().height;
while (rowColHeight.size() <= row) {
rowColHeight.add(new ArrayList<Integer>(column));
}
List<Integer> colHeights = rowColHeight.get(row);
while (colHeights.size() <= column) {
colHeights.add(0);
}
colHeights.set(column, prefH);
int maxH = prefH;
for (Integer colHeight : colHeights) {
if (colHeight > maxH) {
maxH = colHeight;
}
}
if (table.getRowHeight(row) != maxH) {
table.setRowHeight(row, maxH);
}
}
}

JTable copy value from view of cellrenderer

I have a JTable with a cellrenderer and my table is non-editable. When i select a cell and copy (ctrl-c) the value, its copying not the shown in the cell, it is copying the value which store in model. How could I copy cell value which shown in table.
public class TableDemo {
public static void main(String[] args) {
Vector<String> values = new Vector<String>();
values.add("Val1");
values.add("Val2");
JTable table = new JTable(new Object[][] { { "key", values },
{ "key2", values } }, new String[] { "Col1", "Col2" });
table.getColumnModel().getColumn(1).setCellRenderer(new MyTableCellRenderer());
table.setCellSelectionEnabled(true);
JFrame jf = new JFrame();
jf.getContentPane().add(table);
jf.setSize(500, 500);
jf.setVisible(true);
}
}
class MyTableCellRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
row, column);
#SuppressWarnings("unchecked")
Vector<String> values = (Vector<String>) value;
setText(values.get(row));
return this;
}
}
You need to implement your own copy command. Here is the solution.
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
public class TableDemo {
public static void main(String[] args) {
final Vector<String> values = new Vector<String>();
values.add("Val1");
values.add("Val2");
final JTable table = new JTable(new Object[][] { { "key", values },
{ "key2", values } }, new String[] { "Col1", "Col2" });
table.getColumnModel().getColumn(1).setCellRenderer(new MyTableCellRenderer());
table.registerKeyboardAction(new CopyAction(), KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK), JComponent.WHEN_FOCUSED);
table.setCellSelectionEnabled(true);
final JFrame jf = new JFrame();
jf.getContentPane().add(table);
jf.setSize(500, 500);
jf.setVisible(true);
}
private static class CopyAction extends AbstractAction {
/**
* {#inheritDoc}
*/
#Override
public void actionPerformed(ActionEvent e) {
final JTable tbl = (JTable) e.getSource();
final int row = tbl.getSelectedRow();
final int col = tbl.getSelectedColumn();
if (row >= 0 && col >= 0) {
final TableCellRenderer renderer = tbl.getCellRenderer(row, col);
final Component comp = tbl.prepareRenderer(renderer, row, col);
if (comp instanceof JLabel) {
final String toCopy = ((JLabel) comp).getText();
final StringSelection selection = new StringSelection(toCopy);
final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, selection);
}
}
}
}
}
#SuppressWarnings("serial")
class MyTableCellRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
row, column);
#SuppressWarnings("unchecked")
final
Vector<String> values = (Vector<String>) value;
setText(values.get(row));
return this;
}
}

Categories