I have a jtable , a customtablemodel and a customcellrenderer with the NetBeans IDE.
I want to have different colors for different rows. But anytime I run the application ,
the rows are not painted as expected.
The code snippets are provided below.
This code is from the jtable :
duesTable = new javax.swing.JTable();
duesTable.setModel(duestableModel);
TableColumn tcol = duesTable.getColumnModel().getColumn(2);
tcol.setCellRenderer(new CustomTableCellRenderer2());
duesTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
this code is from the TableCellRenderer
public class CustomTableCellRenderer2 extends DefaultTableCellRenderer{
#Override
public Component getTableCellRendererComponent (JTable table,
Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
Component cell = super.getTableCellRendererComponent(
table, obj, isSelected, hasFocus, row, column);
if (isSelected) {
cell.setBackground(Color.green);
}
else {
if (row % 2 == 0) {
cell.setBackground(Color.green);
}
else {
cell.setBackground(Color.lightGray);
}
}
return cell;
}
}
This is from the Table Model.
public class DuesTableModel extends AbstractTableModel implements TableModelListener {
private List<List<Object>> dataList = new ArrayList<>();
private String[] header = { "ID"," PAYMENT YEAR" , "AMOUNT"}; // Payment year is a date
datatype
private int minRowCount = 5;
public DuesTableModel()
{ super(); }
public List<List<Object>> getDataList() {
return dataList;
}
public void setDataList(List<List<Object>> dataList) {
this.dataList = dataList;
fireTableDataChanged();
fireTableStructureChanged();
}
#Override
public int getRowCount() {
return Math.max(minRowCount, dataList.size());
}
#Override
public int getColumnCount() {
return header.length;
}
public void setHeader(String[] header) {
this.header = header;
}
public String[] getHeader() {
return header;
}
#Override
public void setValueAt(Object value, int row, int col)
{
int x = 0;
for(List<Object> l : dataList)
{
if(x == row)
{ l.set(col, value);}
x++;
}
fireTableCellUpdated(row,col);
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object value = null;
if(rowIndex < dataList.size())
{value = dataList.get(rowIndex).get(columnIndex);}
return value;
}
#Override
public String getColumnName(int col) {
return header[col];
}
#Override
public Class<?> getColumnClass(int column)
{
switch (column) {
case 0:
return Integer.class;
case 1:
return Date.class;
case 2:
return Double.class;
default:
return String.class;
}
}
#Override
public boolean isCellEditable(int row, int col) {
return true; //col != 1;
}
#Override
public void tableChanged(TableModelEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
Any suggestion to get the desired result.
Related
My JCheckBox "check all" header column works in that if I check the box, all checkboxes in this column become checked. I want to make it so that if you check the checkbox header so that all the boxes in the column become checked, uncheck one of the checkboxes in the column after will uncheck the checkbox header.
public class TablePanel extends javax.swing.JPanel {
public TablePanel() {
initComponents();
populateStringArrays(); //populate string arrays that will populate my table
table.setModel(tableModel);
table.getTableHeader().setReorderingAllowed(false);
setWidthOfTable();
loadTable(); //loads table with my array
table.getColumnModel().getColumn(5).setHeaderRenderer(new BoxRenderer(new MyItemListener()));
}
public class BoxRenderer extends JCheckBox implements TableCellRenderer, MouseListener{
String columnTitle = "Rings";
protected BoxRenderer rendererComponent;
int column;
boolean mousePressed = false;
public BoxRenderer(ItemListener listener){
rendererComponent = this;
rendererComponent.addItemListener(listener);
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if(table != null){
JTableHeader header = table.getTableHeader();
if(header != null){
rendererComponent.setForeground(header.getForeground());
rendererComponent.setBackground(header.getBackground());
rendererComponent.setFont(header.getFont());
Border border = header.getBorder();
header.setBorder(BorderFactory.createRaisedBevelBorder());
rendererComponent.setHorizontalTextPosition(SwingConstants.LEADING);
rendererComponent.setHorizontalAlignment(CENTER);
header.addMouseListener(rendererComponent);
}
}
setColumn(column);
rendererComponent.setText(columnTitle);
return rendererComponent;
}
protected void setColumn(int column) {
this.column = column;
}
public int getColumn() {
return column;
}
protected void handleClickEvent(MouseEvent e) {
if (mousePressed) {
mousePressed=false;
JTableHeader header = (JTableHeader)(e.getSource());
JTable tableView = header.getTable();
TableColumnModel columnModel = tableView.getColumnModel();
int viewColumn = columnModel.getColumnIndexAtX(e.getX());
int column = tableView.convertColumnIndexToModel(viewColumn);
if (viewColumn == this.column && e.getClickCount() == 1 && column != -1) {
doClick();
}
}
}
public void mouseClicked(MouseEvent e) {
((JTableHeader)e.getSource()).repaint();
}
public void mousePressed(MouseEvent e) {
mousePressed = true;
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
class MyItemListener implements ItemListener{
#Override
public void itemStateChanged(ItemEvent e) {
Object source = e.getSource();
if (source instanceof AbstractButton == false){
return;}
boolean checked = e.getStateChange() == ItemEvent.SELECTED;
System.out.println("Boolean checked = " + checked);
if(checked == true){
checkAll();
}else{
uncheckAll();
}
}
}
private void checkAll(){
for(int i=0; i<tableRecordArrayList.size(); i++){
table.getModel().setValueAt(true, i, 5);
}
}
private void uncheckAll(){
for(int i=0; i<tableRecordArrayList.size(); i++){
table.getModel().setValueAt(false, i, 5);
}
}
class TableModel extends javax.swing.table.AbstractTableModel{
/**Constructor**/
#Override
public int getRowCount() {
return tableRecordArrayList.size();
}
#Override
public int getColumnCount() {
return 6;
}
/**refresh for changes**/
public void refreshTable(){
fireTableDataChanged();
}
#Override
public Object getValueAt(int row, int column) {
TableRecord record = tableRecordArrayList.get(row);
switch(column){
case 0:
return record.firstName;
case 1:
return record.middleName;
case 2:
return record.lastName;
case 3:
return record.age;
case 4:
return record.height;
case 5:
return record.ring;
}
return "N/A";
}
#Override
public String getColumnName(int column){
/**set the title of the columns of the table**/
switch(column){
case 0:
return "First Name";
case 1:
return "Middle Name";
case 2:
return "Last Name";
case 3:
return "Age";
case 4:
return "Height(cm)";
case 5:
return "Has Championship Ring";
}
return "N/A";
}
/**turn column into checkboxes**/
#Override
public Class<?> getColumnClass(int column){
if(column == 5){
return Boolean.class;
}
return String.class;
}
#Override
public boolean isCellEditable(int row, int column){
return column == 5;
}
#Override
public void setValueAt(Object avalue, int row, int column){
TableRecord record;
Boolean v;
switch(column){
case 5:
record = tableRecordArrayList.get(row);
v = (Boolean) avalue;
record.ring = v;
fireTableCellUpdated(row,1);
printArrayList();
fireTableDataChanged();
break;
}
}
}
}
this question has been solved. Please visit this link to find the solution.
https://coderanch.com/t/700630/java/uncheck-JCheckBox-header-columns#3288215
I want to make it so that if you check the checkbox header so that all the boxes in the column become checked, uncheck one of the checkboxes in the column after will uncheck the checkbox header.
Add a TableModelListener to the TableModel.
When the TableModelEvent is generated you can check if the data was changed in your column containing the checkbox and then reset the header checkbox when required.
Check out: JTable -> TableModeListener for a basic example of using a TableModelListener.
I have a JTable with 10 columns headers: "A","d","e","f","B","g","h","C","i","j".I want in first view JTable Show only "A","B","C" and I have two JButton when clicked on ViewAll Button all columns show and when clicked on hide Jtable show only three columns with "A","B","C" headers.how can do it?my GridTableModel is:
public abstract class GridTableModel<T> extends AbstractTableModel {
private static final long serialVersionUID = 4283080272635443348L;
private List<T> rows = new ArrayList<T>();
/**
* The property used to find real index of rows that currently are shown to user.
*/
private int offset;
public abstract String[] getColumnNames();
#Override
public String getColumnName(int column) {
return getColumnNames()[column];
}
#Override
public int getColumnCount() {
return getColumnNames().length;
}
#Override
public int getRowCount() {
return rows == null ? 0 : rows.size();
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (rows.size() > 0) {
return getValueAt(rows.get(rowIndex), rowIndex, columnIndex);
}
return null;
}
public void setData(List<T> results, int offset) {
this.rows = results;
this.offset = offset;
fireTableDataChanged();
}
public T get(int row) {
return rows.size() > 0 ? rows.get(row) : null;
}
public abstract Object getValueAt(T t, int rowIndex, int columnIndex);
public List<T> get(int[] rows) {
List<T> list = new ArrayList<T>();
for (int row : rows) {
list.add(this.rows.get(row));
}
return list;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public List<T> getRows() {
return rows;
}
#Override
public Class<?> getColumnClass(int columnIndex) {
if (1==1) {
return Object.class;
}
return getValueAt(0, columnIndex).getClass();
}
}
Attempting to create a custom JTable structure, I started with a very simple project to better understand. Unfortunately, as soon as I start to customize stuff, I get weird behaviours and I would like you to help me understand them. Thank you very much.
Here is my small project :
public class Tableau extends JFrame {
public Tableau() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800,600);
setContentPane(new Panel());
setVisible(true);
}
public static void main(String[] args) {
new Tableau();
}
private static class Panel extends JPanel {
private JTable table = new Table(4, 4);
public Panel() {
add(table);
}
}
private static class Table extends JTable {
private Renderer randerer = new Renderer();
public Table(int row, int col) {
super(new Model(row, col));
setAutoResizeMode(AUTO_RESIZE_OFF);
setDefaultRenderer(String.class, randerer);
setDefaultEditor(String.class, randerer);
}
private class Renderer implements TableCellRenderer, TableCellEditor {
String previousContent = "";
JTextPane rendererComponent = new JTextPane();
public Renderer() {
super();setOpaque(true);
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
rendererComponent.setText((String)value);
rendererComponent.setBorder(hasFocus ? BorderFactory.createLineBorder(Color.RED) : null);
rendererComponent.setBackground(isSelected ? Color.PINK : Color.GREEN);
FontMetrics fm = rendererComponent.getFontMetrics(rendererComponent.getFont());
if(((String)value).length()!=0) {rendererComponent.setPreferredSize(new Dimension(fm.stringWidth((String)value),fm.getHeight()));}
else {rendererComponent.setPreferredSize(new Dimension(20, fm.getHeight()));}
return rendererComponent;
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
rendererComponent.setText((String)value);
rendererComponent.setBackground(isSelected ? table.getSelectionBackground() : Color.MAGENTA);
if(isSelected) {rendererComponent.selectAll();}
previousContent = (String)value;
return rendererComponent;
}
#Override
public Object getCellEditorValue() {
return rendererComponent.getText();
}
#Override
public boolean isCellEditable(EventObject anEvent) {
return true;
}
#Override
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
#Override
public boolean stopCellEditing() {
fireEditingStoppedEvent();
return true;
}
#Override
public void cancelCellEditing() {
rendererComponent.setText(previousContent);
fireEditingCanceledEvent();
}
protected void fireEditingStoppedEvent() {
for(CellEditorListener l : listeners) {l.editingStopped(new ChangeEvent(this));}
}
protected void fireEditingCanceledEvent() {
for(CellEditorListener l : listeners) {l.editingCanceled(new ChangeEvent(this));}
}
private List<CellEditorListener> listeners = new LinkedList<CellEditorListener>();
#Override
public void addCellEditorListener(CellEditorListener l) {
listeners.add(l);
}
#Override
public void removeCellEditorListener(CellEditorListener l) {
listeners.remove(l);
}
}
}
private static class Model implements TableModel {
// private ColumnModel colonnes = new ColumnModel();
private List<List<Cellule>> colonnes = new LinkedList<List<Cellule>>();
private int rowCount = 0;
// private List<Cellule> cellules = new LinkedList<Cellule>();
private static class Cellule {
public Cellule() {}
public Cellule(Object content) {this.content = content;}
private Object content;
private Object getContent() {return content;}
private void setContent(Object newContent) {content = newContent;}
}
public Model(int row, int col) {
for(int j=0; j<col; j++) {
insertColumn(j);
}
for(int i=0; i<row; i++) {
insertRow(i);
}
}
#Override
public int getRowCount() {
return rowCount;
}
#Override
public int getColumnCount() {
return colonnes.size();
}
#Override
public String getColumnName(int columnIndex) {
String result = "";
for (; columnIndex >= 0; columnIndex = columnIndex / 26 - 1) {
result = (char)((char)(columnIndex%26)+'A') + result;
}
return result;
}
#Override
public Class<?> getColumnClass(int columnIndex) {
return colonnes.isEmpty() ? Object.class : getValueAt(columnIndex, 0).getClass();
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return colonnes.get(columnIndex).get(rowIndex).getContent();
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
colonnes.get(columnIndex).get(rowIndex).setContent(aValue);
fireTableChanged(new TableModelEvent(this, rowIndex, rowIndex, columnIndex, TableModelEvent.UPDATE));
}
protected void fireTableChanged(TableModelEvent e) {
for(TableModelListener l : listeners) {
l.tableChanged(null);
}
}
public void insertColumn(int index) {
List<Cellule> newColumn = new LinkedList<Cellule>();
for(int i = 0; i<getRowCount(); i++) {
Cellule newCell = new Cellule("");
newColumn.add(newCell);
}
colonnes.add(index, newColumn);
fireTableChanged(new TableModelEvent(this, 0, getRowCount(), index, TableModelEvent.INSERT));
}
public void insertRow(int index) {
for(List<Cellule> colonne : colonnes) {
Cellule newCell = new Cellule("");
colonne.add(index, newCell);
}
rowCount++;
fireTableChanged(new TableModelEvent(this, index, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
}
public void removeColumn(int index) {
colonnes.remove(index);
fireTableChanged(new TableModelEvent(this, 0, getRowCount(), index, TableModelEvent.DELETE));
}
public void removeRow(int index) {
for(List<Cellule> row : colonnes) {
row.remove(index);
}
rowCount--;
fireTableChanged(new TableModelEvent(this, index, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE));
}
private List<TableModelListener> listeners = new LinkedList<TableModelListener>();
#Override
public void addTableModelListener(TableModelListener l) {
listeners.add(l);
}
#Override
public void removeTableModelListener(TableModelListener l) {
listeners.remove(l);
}
}
}
Basically, we have a JFrame (class Tableau), containing a JPanel (class Panel) containing a JTable (class Table). This Table uses a TableModel (class Model) and a JTextPane (class Renderer) that will serve for both rendering and editing the table content.
Here are my problems :
1) If I click a cell, it becomes white (which I don't understand how it is possible given the code of the renderer...). If I write something, first, nothing appears in the cell, but then, when I move the focus, the text appears...
2) If I click a cell and then move the focus using arrow keys, only then the selections seems to be done correctly. The red border is correctly displayed, etc. Why is the selection incorrect when I just click, without using arrows ?
Thanks !
I am trying to add image Icon in Jtable's cell. I have a code as mentioned below. What should I do for that?
package com.orb;
private final LinkedList<Product> list= new LinkedList<Product>();
private final LinkedList<Boolean> checkList = new LinkedList<Boolean>();
public void addItem(Product customer) {
list.add(customer);
checkList.add(false);
checkList.remove(true);
fireTableDataChanged();
}
#Override
public int getColumnCount() {
return 6;
}
#Override
public int getRowCount() {
return list.size();
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object obj = null;
if(columnIndex==4){
setTotal(list.get(rowIndex));
}
switch (columnIndex){
case 0: obj= list.get(rowIndex).getCode() ;break;
case 1: obj=list.get(rowIndex).getDescription(); break;
case 2: obj=list.get(rowIndex).getQuantity();break;
case 3: obj=list.get(rowIndex).getPrice();break;
case 4: obj=list.get(rowIndex).getTotal();break;
}
return obj;
}
#Override
public Class<?> getColumnClass(int arg0) {
switch(arg0){
case 0: case 1: return String.class;
case 2: return Integer.class;
case 3: case 4: return Double.class;
//case 5: return ImageIcon.class;
}
return super.getColumnClass(arg0);
}
#Override
public boolean isCellEditable(int arg0, int arg1) {
boolean isCellEditable = false;
switch(arg1){
case 2: case 3: isCellEditable= true;break;
default: isCellEditable= false;break;
}
return isCellEditable;
//return super.isCellEditable(arg0, arg1);
}
#Override
public void setValueAt(Object arg0, int arg1, int arg2) {
System.out.println("Value seted" +arg0 + arg1 + arg2);
switch(arg2){
case 0: break;
case 1: break;
case 2: list.get(arg1).setQuantity((Integer)arg0); setTotal(list.get(arg1)); break;
case 3: list.get(arg1).setPrice((Double)arg0); setTotal(list.get(arg1));break;
case 4: list.get(arg1).setTotal((Double)arg0);break;
//case 0: checkList.set(arg1, (Boolean)arg0);break;
default:break;
}
fireTableDataChanged();
}
public LinkedList<Product> getList() {
LinkedList<Product> temp = new LinkedList<Product>();
int index=-1;
for(Boolean isSelected:checkList){
index++;
if(isSelected){
temp.add(list.get(index));
}
}
return temp;
}
public void deleteRow(int rowNubmer)
{
list.remove(rowNubmer);
fireTableDataChanged();
}
public void setTotal(Product product){
Double total = 0.0d;
total = product.getQuantity ()* product.getPrice();
product.setTotal(total);
}
#Override
public void fireTableDataChanged() {
super.fireTableDataChanged();
}
I have a table model like above. I want to add image icon in table cell and want to delete cell when that icon is pressed. How can I do with this code?
Please give me full description over this.
You can use a DefaltTableCellRenderer which is backed by a JLabel which you can then use to set the icon.
The best solution would be to extend DefaltTableCellRenderer and override the getTableCellRendererComponent method and apply the icon as is needed on a cell by cell need
You can apply renderers either by defining the default renderer for a given Class type or directly to the column
Check out How to Use JTables and Using Custom Renderers in particular
UPDATED with example
This is A approach, there are many more...
public class TestTable {
public static void main(String[] args) {
new TestTable();
}
public TestTable() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JTable table = new JTable();
table.setGridColor(Color.LIGHT_GRAY);
table.setShowGrid(true);
table.setShowHorizontalLines(true);
table.setShowVerticalLines(true);
table.setModel(new TestTableModel());
table.getColumn("X").setCellRenderer(new DeleteCellRenderer());
table.getColumn("X").setCellEditor(new DeleteCellEditor());
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected class TestTableModel extends AbstractTableModel {
private List<RowData> rowData;
public TestTableModel() {
rowData = new ArrayList<RowData>(25);
for (int index = 0; index < 10; index++) {
rowData.add(new RowData(index));
}
}
#Override
public String getColumnName(int column) {
return column == 0 ? "Text" : "X";
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
RowData rd = rowData.get(rowIndex);
return rd.isDeletable();
}
#Override
public int getRowCount() {
return rowData.size();
}
#Override
public int getColumnCount() {
return 2;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
RowData rd = rowData.get(rowIndex);
return columnIndex == 0 ? rd.getText() : rd.isDeletable();
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
RowData rd = rowData.get(rowIndex);
if (columnIndex == 1) {
if (aValue instanceof Boolean && (Boolean)aValue) {
rowData.remove(rd);
fireTableRowsDeleted(rowIndex, rowIndex);
}
}
}
}
public class RowData {
private String text;
private boolean deletable;
public RowData(int row) {
text = "Row " + row;
deletable = Math.round(Math.random() * 1) == 0;
}
public String getText() {
return text;
}
public boolean isDeletable() {
return deletable;
}
}
public class DeleteCellRenderer extends DefaultTableCellRenderer {
public DeleteCellRenderer() {
try {
BufferedImage img = ImageIO.read(getClass().getResource("/Delete.png"));
setIcon(new ImageIcon(img));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setText(null);
if (value instanceof Boolean && (Boolean)value) {
setEnabled(true);
} else {
setEnabled(false);
}
return this;
}
}
public class DeleteCellEditor extends AbstractCellEditor implements TableCellEditor {
private JLabel label;
public DeleteCellEditor() {
label = new JLabel("Delete");
}
#Override
public Object getCellEditorValue() {
return true;
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
stopCellEditing();
}
});
return label;
}
#Override
public boolean isCellEditable(EventObject e) {
return true;
}
}
}
Updated
Why not use a JButton/TableCellEditor? Here's why
This is done through the custom cell renderer that can extend JLabel. You can easily set the icon for JLabel.
Renderer is a component that must draw itself as a table cell after JTable calls getTableCellRendererComponent passing the cells state and content. It is common for a renderer then to set properties on its own and return this. The renderer can also return some other object as long as it extends Component.
I have a JTable with a custom TableCellRenderer and a custom TableCellEditor. By default, the first click on a table row switch from renderer to editor and the second click select the row.
Is there any way I can make the row selected on a single click (and swith to the editor)?
I have tried to use:
table.getSelectionModel().setSelectionInterval(row, row);
in my getTableCellEditorComponent but it doesn't work, and if I add it to my getTableCellRendererComponent it works, but only sometimes.
Here is a full example:
public class SelectRowDemo extends JFrame {
public SelectRowDemo() {
CellRendererAndEditor rendererAndEditor = new CellRendererAndEditor();
StringTableModel model = new StringTableModel();
JTable table = new JTable(model);
table.setDefaultEditor(String.class, rendererAndEditor);
table.setDefaultRenderer(String.class, rendererAndEditor);
model.addElement("");
model.addElement("");
model.addElement("");
add(new JScrollPane(table));
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
new SelectRowDemo();
}
});
}
class CellRendererAndEditor extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private final JLabel renderer = new JLabel();
private final JLabel editor = new JLabel();
#Override
public Object getCellEditorValue() {
return editor.getText();
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
String str = "renderer ";
str += (isSelected) ? "selected" : "not selected";
renderer.setText(str);
return renderer;
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
table.getSelectionModel().setSelectionInterval(row, row);
String str = "editor ";
str += (isSelected) ? "selected" : "not selected";
editor.setText(str);
return editor;
}
}
class StringTableModel extends AbstractTableModel {
private final List<String> data = new ArrayList<String>();
#Override
public int getColumnCount() {
return 1;
}
#Override
public int getRowCount() {
return data.size();
}
#Override
public Object getValueAt(int row, int column) {
return data.get(row);
}
#Override
public Class<?> getColumnClass(int column) {
return String.class;
}
#Override
public boolean isCellEditable(int row, int column) {
return true;
}
#Override
public void setValueAt(Object aValue, int row, int column) {
if(aValue instanceof String) {
data.set(row, (String)aValue);
fireTableRowsUpdated(row, column);
} else throw new IllegalStateException("aValue is not a String");
}
public void addElement(String s) {
data.add(s);
}
}
}
What's happening is that the table UI is starting to edit the cell before changing selection. If you put a println in getTableCellEditor() and shouldSelectCell(), the editor gets called first, with isSelected == false, then it calls shouldSelectCell and changes the selection.
You can see exactly where it happens in BasicTableUI.adjustSelection(MouseEvent).
boolean dragEnabled = table.getDragEnabled();
if (!dragEnabled && !isFileList && table.editCellAt(pressedRow, pressedCol, e)) {
setDispatchComponent(e);
repostEvent(e);
}
CellEditor editor = table.getCellEditor();
if (dragEnabled || editor == null || editor.shouldSelectCell(e)) {
table.changeSelection(pressedRow, pressedCol,
BasicGraphicsUtils.isMenuShortcutKeyDown(e),
e.isShiftDown());
}
As for rendering purposes, I'd just render it as if selected == true, since it will before that event is finished processing.