I have a JTable that is used to capture user input which later will be printed upon hitting the Print button. I have an image that I would want to be the header and another one to be a footer.an image showing this can be found here. I have followed the example that I found from oracle documents here. I want it exactly the way it is done in TablePrintdemo3 here.
Allow me to post the classes here.
Here is my first class:
public class Product {
String productDescription;
Double productPrice;
//dummy properties
Integer productQuantity;
Double productTotalAmount;
public Product() {
this.productDescription = "";
this.productPrice = 0.0;
this.productTotalAmount = 0.0;
this.productQuantity = 0;
}//getters and setters here
}
The second class is a custom model as shown here:
public class ProductTableModel extends AbstractTableModel {
private final List<String> columnNames;
private final List<Product> products;
public ProductTableModel() {
String[] header = new String[] {
"Quantity",
"Description",
"Unity Price",
"Total Price"
};
this.columnNames = Arrays.asList(header);
this.products = new ArrayList<>();
}
#Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0: return Integer.class;
case 1: return String.class;
case 2: return Double.class;
case 3: return Double.class;
default: throw new ArrayIndexOutOfBoundsException(columnIndex);
}
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
Product product = this.getProduct(rowIndex);
switch (columnIndex) {
case 0: return product.getProductQuantity();
case 1: return product.getProductDescription();
case 2: return product.getProductPrice();
case 3: return product.getProductTotalAmount();
default: throw new ArrayIndexOutOfBoundsException(columnIndex);
}
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex < 0 || columnIndex >= getColumnCount()) {
throw new ArrayIndexOutOfBoundsException(columnIndex);
} else {
Product product = this.getProduct(rowIndex);
switch (columnIndex) {
case 0: product.setProductQuantity((Integer)aValue); break;
case 1: product.setProductDescription((String)aValue); break;
case 2: product.setProductPrice((Double)aValue); break;
case 3: product.setProductTotalAmount((Double)aValue); break;
}
fireTableCellUpdated(rowIndex, columnIndex);
}
}
#Override
public int getRowCount() {
return this.products.size();
}
#Override
public int getColumnCount() {
return this.columnNames.size();
}
#Override
public String getColumnName(int columnIndex) {
return this.columnNames.get(columnIndex);
}
public void setColumnNames(List<String> columnNames) {
if (columnNames != null) {
this.columnNames.clear();
this.columnNames.addAll(columnNames);
fireTableStructureChanged();
}
}
public List<String> getColumnNames() {
return Collections.unmodifiableList(this.columnNames);
}
public void addProducts(Product product) {
int rowIndex = this.products.size();
this.products.add(product);
fireTableRowsInserted(rowIndex, rowIndex);
}
public void addProducts(List<Product> productList) {
if (!productList.isEmpty()) {
int firstRow = this.products.size();
this.products.addAll(productList);
int lastRow = this.products.size() - 1;
fireTableRowsInserted(firstRow, lastRow);
}
}
public void addEmptyRow(){
products.add(new Product());
this.fireTableRowsInserted(products.size()-1, products.size()-1);
}
public void insertProduct(Product product, int rowIndex) {
this.products.add(rowIndex, product);
fireTableRowsInserted(rowIndex, rowIndex);
}
public void deleteProduct(int rowIndex) {
if (this.products.remove(this.products.get(rowIndex))) {
fireTableRowsDeleted(rowIndex, rowIndex);
}
}
public Product getProduct(int rowIndex) {
return this.products.get(rowIndex);
}
public List<Product> getProducts() {
return Collections.unmodifiableList(this.products);
}
public void clearTableModelData() {
if (!this.products.isEmpty()) {
int lastRow = products.size() - 1;
this.products.clear();
fireTableRowsDeleted(0, lastRow);
}
}
}
The third class is my is as follows:
public class NiceTablePrinting extends MainClass{
#Override
protected JTable initializeTable(TableModel model) {
return new NicePrintingJTable(model);
}
private static class NicePrintingJTable extends JTable {
public NicePrintingJTable(TableModel model) {
super(model);
}
/**
* Overridden to return a fancier printable, that wraps the default.
* Ignores the given header and footer. Renders its own header.Always
* uses the page number as the footer.
*/
#Override
public Printable getPrintable(PrintMode printMode,
MessageFormat headerFormat,
MessageFormat footerFormat) {
MessageFormat pageNumber = new MessageFormat("- {0} -");
/* Fetch the default printable */
Printable delegate = per.getPrintable(printMode,null,pageNumber);
/* Return a fancy printable that wraps the default */
return new NicePrintable(delegate);
}
}
private static class NicePrintable implements Printable {
Printable delegate;
//
BufferedImage header;
BufferedImage footer;
//
boolean imagesLoaded;
{
try{
header=ImageIO.read(getClass().getResource("images/header.PNG"));
footer=ImageIO.read(getClass().getResource("images/footer.PNG"));
imagesLoaded=true;
}
catch(IOException ex)
{
ex.printStackTrace();
}
imagesLoaded=false;
}
public NicePrintable(Printable delegate) {
this.delegate = delegate;
}
#Override
public int print(Graphicsg,PageFormatpf,intpi)throwsPrinterException
{
if(!imagesLoaded){
return delegate.print(g, pf, pi);
}
//top origin
int x=(int)pf.getImageableX();
int y=(int)pf.getImageableY();
//
int iw=(int)pf.getImageableWidth();
int ih=(int)pf.getImageableHeight();
//image header
int hh= header.getHeight();
int hw=header.getWidth();
//image footer
int fh=footer.getHeight();
int fw=footer.getWidth();
int fY=ih-fh-10;
int fX=x;
//calculating the area to print the table
int tableX=10;
int tableY=hh +10;
int tableW=iw-20;
int tableH=ih-hh-10-fh-10;
/* create a new page format representing the shrunken area to print the table into */
PageFormat format = new PageFormat() {
#Override
public double getImageableX() {return tableX;}
#Override
public double getImageableY() {return tableY;}
#Override
public double getImageableWidth() {return tableW;}
#Override
public double getImageableHeight() {return tableH;}
};
/*
* We'll use a copy of the graphics to print the table to. This protects
* us against changes that the delegate printable could make to the graphics
* object.
*/
Graphics gCopy = g.create();
/* print the table into the shrunken area */
int retVal = delegate.print(gCopy, format, pi);
/* if there's no pages left, return */
if (retVal == NO_SUCH_PAGE) {
return retVal;
}
/* dispose of the graphics copy */
gCopy.dispose();
//draw the images
g.drawImage(header, x, y, hw, hh, null);
g.drawImage(footer, fX, fY, fw, fh, null);
return Printable.PAGE_EXISTS;
}
}
}
The fourth class is as follows:
public class MainClass {
private JTable table;
JFrame frame;
JButton print;
JScrollPane sp;
ProductTableModel model;
public MainClass(){
frame= new JFrame("Test Printing");
frame.setLayout(new java.awt.BorderLayout());
frame.setVisible(true);
///create table
model=new ProductTableModel();
table=this.initializeTable(model);
model.addEmptyRow();
table.setPreferredScrollableViewportSize(newjava.awt.Dimension(300,300));
sp= new javax.swing.JScrollPane(table);
frame.add(sp);
//button
print= new JButton("Print");
frame.add(print,BorderLayout.SOUTH);
frame.pack();
print.addActionListener((ActionEvent e) -> {
try {
printTable();
} catch (PrinterException ex) {
Logger.getLogger(MainClass.class.getName()).log(Level.SEVERE, null, ex);
}
});
}
protected JTable initializeTable(TableModel model) {
return new JTable(model);
}
public void printTable() throws PrinterException {
table.print(JTable.PrintMode.NORMAL, null, null, true, null, true);
}
public static void main(String [] args){
MainClass cl= new MainClass();
}
}
I would want to set my things the way it is done in TablePrintdemo3. Now I cannot see where I have gone wrong. Please assist.
The problem is it is printing only the table -no header and footer images.
Related
I am developing a small application on Java. I created a custom model for jtable. The model is this:
package tienda.funcionalidad;
import java.awt.Component;
import java.util.ArrayList;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import tienda.funcionalidad.excepciones.NombreNoValidoException;
import tienda.funcionalidad.excepciones.PrecioNoValidoException;
import tienda.funcionalidad.excepciones.ProductoNoExisteException;
public class ProductTableModel extends AbstractTableModel implements TableCellRenderer {
/**
*
*/
private static final long serialVersionUID = 1L;
final String[] columns = { "Producto", "Serodys", "Ramírez", "Entrada", "MercaSur" };
final ArrayList registros = GestionTienda.getProductos();
#Override
public int getColumnCount() {
return columns.length;
}
#Override
public String getColumnName(int column) {
return columns[column];
}
#Override
public int getRowCount() {
if (registros.isEmpty())
return 0;
return registros.size();
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
Product product = (Product) registros.get(rowIndex);
switch (columnIndex) {
case 0:
return product.getName();
case 1:
return product.getPriceSerodys();
case 2:
return product.getPriceRamirez();
case 3:
return product.getPriceEntrada();
case 4:
return product.getPriceMercasur();
}
return null;
}
public boolean isCellEditable(int row, int col) {
return true;
}
public Class getColumnClass(int col) {
switch (col) {
case 0: // Name
return String.class;
case 1: // value
return Double.class;
case 2: // location
return Double.class;
case 3: // quantity
return Double.class;
case 4:
return Double.class;
}
return null;
}
public void setValueAt(Object value, int row, int col) {
try {
Product product = (Product) registros.get(row);
switch (col) {
case 0: // Name
product.setName(value.toString());
break;
case 1: // value
Double priceSerodys = (Double) value;
product.setPriceSerodys(priceSerodys);
break;
case 2: // location
Double priceRamirez = (Double) value;
product.setPriceRamirez(priceRamirez);
break;
case 3: // quantity
Double priceEntrada = (Double) value;
product.setPriceEntrada(priceEntrada);
break;
case 4: // quantity
Double priceMercasur = (Double) value;
product.setPriceMercasur(priceMercasur);
break;
}
} catch (NombreNoValidoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PrecioNoValidoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public Component getTableCellRendererComponent(JTable arg0, Object arg1, boolean arg2, boolean arg3, int arg4,
int arg5) {
return null;
}
}
And the class Product is this:
package tienda.funcionalidad;
import java.io.Serializable;
import tienda.funcionalidad.excepciones.NombreNoValidoException;
import tienda.funcionalidad.excepciones.PrecioNoValidoException;
public class Product implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private int id;
private String name;
private double priceSerodys;
private double priceRamirez;
private double priceEntrada;
private double priceMercasur;
private double priceAux = 0;
public Product(int id,String name, double priceSerodys, double priceRamirez, double priceEntrada, double priceMercasur) throws PrecioNoValidoException, NombreNoValidoException {
setName(name);
setPriceSerodys(priceSerodys);
setPriceRamirez(priceRamirez);
setPriceEntrada(priceEntrada);
setPriceMercasur(priceMercasur);
setId(id);
}
public Product(int id,String nombre) throws NombreNoValidoException {
setName(nombre);
setId(id);
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
protected void setPriceSerodys(Double priceSerodys) throws PrecioNoValidoException {
if(priceSerodys<0)
throw new PrecioNoValidoException("Debes introducir un precio superior a 0");
this.priceSerodys=priceSerodys;
}
public double getPriceSerodys() {
return priceSerodys;
}
protected void setPriceRamirez(Double priceRamirez) throws PrecioNoValidoException {
if(priceRamirez<0)
throw new PrecioNoValidoException("Debes introducir un precio superior a 0");
this.priceRamirez=priceRamirez;
}
public double getPriceRamirez() {
return priceRamirez;
}
protected void setPriceEntrada(Double priceEntrada) throws PrecioNoValidoException {
if(priceEntrada<0)
throw new PrecioNoValidoException("Debes introducir un precio superior a 0");
this.priceEntrada=priceEntrada;
}
public double getPriceEntrada() {
return priceEntrada;
}
protected void setPriceMercasur(Double priceMercasur) throws PrecioNoValidoException {
if(priceMercasur<0)
throw new PrecioNoValidoException("Debes introducir un precio superior a 0");
this.priceMercasur=priceMercasur;
}
public double getPriceMercasur() {
return priceMercasur;
}
protected void setName(String nombre) throws NombreNoValidoException {
if(nombre.equals("") || nombre==null)
throw new NombreNoValidoException("Debes introducir un nombre para el producto");
this.name=nombre;
}
public String getName() {
return name;
}
public double getPrecio() {
return priceSerodys;
}
#Override
public String toString() {
return getName();
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Product other = (Product) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
}
I need color the cell with the minimun value of each row with green and grey the other values. I am not idea how i have to codify the method getTableCellRendererComponent, can someone help me?
Sorry if my english is bad, i am spanish.
Thank you.
To achieve the result your are looking for, you can override the JTable prepareRenderer method.
Please refer the code below. This is just an example code and doesn't follow the java coding standard.
Left that work for you :)
JTable table = new JTable(new ProductTableModel()){
#Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex,
int columnIndex) {
JComponent component = (JComponent) super.prepareRenderer(renderer, rowIndex, columnIndex);
int columnCount = getColumnCount();
if(columnIndex != 0){
double firstVal = Double.parseDouble(getValueAt(rowIndex, 1).toString());
for (int i = 2; i < columnCount; i++) {
Double cellValue = Double.valueOf(getValueAt(rowIndex, i).toString());
if(cellValue < firstVal ){
firstVal = cellValue;
}
}
if(firstVal == Double.valueOf(getValueAt(rowIndex, columnIndex).toString()).doubleValue()) {
component.setBackground(Color.GREEN);
} else{
component.setBackground(Color.GRAY);
}
}
return component;
}
};
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.
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.
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 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