popupmenu for a cell in a JTable

S

shoa

Hello

I want to have a popupmenu when I right click on a selected cell in a JTable
(using with a AbtractTableModel). What are steps I should do, please help.

Thank you
S.Hoa
 
R

Roland

Hello

I want to have a popupmenu when I right click on a selected cell in a JTable
(using with a AbtractTableModel). What are steps I should do, please help.

Thank you
S.Hoa
Basically you need to
(1) get the colum and row index of the cell on which you clicked:
jTable.columnAtPoint(p);
jTable.rowAtPoint(p);
(2) convert the column index to the table's model index:
jTable.convertColumnIndexToModel(col);
(3) create popup menu and add menu items specific for the row and/or
column
(4) show the popup menu

Here's a complete example:


import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

import javax.swing.CellEditor;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class TableMenu extends JFrame {
public static void main(String[] args) {
TableMenu app = new TableMenu();
app.getTableModel().addItem("Apple", 1.39, 3);
app.getTableModel().addItem("Pear", 2.19, 2);
app.getTableModel().addItem("Banana", 1.52, 4);
app.setVisible(true);
}

private static final String PROP_CHANGE_QUANTITY = "CHANGE_QUANTITY";

private static String getClipboardContents(Object requestor) {
Transferable t = Toolkit.getDefaultToolkit()
.getSystemClipboard().getContents(requestor);
if (t != null) {
DataFlavor df = DataFlavor.stringFlavor;
if (df != null) {
try {
Reader r = df.getReaderForText(t);
char[] charBuf = new char[512];
StringBuffer buf = new StringBuffer();
int n;
while ((n = r.read(charBuf, 0, charBuf.length)) > 0) {
buf.append(charBuf, 0, n);
}
r.close();
return (buf.toString());
} catch (IOException ex) {
ex.printStackTrace();
} catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
}
}
}
return null;
}

private static boolean isClipboardContainingText(Object requestor) {
Transferable t = Toolkit.getDefaultToolkit()
.getSystemClipboard().getContents(requestor);
return t != null
&& (t.isDataFlavorSupported(DataFlavor.stringFlavor) || t
.isDataFlavorSupported(DataFlavor.plainTextFlavor));
}

private static void setClipboardContents(String s) {
StringSelection selection = new StringSelection(s);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
selection, selection);
}

private JPanel jContentPane;

private JScrollPane jScrollPane;

private JTable jTable;

private ExampleTableModel tableModel;

public TableMenu() {
super();
initialize();
}

private JTable getJTable() {
if (jTable == null) {
jTable = new JTable();
jTable.setModel(getTableModel());
jTable.addMouseListener(new MouseAdapter() {

private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger() && jTable.isEnabled()) {
Point p = new Point(e.getX(), e.getY());
int col = jTable.columnAtPoint(p);
int row = jTable.rowAtPoint(p);

// translate table index to model index
int mcol = jTable.getColumn(
jTable.getColumnName(col)).getModelIndex();

if (row >= 0 && row < jTable.getRowCount()) {
cancelCellEditing();

// create popup menu...
JPopupMenu contextMenu = createContextMenu(row,
mcol);

// ... and show it
if (contextMenu != null
&& contextMenu.getComponentCount() > 0) {
contextMenu.show(jTable, p.x, p.y);
}
}
}
}

public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}

public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
});
}
return jTable;
}

private void cancelCellEditing() {
CellEditor ce = getJTable().getCellEditor();
if (ce != null) {
ce.cancelCellEditing();
}
}

private JPopupMenu createContextMenu(final int rowIndex,
final int columnIndex) {
JPopupMenu contextMenu = new JPopupMenu();

JMenuItem copyMenu = new JMenuItem();
copyMenu.setText("Copy");
copyMenu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Object value = getTableModel().getValueAt(rowIndex,
columnIndex);
setClipboardContents(value == null ? "" : value
.toString());
}
});
contextMenu.add(copyMenu);

JMenuItem pasteMenu = new JMenuItem();
pasteMenu.setText("Paste");
if (isClipboardContainingText(this)
&& getTableModel().isCellEditable(rowIndex, columnIndex)) {
pasteMenu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String value = getClipboardContents(TableMenu.this);
getTableModel().setValueAt(value, rowIndex,
columnIndex);
}
});
} else {
pasteMenu.setEnabled(false);
}
contextMenu.add(pasteMenu);

switch (columnIndex) {
case ExampleTableModel.COLUMN_NAME:
break;
case ExampleTableModel.COLUMN_PRICE:
break;
case ExampleTableModel.COLUMN_QUANTITY:
contextMenu.addSeparator();
ActionListener changer = new ActionListener() {

public void actionPerformed(ActionEvent e) {
JMenuItem sourceItem = (JMenuItem) e.getSource();
Object value = sourceItem
.getClientProperty(PROP_CHANGE_QUANTITY);
if (value instanceof Integer) {
Integer changeValue = (Integer) value;
Integer currentValue = (Integer) getTableModel()
.getValueAt(rowIndex, columnIndex);
getTableModel().setValueAt(
new Integer(currentValue.intValue()
+ changeValue.intValue()), rowIndex,
columnIndex);
}
}
};
JMenuItem changeItem = new JMenuItem();
changeItem.setText("+1");
changeItem.putClientProperty(PROP_CHANGE_QUANTITY,
new Integer(1));
changeItem.addActionListener(changer);
contextMenu.add(changeItem);

changeItem = new JMenuItem();
changeItem.setText("-1");
changeItem.putClientProperty(PROP_CHANGE_QUANTITY,
new Integer(-1));
changeItem.addActionListener(changer);
contextMenu.add(changeItem);

changeItem = new JMenuItem();
changeItem.setText("+10");
changeItem.putClientProperty(PROP_CHANGE_QUANTITY,
new Integer(10));
changeItem.addActionListener(changer);
contextMenu.add(changeItem);

changeItem = new JMenuItem();
changeItem.setText("-10");
changeItem.putClientProperty(PROP_CHANGE_QUANTITY,
new Integer(-10));
changeItem.addActionListener(changer);
contextMenu.add(changeItem);

changeItem = null;
break;
case ExampleTableModel.COLUMN_AMOUNT:
break;
default:
break;
}
return contextMenu;
}

private JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(getJScrollPane(),
java.awt.BorderLayout.CENTER);
}
return jContentPane;
}

private JScrollPane getJScrollPane() {
if (jScrollPane == null) {
jScrollPane = new JScrollPane();
jScrollPane.setViewportView(getJTable());
}
return jScrollPane;
}

private ExampleTableModel getTableModel() {
if (tableModel == null) {
tableModel = new ExampleTableModel();
}
return tableModel;
}

private void initialize() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300, 200);
this.setContentPane(getJContentPane());
this.setTitle("Application");
}

}

class ExampleTableModel extends AbstractTableModel {
private static class Item {
private String name;

private double price;

private int quantity;

public Item(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}

public double getAmount() {
return quantity * price;
}
}

public static final int COLUMN_AMOUNT = 3;

public static final int COLUMN_NAME = 0;

public static final int COLUMN_PRICE = 1;

public static final int COLUMN_QUANTITY = 2;

private List items = new ArrayList();

public void addItem(String name, double price, int quantity) {
items.add(new Item(name, price, quantity));
}

public Class getColumnClass(int columnIndex) {
switch (columnIndex) {
case COLUMN_NAME:
return String.class;
case COLUMN_PRICE:
case COLUMN_AMOUNT:
return Double.class;
case COLUMN_QUANTITY:
return Integer.class;
default:
return Object.class;
}
}

public int getColumnCount() {
return 4;
}

public String getColumnName(int columnIndex) {
switch (columnIndex) {
case COLUMN_NAME:
return "Name";
case COLUMN_PRICE:
return "Price";
case COLUMN_QUANTITY:
return "Quantity";
case COLUMN_AMOUNT:
return "Amount";

default:
return "# COLUMN " + columnIndex + " #";
}
}

public int getRowCount() {
return items.size();
}

public Object getValueAt(int rowIndex, int columnIndex) {
Item item = (Item) items.get(rowIndex);
switch (columnIndex) {
case COLUMN_NAME:
return item.name;
case COLUMN_PRICE:
return new Double(item.price);
case COLUMN_QUANTITY:
return new Integer(item.quantity);
case COLUMN_AMOUNT:
return new Double(item.getAmount());
default:
return null;
}
}

public boolean isCellEditable(int rowIndex, int columnIndex) {
switch (columnIndex) {
case COLUMN_NAME:
case COLUMN_PRICE:
case COLUMN_QUANTITY:
return true;
case COLUMN_AMOUNT:
default:
return false;
}
}

public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Item item = (Item) items.get(rowIndex);
switch (columnIndex) {
case COLUMN_NAME:
item.name = aValue.toString();
fireTableCellUpdated(rowIndex, columnIndex);
break;
case COLUMN_PRICE:
try {
item.price = Double.parseDouble(aValue.toString());
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
fireTableCellUpdated(rowIndex, columnIndex);
fireTableCellUpdated(rowIndex, COLUMN_AMOUNT);
break;
case COLUMN_QUANTITY:
try {
item.quantity = Integer.parseInt(aValue.toString());
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
fireTableCellUpdated(rowIndex, columnIndex);
fireTableCellUpdated(rowIndex, COLUMN_AMOUNT);
break;
case COLUMN_AMOUNT:
default:
return;
}
}
}

--
Regards,

Roland de Ruiter
` ___ ___
`/__/ w_/ /__/
/ \ /_/ / \
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top