JTable ComboBox - java

For some reason this was removed.
This question is CLOSED and i won't be reading it as i have moved onwards and implemented more methods working. So no need putting snarky comments here, i won't read them.
Ok, so this might be quite the simple question, but here goes. I am setting up a JTable for editing and i want column 1 to have a comboBox editor. I looked up how to do it and followed the instructions which lead me to the code under, however it doesn't seem to actually update into the display. What am I misssing here? Thank you in advance.
//MainWindow class
public class MainWindow extends JFrame{
GridBagConstraints gbc;
JTable gridDisplay;
private AbstractTableModel tableModel;
JLabel statusBar;
MainWindow()
{
super("LayoutEditor");
setLayout(new BorderLayout());
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
gridDisplay = new JTable();
tableModel = new MyTableModel();
gridDisplay.setAutoCreateRowSorter(true);
gridDisplay.setColumnSelectionAllowed(true);
gridDisplay.setCellSelectionEnabled(true);
gridDisplay.setModel(tableModel);
TableColumn tc = gridDisplay.getColumnModel().getColumn(0);
JComboBox<String> cb = new JComboBox<String>();
cb.addItem("JLabel");
cb.addItem("JButton");
cb.addItem("JTextField");
cb.addItem("JTextArea");
cb.addItem("JCheckBox");
cb.addItem("JList");
cb.addItem("JComboBox");
cb.addItem("JSpinnerList");
cb.addItem("JSpinnerNumber");
cb.setSelectedIndex(0);
tc.setCellEditor(new DefaultCellEditor(cb));
MyDataModel temp= new MyDataModel();
MyTableModel table = (MyTableModel)gridDisplay.getModel();
table.append(temp);
JScrollPane gridScroll = new JScrollPane(gridDisplay);
mainPanel.add(toolBox, BorderLayout.NORTH);
mainPanel.add(gridScroll, BorderLayout.CENTER);
add(mb, BorderLayout.NORTH);
add(mainPanel, BorderLayout.CENTER);
setSize(1280,720);
setVisible(true);
}
]
//myTableModel class
public class MyTableModel extends AbstractTableModel {
ArrayList<MyDataModel> data;
String[] names;
MyTableModel()
{
names = new String[]{"Type","Variable name","Text","Row","Column","Rows","Columns","Fill","Anchor"};
data = new ArrayList<MyDataModel>();
}
#Override
public int getRowCount() {
return data.size();
}
#Override
public int getColumnCount() {
return names.length;
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
switch (columnIndex)
{
case 0:
data.get(rowIndex).setType(aValue.toString());
case 1:
data.get(rowIndex).setName(aValue.toString());
case 2:
data.get(rowIndex).setText(aValue.toString());
case 3:
data.get(rowIndex).setRow((int)aValue);
case 4:
data.get(rowIndex).setColumn((int)aValue);
case 5:
data.get(rowIndex).setRows((int)aValue);
case 6:
data.get(rowIndex).setColumns((int)aValue);
case 7:
data.get(rowIndex).setFill((int)aValue);
case 8:
data.get(rowIndex).setAnchor((int)aValue);
}
fireTableCellUpdated(rowIndex, columnIndex);
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex){
case 0:
return data.get(rowIndex).getType();
case 1:
return data.get(rowIndex).getName();
case 2:
return data.get(rowIndex).getText();
case 3:
return data.get(rowIndex).getRow();
case 4:
return data.get(rowIndex).getColumn();
case 5:
return data.get(rowIndex).getRows();
case 6:
return data.get(rowIndex).getColumns();
case 7:
return data.get(rowIndex).getFill();
case 8:
return data.get(rowIndex).getAnchor();
}
return null;
}
public void append(MyDataModel item)
{
data.add(item);
}
#Override
public String getColumnName(int column) {
return names[column];
}
}
//MyDataModel Class
public class MyDataModel {
String type, name, text;
int row, column, rows, columns, fill, anchor;
MyDataModel()
{
type = new String("");
name = new String("");
text = new String("");
row = 0;
column = 0;
rows = 0;
columns = 0;
fill = 0;
anchor = 0;
}
public MyDataModel(MyDataModel test) {
type = test.getType();
name = test.getName();
text = test.getText();
row = test.getRow();
column = test.getColumn();
rows = test.getRows();
columns = test.getColumns();
fill = test.getFill();
anchor = test.getAnchor();
}
public int getAnchor() {
return anchor;
}
public void setAnchor(int anchor) {
this.anchor = anchor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getColumns() {
return columns;
}
public void setColumns(int columns) {
this.columns = columns;
}
public int getFill() {
return fill;
}
public void setFill(int fill) {
this.fill = fill;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

it doesn't seem to actually update into the display.
The value you select from the combo box is not being saved in the TableModel.
Your TableModel needs to implement the setValueAt(...) method.
See the section from the Swing tutorial on Create a Table Model for a simple implementation. It also shows you what fireXXX(...) method to invoke so the table is notified of the change in data.

You're missing a bit from your model including setValueAt(...), isCellEditable(...), and you forgot to call fireTableRowsInserted(...) inside of your append method.
e.g.,
public void append(MyDataModel item) {
data.add(item);
// !! don't forget this!!
int firstRow = getRowCount() - 1;
int lastRow = firstRow;
fireTableRowsInserted(firstRow, lastRow);
}
#Override
public String getColumnName(int column) {
return names[column];
}
#Override //!!
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == 0; // allow editing of first column
}
#Override //!!
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex == 0) {
MyDataModel row = data.get(rowIndex);
row.setType(aValue.toString());
fireTableCellUpdated(rowIndex, columnIndex);
return;
}
super.setValueAt(aValue, rowIndex, columnIndex);
}
You will want to re-read the JTable tutorial because you're skipping a lot of key concepts.
And I forgot -- you also need to override public boolean isCellEditable(int row, int col) and have it return true, at least for the JComboBox column, else you'll never see combo boxes since it is an editor.

Related

How do I uncheck a JCheckBox that I am using as one of my header columns?

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.

Jtable will not save data of the cell when editing

I have JTable that has a column editable. It should get Integer values and update table. But when I edit a cell and go to another cell, the data will erase and goes back to null but the program does not throw any exceptions. How can I fix it?
public class FoodListPanel extends JPanel{
JTable jTable;
FoodTableModel fm;
public FoodListPanel() {
try {
fm = new FoodTableModel(FoodDAO.getAllFoodsFromDB(), new ArrayList<Integer>());
jTable = new JTable(fm) {
public boolean isCellEditable(int data, int columns) {
if(columns<5){
return false;
}
else if(columns ==5){
return true;
}
else if(columns ==6){
if(getValueAt(data, 5)==Boolean.FALSE){
return false;
}
else {
return true;
}
}
else{
return true;
}
}
public Component prepareRenderer(TableCellRenderer r, int data, int columns) {
Component c = super.prepareRenderer(r, data, columns);
return c;
}
};
jTable.setPreferredScrollableViewportSize(new Dimension(650, 420));
jTable.setFillsViewportHeight(true);
JScrollPane jScrollPane = new JScrollPane(jTable);
add(jScrollPane);
} catch (SQLException e) {
e.printStackTrace();
}
}
class FoodTableModel extends AbstractTableModel {
protected String[] cols = {"نام‌غذا", "دسته‌بندی", "قیمت", "توضیحات", "عکس" , "تعداد"};
protected Class[] colClasses = {String.class, Integer.class, String.class, String.class,
JLabel.class, Integer.class};
ArrayList<Food> al;
ArrayList<Integer> vals;
public FoodTableModel(ArrayList<Food> foods, ArrayList<Integer> val) {
al = new ArrayList<Food>();
al.addAll(foods);
vals = new ArrayList<Integer>(al.size());
vals.addAll(val);
}
////// TODO: 8/20/16 make dynamic from DB
public int getColumnCount (){return cols.length;}
public int getRowCount (){return al.size();}
public String getColumnName(int col) { return cols[col]; }
public Class getColumnClass(int col) { return colClasses[col]; }
public Object getValueAt(int row, int col){
switch (col) {
case 0:
return al.get(row).getName();
case 1:
return al.get(row).getType();
case 2:
return al.get(row).getPrice();
case 3:
return al.get(row).getDiscreption();
case 5:
if(vals.size()>= al.size()) return vals.get(row);
default:
return null;
}
}
////https://stackoverflow.com/questions/39066012/index-out-of-bound-exception-when-setting-value-to-jtable
public void setValueAt(Object vlaue, int row, int column){
if (column==6){
this.vals.set(row, (Integer)vlaue);
}
this.fireTableCellUpdated(row, column);
this.fireTableDataChanged();
}
/*public void setCols(String[] columns){
cols = columns;
}
public void setClasses(Class[] classes){
colClasses = classes;
}*/
}
}
the data will erase and goes back to null
Your getValuaAt(..) and setValueAt() methods are out of sync.
In the setValueAt() you only save the data for column 6.
In the getValueAt() you only return the data for columns 0-5 and return null for column 6.
You need to fix the getValueAt(...) method to return the actual data, not null.
Also, the setValueAt(...) method should only invoke the fireTableCellUpdated(...) method not the fireTableDataChanged(...) method.

JTable Rows Not Rendered in Expected Colors

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.

How to set up icon in JTable cell?

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.

Converting selected items on a Table model to an object

I have Components I have created that are being put into a table model with two columns as below.
if (!newAcList.isEmpty()) {
for (Acronym acc : newAcList) {
tableModel.addRow(new String[]{acc.getName(), acc.getDefinition()});
}
}
What I need is when the user selects an item on the table model it converts the item back to my Acronym Object. I am using a Listselectionevent Listener.
Here is valueChanged selection event``
#Override
public void valueChanged(ListSelectionEvent e) {
String selectedAcData = null;
String selectDefData = null;
int[] selectedRow = accTable.getSelectedRows();
int[] selectedColumns = accTable.getSelectedColumns();
for (int i = 0; i < selectedRow.length; i++) {
// for (int j = 0; j < selectedColumns.length; j++) {
selectedAcData = (String) accTable.getValueAt(selectedRow[i], 0);
}
}
You might want to create a class that implements the TableModel interface for the acronyms. It might be called AcronymTableModel and is backed by a List<Acronym> list of Acronyms. Then give this model to your table.
The call to accTable.getValueAt(selectedRow[i], 0); in your valueChanged method will then return an instance of an Acronym.
Here's a quick example.
public class Example {
public static void main(String [] a) {
JFrame f = new JFrame();
JPanel p = new JPanel();
List<Acronym> acronyms = new ArrayList<Acronym>();
acronyms.add(new Acronym("FBI", "Federal Bureau of Investigation"));
acronyms.add(new Acronym("CIA", "Central Intelligence Agency"));
final TableModel tModel = new AcronymTableModel(acronyms);
JTable t = new JTable(tModel);
t.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
Acronym a = (Acronym)tModel.getValueAt(e.getFirstIndex(), 0);
System.out.println(a.acronym + ": " + a.definition);
}});
p.add(t);
f.getContentPane().add(p);
f.pack();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
class Acronym {
String acronym;
String definition;
public Acronym(String a, String d) {
acronym = a;
definition = d;
}
}
class AcronymTableModel implements TableModel {
private List<Acronym> acronyms;
public AcronymTableModel(List<Acronym> acs) {
this.acronyms = new ArrayList<Acronym>(acs);
}
#Override
public int getRowCount() {
return this.acronyms.size();
}
#Override
public int getColumnCount() {
return 2;
}
#Override
public String getColumnName(int columnIndex) {
switch(columnIndex) {
case 0:
return "Acronym";
case 1:
return "Definition";
}
return null;
}
#Override
public Class<?> getColumnClass(int columnIndex) {
return String.class; // Since both columns are simply
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return acronyms.get(rowIndex);
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
}
#Override
public void addTableModelListener(TableModelListener l) {
}
#Override
public void removeTableModelListener(TableModelListener l) {
}
}
The Java tutorials are always good and have good examples.
http://docs.oracle.com/javase/tutorial/uiswing/events/listselectionlistener.html

Categories