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();
}
}
Related
I have stored in a List a dataset from the Database. (It contains data of a single column).
In my inner class which implements my own TableDataModel I simply convert that List to a Vector to feed the JTable. In a second column I would like to display for each row a JCheckBox (rows with ticked Checkboxes will be stored afterwards in the database).
How can I extend/append the List/Vector with the "Boolean.TRUE" or "Boolean.False" as the value for the second column?
Sorry I am bloody newbie... thanks a lot
class SetVehicleCategoryTableModel extends AbstractTableModel {
private List<Category> all = null;
Vector<Object> tableData;
Vector<String> tableHeaders;
public SetVehicleCategoryTableModel(){
initModel();
}
public void initModel(){
tableData = new Vector<Object>();
// TableModel's column names
tableHeaders = new Vector<String>();
tableHeaders.add("Category");
tableHeaders.add("Selection");
// Database call
all = new ReadCategory().allCategories();
// TableModel's data
// converting List<Category> -> Vector<Object> tableData
for(Object o : all) {
tableData.addElement(o);
//tableData.add(,o);
// debug:
System.out.println("item added");
}
//debug:
System.out.println(tableData.size());
for(Object obj : tableData){
System.out.println(obj.toString());
}
}
#Override
public int getRowCount() {
return tableData.size();
}
#Override
public int getColumnCount() {
return tableHeaders.size();
}
#Override
public String getColumnName(int column){
return tableHeaders.elementAt(column);
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return tableData.elementAt(rowIndex);
//return ((Vector<Object>) tableData.get(rowIndex)).get(columnIndex);
}
public void removeRow(int row) {
tableData.removeElementAt(row);
fireTableDataChanged();
}
public void insertRow(Object aValue) {
tableData.addElement(aValue);
fireTableDataChanged();
//fireTableRowsInserted(index, index);
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex){
Category edit = (Category) tableData.elementAt(rowIndex);
edit.setName((String) aValue);
fireTableCellUpdated(rowIndex, columnIndex);
//fireTableRowsUpdated(rowIndex, columnIndex);
}
// This method is used by the JTable to define the default
// renderer or editor for each cell. For example if you have
// a boolean data it will be rendered as a check box. A
// number value is right aligned.
/*#Override
public Class<?> getColumnClass(int columnIndex) {
return getValueAt(0, columnIndex).getClass();
//return data[0][columnIndex].getClass();
}*/
public Class<?> getColumnClass(int columnIndex) {
return getValueAt(0, columnIndex).getClass();
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
}
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.
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'm trying to read a csv file and get it setup to convert into another format to save some time at work, but the JTable i'm loading it into throws an exception when a row has a length less than the expected column. Is there a method to create an empty cell if row length < column length?
here is the table model:
private class CSVTableModel extends AbstractTableModel{
private ArrayList<String[]> list;
private String[] columns;
public CSVTableModel() {
this.list = p.getData();
this.columns = p.getHeaders();
}
#Override
public String getColumnName(int col) {
return columns[col];
}
#Override
public int getRowCount() {
return list.size();
}
#Override
public int getColumnCount() {
return columns.length;
}
#Override
public Object getValueAt(int row, int col) {
return list.get(row)[col];
}
#Override
public void setValueAt(Object value, int row, int col) {
list.get(row)[col] = (String) value;
this.fireTableCellUpdated(row, col);
}
}
So you can see with the getValueAt(int row, int col) method it will cause an error if the col exceeds the String[].length.
I literally solved it after posting. Rubber duck debugging.
#Override
public Object getValueAt(int row, int col) {
if ( col < list.get(row).length ) {
return list.get(row)[col];
} else {
return "";
}
}
added a condition and works fine now. Should've seen it before.
I have a JTable for which I have made a table model. But on passing the column names to table model, it is not updating the column names. Can someone tell me why?
class MyTableModelTwo extends AbstractTableModel {
private Object[][] data;
private String[] columnNames = {"Name", "ID Number", "CGPA"};
public MyTableModelTwo(Object[][] data) {
this.data = data;
}
#Override
public int getRowCount() {
return data.length;
}
#Override
public int getColumnCount() {
return columnNames.length;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
#Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
#Override
public boolean isCellEditable(int rowIndes, int columnIndex) {
return false;
}
#Override
public void setValueAt(Object value, int rowIndex, int columnIndex) {
data[rowIndex][columnIndex] = value;
fireTableCellUpdated(rowIndex, columnIndex);
}
}
class MyTableTwo extends JPanel implements TableModelListener {
private JTable table;
private Object[][] data;
private JTextField t;
public MyTableTwo() {
data = new Object[3][3];
t = new JTextField();
for (int i = 0; i < noElements; i++) {
data[i][0] = "Kaushik";
data[i][1] = "2008A3";
data[i][2] = "7.79";
}
MyTableModelTwo m = new MyTableModelTwo(data);
table = new JTable(m);
}
#Override
public void tableChanged(TableModelEvent e) {
int row = table.getRowCount();
double sum = 0, d = 0;
for (int i = 0; i < row; i++) {
double c = (Double) table.getValueAt(i, 16);
sum += c;
}
t.setText("" + sum);
t.setHorizontalAlignment(JTextField.RIGHT);
}
}
You need to override getColumnName(int index) in your TableModel.
#Override
public String getColumnName(int index) {
return columnNames[index];
}