JButton used like a JTextArea

I have a code snippet which allows the user to click on a JTable cell, and edit the text using a pop-up window.

I want to add a context menu to this, but it doesn't seem to work with a JButton. Here is the code:

public TablePopupEditor(String strHeading)

{

super(new JTextField());

setClickCountToStart(1);

// Use a JButton as the editor component

editorComponent =new JButton();

editorComponent.setBackground(Color.white);

editorComponent.setBorderPainted(false);

editorComponent.setContentAreaFilled(false );

// editorComponent.addActionListener( this );

// Set up the dialog where we do the actual editing

popup =new PopupDialog(strHeading);

createPopupMenu();

}

I was very surprised to see this code uses a JButton (!?) like a JTextArea. It has multiple rows, you type in text, etc. Why a JButton?

Anyhow, I need to either use something else, or I need to figure out how to get a MouseListener on a JButton. The latter doesn't work right now.

The context menu code works fine in a demo program -- but it is using a JTextArea:

public Container createContentPane(){

//Create the content-pane-to-be.

JPanel contentPane =new JPanel(new BorderLayout());

contentPane.setOpaque(true);

//Create a scrolled text area.

output =new JTextArea(5, 30);

output.setEditable(true);

scrollPane =new JScrollPane(output);

//Add the text area to the content pane.

contentPane.add(scrollPane, BorderLayout.CENTER);

return contentPane;

}

Any help would be much appreciated.

Thank you,

Matthew

[2474 byte] By [CathInfoa] at [2007-11-26 20:08:07]
# 1

Here is a snapshot of what I'm trying to do:

http://www.cathinfo.com/table.jpg

Note the context menu -- it only comes up if you right-click on the bottom part of the pop-up dialog (where the OK button is) -- but it does not appear if you right-click in the text area. That is what I need to achieve.

Thanks,

Matthew

CathInfoa at 2007-7-9 23:10:36 > top of Java-index,Desktop,Core GUI APIs...
# 2

Your welcome for the original code. In case you are wondering what the OP is doing the original code came from here:

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=5129515

> but it does not appear if you right-click in the text area.

Then your code is wrong. Since you

a) didn't bother to respond when you got help the first time

b) didn't post a SSCCE showing the problem code

you are on your own.

camickra at 2007-7-9 23:10:36 > top of Java-index,Desktop,Core GUI APIs...
# 3

Here is an SSCCE which might be of help:

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.table.*;

import javax.swing.event.TableModelEvent;

import javax.swing.table.AbstractTableModel;

import javax.swing.event.TableModelListener;

import javax.swing.text.DefaultEditorKit;

import java.util.*;

import java.io.*;

import java.util.List;

import java.awt.datatransfer.*;

import java.awt.dnd.*;

public class Demo extends JPanel

implements KeyListener, ActionListener, ItemListener {

public final int NUM_RECS = 4;

MyTableModel mainTable;

TableSorter sorter;

JTable table;

JPanel mainPanel, top;

static JFrame frame;

private MouseListener mouseListener;

public Demo() {

top = new JPanel();

sorter = new TableSorter(new MyTableModel());

table = new JTable(sorter);

sorter.setTableHeader(table.getTableHeader());

// We want a horizontal scroller, not auto-resize as we shrink/grow the table

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

//Create the scroll pane and add the table to it.

JScrollPane scrollPane = new JScrollPane(table);

scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

//Add the scroll pane to this panel.

top.add(scrollPane);

setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

setBorder(BorderFactory.createEmptyBorder(5,5,5,5));

//Add all panels to the main panel.

add(top);

vLoadTableData();

}

public void actionPerformed(ActionEvent e) {

String strCommand = e.getActionCommand();

}

public void itemStateChanged(ItemEvent e) {

JMenuItem source = (JMenuItem)(e.getSource());

}

public void keyTyped(KeyEvent e) {}

public void keyPressed(KeyEvent e) {}

public void keyReleased(KeyEvent e) {}

protected void displayInfo(KeyEvent e, String s){}

public void vLoadTableData() {

TableColumn column = null;

column = table.getColumnModel().getColumn(0);

column.setPreferredWidth(50);

column = table.getColumnModel().getColumn(1);

column.setPreferredWidth(40);

column = table.getColumnModel().getColumn(2);

column.setCellEditor(new TablePopupEditor("Edit Description text"));

column.setPreferredWidth(350);

}

class MyTableModel extends AbstractTableModel {

private String[] columnNames = {"Publish", "ID", "Description"};

private Object[][] data;

MyTableModel() {

data = new Object[NUM_RECS][3];

// Sample data

data[0][0] = false;

data[0][1] = (int)101;

data[0][2] = "This is a book that is being sold at the present time. Buy yours today!";

data[1][0] = true;

data[1][1] = (int)102;

data[1][2] = "Gripping, thrilling, exciting. Tells how to grow tomatoes in your own backyard!";

data[2][0] = true;

data[2][1] = (int)103;

data[2][2] = "A story about a dog that attacks Kansas City.";

data[3][0] = false;

data[3][1] = (int)104;

data[3][2] = "Learn how to write an SSCCE that your Java forum will love.";

}

public int getColumnCount() {

return columnNames.length;

}

public int getRowCount() {

return data.length;

}

public String getColumnName(int col) {

return columnNames[col];

}

public Object getValueAt(int row, int col) {

return data[row][col];

}

public Class getColumnClass(int c) {

return getValueAt(0, c).getClass();

}

public boolean isCellEditable(int row, int col) {

return true;

}

public void setValueAt(Object value, int row, int col) {

data[row][col] = value;

fireTableCellUpdated(row, col);

}

}

private static void createAndShowGUI() {

JFrame.setDefaultLookAndFeelDecorated(false);

frame = new JFrame("Test of Product database");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.

Demo newContentPane = new Demo();

newContentPane.setOpaque(true);

frame.setContentPane(newContentPane);

frame.pack();

frame.setVisible(true);

}

public static void main(String[] args) {

//Schedule a job for the event-dispatching thread:

//creating and showing this application's GUI.

javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGUI();

}

});

}

}

class TableSorter extends AbstractTableModel {

protected TableModel tableModel;

public static final int DESCENDING = -1;

public static final int NOT_SORTED = 0;

public static final int ASCENDING = 1;

private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);

public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {

public int compare(Object o1, Object o2) {

return ((Comparable) o1).compareTo(o2);

}

};

public static final Comparator LEXICAL_COMPARATOR = new Comparator() {

public int compare(Object o1, Object o2) {

return o1.toString().compareTo(o2.toString());

}

};

private Row[] viewToModel;

private int[] modelToView;

private JTableHeader tableHeader;

private MouseListener mouseListener;

private TableModelListener tableModelListener;

private Map columnComparators = new HashMap();

private List sortingColumns = new ArrayList();

public TableSorter() {

this.mouseListener = new MouseHandler();

this.tableModelListener = new TableModelHandler();

}

public TableSorter(TableModel tableModel) {

this();

setTableModel(tableModel);

}

public TableSorter(TableModel tableModel, JTableHeader tableHeader) {

this();

setTableHeader(tableHeader);

setTableModel(tableModel);

}

private void clearSortingState() {

viewToModel = null;

modelToView = null;

}

public TableModel getTableModel() {

return tableModel;

}

public void setTableModel(TableModel tableModel) {

if (this.tableModel != null) {

this.tableModel.removeTableModelListener(tableModelListener);

}

this.tableModel = tableModel;

if (this.tableModel != null) {

this.tableModel.addTableModelListener(tableModelListener);

}

clearSortingState();

fireTableStructureChanged();

}

public JTableHeader getTableHeader() {

return tableHeader;

}

public void setTableHeader(JTableHeader tableHeader) {

if (this.tableHeader != null) {

this.tableHeader.removeMouseListener(mouseListener);

TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();

if (defaultRenderer instanceof SortableHeaderRenderer) {

this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);

}

}

this.tableHeader = tableHeader;

if (this.tableHeader != null) {

this.tableHeader.addMouseListener(mouseListener);

this.tableHeader.setDefaultRenderer(

new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));

}

}

public boolean isSorting() {

return sortingColumns.size() != 0;

}

private Directive getDirective(int column) {

for (int i = 0; i < sortingColumns.size(); i++) {

Directive directive = (Directive)sortingColumns.get(i);

if (directive.column == column) {

return directive;

}

}

return EMPTY_DIRECTIVE;

}

public int getSortingStatus(int column) {

return getDirective(column).direction;

}

private void sortingStatusChanged() {

clearSortingState();

fireTableDataChanged();

if (tableHeader != null) {

tableHeader.repaint();

}

}

public void setSortingStatus(int column, int status) {

Directive directive = getDirective(column);

if (directive != EMPTY_DIRECTIVE) {

sortingColumns.remove(directive);

}

if (status != NOT_SORTED) {

sortingColumns.add(new Directive(column, status));

}

sortingStatusChanged();

}

protected Icon getHeaderRendererIcon(int column, int size) {

Directive directive = getDirective(column);

if (directive == EMPTY_DIRECTIVE) {

return null;

}

return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));

}

private void cancelSorting() {

sortingColumns.clear();

sortingStatusChanged();

}

public void setColumnComparator(Class type, Comparator comparator) {

if (comparator == null) {

columnComparators.remove(type);

} else {

columnComparators.put(type, comparator);

}

}

protected Comparator getComparator(int column) {

Class columnType = tableModel.getColumnClass(column);

Comparator comparator = (Comparator) columnComparators.get(columnType);

if (comparator != null) {

return comparator;

}

if (Comparable.class.isAssignableFrom(columnType)) {

return COMPARABLE_COMAPRATOR;

}

return LEXICAL_COMPARATOR;

}

private Row[] getViewToModel() {

if (viewToModel == null) {

int tableModelRowCount = tableModel.getRowCount();

viewToModel = new Row[tableModelRowCount];

for (int row = 0; row < tableModelRowCount; row++) {

viewToModel[row] = new Row(row);

}

if (isSorting()) {

Arrays.sort(viewToModel);

}

}

return viewToModel;

}

public int modelIndex(int viewIndex) {

return getViewToModel()[viewIndex].modelIndex;

}

private int[] getModelToView() {

if (modelToView == null) {

int n = getViewToModel().length;

modelToView = new int[n];

for (int i = 0; i < n; i++) {

modelToView[modelIndex(i)] = i;

}

}

return modelToView;

}

// TableModel interface methods

public int getRowCount() {

return (tableModel == null) ? 0 : tableModel.getRowCount();

}

public int getColumnCount() {

return (tableModel == null) ? 0 : tableModel.getColumnCount();

}

public String getColumnName(int column) {

return tableModel.getColumnName(column);

}

public Class getColumnClass(int column) {

return tableModel.getColumnClass(column);

}

public boolean isCellEditable(int row, int column) {

return tableModel.isCellEditable(modelIndex(row), column);

}

public Object getValueAt(int row, int column) {

return tableModel.getValueAt(modelIndex(row), column);

}

public void setValueAt(Object aValue, int row, int column) {

tableModel.setValueAt(aValue, modelIndex(row), column);

}

// Helper classes

private class Row implements Comparable {

private int modelIndex;

public Row(int index) {

this.modelIndex = index;

}

public int compareTo(Object o) {

int row1 = modelIndex;

int row2 = ((Row) o).modelIndex;

for (Iterator it = sortingColumns.iterator(); it.hasNext();) {

Directive directive = (Directive) it.next();

int column = directive.column;

Object o1 = tableModel.getValueAt(row1, column);

Object o2 = tableModel.getValueAt(row2, column);

int comparison = 0;

// Define null less than everything, except null.

if (o1 == null && o2 == null) {

comparison = 0;

} else if (o1 == null) {

comparison = -1;

} else if (o2 == null) {

comparison = 1;

} else {

comparison = getComparator(column).compare(o1, o2);

}

if (comparison != 0) {

return directive.direction == DESCENDING ? -comparison : comparison;

}

}

return 0;

}

}

private class TableModelHandler implements TableModelListener {

public void tableChanged(TableModelEvent e) {

// If we're not sorting by anything, just pass the event along.

if (!isSorting()) {

clearSortingState();

fireTableChanged(e);

return;

}

// If the table structure has changed, cancel the sorting; the

// sorting columns may have been either moved or deleted from

// the model.

if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {

cancelSorting();

fireTableChanged(e);

return;

}

// We can map a cell event through to the view without widening

// when the following conditions apply:

//

// a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and,

// b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,

// c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and,

// d) a reverse lookup will not trigger a sort (modelToView != null)

//

// Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.

//

// The last check, for (modelToView != null) is to see if modelToView

// is already allocated. If we don't do this check; sorting can become

// a performance bottleneck for applications where cells

// change rapidly in different parts of the table. If cells

// change alternately in the sorting column and then outside of

// it this class can end up re-sorting on alternate cell updates -

// which can be a performance problem for large tables. The last

// clause avoids this problem.

int column = e.getColumn();

if (e.getFirstRow() == e.getLastRow()

&& column != TableModelEvent.ALL_COLUMNS

&& getSortingStatus(column) == NOT_SORTED

&& modelToView != null) {

int viewIndex = getModelToView()[e.getFirstRow()];

fireTableChanged(new TableModelEvent(TableSorter.this,

viewIndex, viewIndex,

column, e.getType()));

return;

}

// Something has happened to the data that may have invalidated the row order.

clearSortingState();

fireTableDataChanged();

return;

}

}

private class MouseHandler extends MouseAdapter {

public void mouseClicked(MouseEvent e) {

JTableHeader h = (JTableHeader) e.getSource();

TableColumnModel columnModel = h.getColumnModel();

int viewColumn = columnModel.getColumnIndexAtX(e.getX());

int column = columnModel.getColumn(viewColumn).getModelIndex();

if (column != -1) {

int status = getSortingStatus(column);

if (!e.isControlDown()) {

cancelSorting();

}

// Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or

// {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed.

status = status + (e.isShiftDown() ? -1 : 1);

status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1}

setSortingStatus(column, status);

}

}

}

private static class Arrow implements Icon {

private boolean descending;

private int size;

private int priority;

public Arrow(boolean descending, int size, int priority) {

this.descending = descending;

this.size = size;

this.priority = priority;

}

public void paintIcon(Component c, Graphics g, int x, int y) {

Color color = c == null ? Color.GRAY : c.getBackground();

// In a compound sort, make each succesive triangle 20%

// smaller than the previous one.

int dx = (int)(size/2*Math.pow(0.8, priority));

int dy = descending ? dx : -dx;

// Align icon (roughly) with font baseline.

y = y + 5*size/6 + (descending ? -dy : 0);

int shift = descending ? 1 : -1;

g.translate(x, y);

// Right diagonal.

g.setColor(color.darker());

g.drawLine(dx / 2, dy, 0, 0);

g.drawLine(dx / 2, dy + shift, 0, shift);

// Left diagonal.

g.setColor(color.brighter());

g.drawLine(dx / 2, dy, dx, 0);

g.drawLine(dx / 2, dy + shift, dx, shift);

// Horizontal line.

if (descending) {

g.setColor(color.darker().darker());

} else {

g.setColor(color.brighter().brighter());

}

g.drawLine(dx, 0, 0, 0);

g.setColor(color);

g.translate(-x, -y);

}

public int getIconWidth() {

return size;

}

public int getIconHeight() {

return size;

}

}

private class SortableHeaderRenderer implements TableCellRenderer {

private TableCellRenderer tableCellRenderer;

public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {

this.tableCellRenderer = tableCellRenderer;

}

public Component getTableCellRendererComponent(JTable table,

Object value,

boolean isSelected,

boolean hasFocus,

int row,

int column) {

Component c = tableCellRenderer.getTableCellRendererComponent(table,

value, isSelected, hasFocus, row, column);

if (c instanceof JLabel) {

JLabel l = (JLabel) c;

l.setHorizontalTextPosition(JLabel.LEFT);

int modelColumn = table.convertColumnIndexToModel(column);

l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize()));

}

return c;

}

}

private static class Directive {

private int column;

private int direction;

public Directive(int column, int direction) {

this.column = column;

this.direction = direction;

}

}

}

class TablePopupEditor extends DefaultCellEditor

implements TableCellEditor, ActionListener {

private PopupDialog popup;

private String currentText = "";

private JButton editorComponent;

String newline = "\n";

JTextArea output;

JScrollPane scrollPane;

JPanel contentPane;

public TablePopupEditor(String strHeading)

{

super(new JTextField());

setClickCountToStart(1);

// Use a JButton as the editor component

editorComponent = new JButton();

editorComponent.setBackground(Color.white);

editorComponent.setBorderPainted(false);

editorComponent.setContentAreaFilled( false );

// editorComponent.addActionListener( this );

// Set up the dialog where we do the actual editing

popup = new PopupDialog(strHeading);

createPopupMenu();

}

public void createPopupMenu() {

JMenuItem menuItem;

//Create the popup menu.

JPopupMenu contextMenu = new JPopupMenu();

menuItem = new JMenuItem(new DefaultEditorKit.CopyAction());

menuItem.setText("Copy");

menuItem.setMnemonic(KeyEvent.VK_C);

menuItem.addActionListener(this);

contextMenu.add(menuItem);

menuItem = new JMenuItem(new DefaultEditorKit.CutAction());

menuItem.setText("Cut");

menuItem.setMnemonic(KeyEvent.VK_T);

menuItem.addActionListener(this);

contextMenu.add(menuItem);

menuItem = new JMenuItem(new DefaultEditorKit.PasteAction());

menuItem.setText("Paste");

menuItem.setMnemonic(KeyEvent.VK_P);

menuItem.addActionListener(this);

contextMenu.add(menuItem);

//Add listener to the text area so the popup menu can come up.

MouseListener popupListener = new PopupListener(contextMenu);

editorComponent.addMouseListener(popupListener);

popup.addMouseListener(popupListener);

}

public Object getCellEditorValue()

{

return currentText;

}

public Component getTableCellEditorComponent(

JTable table, Object value, boolean isSelected, int row, int column)

{

SwingUtilities.invokeLater(new Runnable()

{

public void run()

{

popup.setText( currentText );

popup.setLocationRelativeTo( editorComponent );

popup.show();

fireEditingStopped();

}

});

currentText = value.toString();

editorComponent.setText( currentText );

return editorComponent;

}

/*

*When the editor button is clicked display the editing dialog

*/

public void actionPerformed(ActionEvent e)

{

popup.setText( currentText );

popup.setLocationRelativeTo( editorComponent );

popup.show();

// Since dialog is modal editing will only stop when the

// dialog is closed

fireEditingStopped();

}

// Returns just the class name -- no package info.

protected String getClassName(Object o) {

String classString = o.getClass().getName();

int dotIndex = classString.lastIndexOf(".");

return classString.substring(dotIndex+1);

}

/*

*Simple dialog containing the actual editing component

*/

class PopupDialog extends JDialog implements ActionListener

{

private JTextArea textArea;

public PopupDialog(String strHeading)

{

super((Frame)null, strHeading, true);

setDefaultLookAndFeelDecorated(false);

textArea = new JTextArea(7, 30);

textArea.setLineWrap( true );

textArea.setWrapStyleWord( true );

KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");

textArea.getInputMap().put(keyStroke, "none");

JScrollPane scrollPane = new JScrollPane( textArea );

getContentPane().add( scrollPane );

JButton cancel = new JButton("Cancel");

cancel.addActionListener( this );

JButton ok = new JButton("Ok");

ok.setPreferredSize( cancel.getPreferredSize() );

ok.addActionListener( this );

JPanel buttons = new JPanel();

buttons.add( ok );

buttons.add( cancel );

getContentPane().add(buttons, BorderLayout.SOUTH);

pack();

getRootPane().setDefaultButton( ok );

}

public void setText(String text) {

textArea.setText( text );

}

/*

*Save the changed text before hiding the popup

*/

public void actionPerformed(ActionEvent e)

{

if ("Ok".equals( e.getActionCommand() ) )

{

currentText = textArea.getText();

}

textArea.requestFocusInWindow();

setVisible( false );

}

}

}

class PopupListener extends MouseAdapter {

JPopupMenu popup;

PopupListener(JPopupMenu popupMenu) {

popup = popupMenu;

}

public void mousePressed(MouseEvent e) {

maybeShowPopup(e);

}

public void mouseReleased(MouseEvent e) {

maybeShowPopup(e);

}

private void maybeShowPopup(MouseEvent e) {

if (e.isPopupTrigger()) {

popup.show(e.getComponent(),

e.getX(), e.getY());

}

}

}

CathInfoa at 2007-7-9 23:10:36 > top of Java-index,Desktop,Core GUI APIs...
# 4

> Here is an SSCCE which might be of help:

This is not a SSCCE. A SSCCE includes only the relevant code to demonstrate the problem.

Why is a custom TableModel included? The DefaultTableModel is perfectly valid for storing the data in your example.

Why is a TableSorter included? Sorting has nothing to do with your problem description.

Why is the Arrow renderer included? How is it related to the problem.

The original code you copied is a SSCCE, since it contains only the required code to display the popup dialog when you click on a cell in the table. If your problem is about adding a popup listener to the text area then where in the code do you actually add your MouseLIstener to the text area? Get the fucntionality working in my original SSCCE and then incorporate the changes in to your real program. We are not going to read through 500 lines of code trying to figure out what you are doing.

camickra at 2007-7-9 23:10:36 > top of Java-index,Desktop,Core GUI APIs...
# 5

Sorry about that. I took out the TableSorter class, which indeed wasn't necesary. Now it's much shorter:

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.table.*;

import javax.swing.event.TableModelEvent;

import javax.swing.event.TableModelListener;

import javax.swing.text.DefaultEditorKit;

import java.util.*;

import java.io.*;

import java.util.List;

import java.awt.datatransfer.*;

import java.awt.dnd.*;

public class Demo extends JPanel

implements KeyListener, ActionListener, ItemListener {

public final int NUM_RECS = 4;

MyTableModel mainTable;

JTable table;

JPanel mainPanel, top;

static JFrame frame;

private MouseListener mouseListener;

public Demo() {

top = new JPanel();

table = new JTable(new MyTableModel());

// We want a horizontal scroller, not auto-resize as we shrink/grow the table

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

//Create the scroll pane and add the table to it.

JScrollPane scrollPane = new JScrollPane(table);

scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

//Add the scroll pane to this panel.

top.add(scrollPane);

setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

setBorder(BorderFactory.createEmptyBorder(5,5,5,5));

//Add all panels to the main panel.

add(top);

vLoadTableData();

}

public void actionPerformed(ActionEvent e) {

String strCommand = e.getActionCommand();

}

public void itemStateChanged(ItemEvent e) {

JMenuItem source = (JMenuItem)(e.getSource());

}

public void keyTyped(KeyEvent e) {}

public void keyPressed(KeyEvent e) {}

public void keyReleased(KeyEvent e) {}

protected void displayInfo(KeyEvent e, String s){}

public void vLoadTableData() {

TableColumn column = null;

column = table.getColumnModel().getColumn(0);

column.setPreferredWidth(50);

column = table.getColumnModel().getColumn(1);

column.setPreferredWidth(40);

column = table.getColumnModel().getColumn(2);

column.setCellEditor(new TablePopupEditor("Edit Description text"));

column.setPreferredWidth(350);

}

class MyTableModel extends AbstractTableModel {

private String[] columnNames = {"Publish", "ID", "Description"};

private Object[][] data;

MyTableModel() {

data = new Object[NUM_RECS][3];

// Sample data

data[0][0] = false;

data[0][1] = (int)101;

data[0][2] = "This is a book that is being sold at the present time. Buy yours today!";

data[1][0] = true;

data[1][1] = (int)102;

data[1][2] = "Gripping, thrilling, exciting. Tells how to grow tomatoes in your own backyard!";

data[2][0] = true;

data[2][1] = (int)103;

data[2][2] = "A story about a dog that attacks Kansas City.";

data[3][0] = false;

data[3][1] = (int)104;

data[3][2] = "Learn how to write an SSCCE that your Java forum will love.";

}

public int getColumnCount() {

return columnNames.length;

}

public int getRowCount() {

return data.length;

}

public String getColumnName(int col) {

return columnNames[col];

}

public Object getValueAt(int row, int col) {

return data[row][col];

}

public Class getColumnClass(int c) {

return getValueAt(0, c).getClass();

}

public boolean isCellEditable(int row, int col) {

return true;

}

public void setValueAt(Object value, int row, int col) {

data[row][col] = value;

fireTableCellUpdated(row, col);

}

}

private static void createAndShowGUI() {

JFrame.setDefaultLookAndFeelDecorated(false);

frame = new JFrame("Test of Product database");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.

Demo newContentPane = new Demo();

newContentPane.setOpaque(true);

frame.setContentPane(newContentPane);

frame.pack();

frame.setVisible(true);

}

public static void main(String[] args) {

//Schedule a job for the event-dispatching thread:

//creating and showing this application's GUI.

javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGUI();

}

});

}

}

class TablePopupEditor extends DefaultCellEditor

implements TableCellEditor, ActionListener {

private PopupDialog popup;

private String currentText = "";

private JButton editorComponent;

String newline = "\n";

JTextArea output;

JScrollPane scrollPane;

JPanel contentPane;

public TablePopupEditor(String strHeading)

{

super(new JTextField());

setClickCountToStart(1);

// Use a JButton as the editor component

editorComponent = new JButton();

editorComponent.setBackground(Color.white);

editorComponent.setBorderPainted(false);

editorComponent.setContentAreaFilled( false );

// editorComponent.addActionListener( this );

// Set up the dialog where we do the actual editing

popup = new PopupDialog(strHeading);

createPopupMenu();

}

public void createPopupMenu() {

JMenuItem menuItem;

//Create the popup menu.

JPopupMenu contextMenu = new JPopupMenu();

menuItem = new JMenuItem(new DefaultEditorKit.CopyAction());

menuItem.setText("Copy");

menuItem.setMnemonic(KeyEvent.VK_C);

menuItem.addActionListener(this);

contextMenu.add(menuItem);

menuItem = new JMenuItem(new DefaultEditorKit.CutAction());

menuItem.setText("Cut");

menuItem.setMnemonic(KeyEvent.VK_T);

menuItem.addActionListener(this);

contextMenu.add(menuItem);

menuItem = new JMenuItem(new DefaultEditorKit.PasteAction());

menuItem.setText("Paste");

menuItem.setMnemonic(KeyEvent.VK_P);

menuItem.addActionListener(this);

contextMenu.add(menuItem);

//Add listener to the text area so the popup menu can come up.

MouseListener popupListener = new PopupListener(contextMenu);

editorComponent.addMouseListener(popupListener);

popup.addMouseListener(popupListener);

}

public Object getCellEditorValue()

{

return currentText;

}

public Component getTableCellEditorComponent(

JTable table, Object value, boolean isSelected, int row, int column)

{

SwingUtilities.invokeLater(new Runnable()

{

public void run()

{

popup.setText( currentText );

popup.setLocationRelativeTo( editorComponent );

popup.show();

fireEditingStopped();

}

});

currentText = value.toString();

editorComponent.setText( currentText );

return editorComponent;

}

/*

*When the editor button is clicked display the editing dialog

*/

public void actionPerformed(ActionEvent e)

{

popup.setText( currentText );

popup.setLocationRelativeTo( editorComponent );

popup.show();

// Since dialog is modal editing will only stop when the

// dialog is closed

fireEditingStopped();

}

// Returns just the class name -- no package info.

protected String getClassName(Object o) {

String classString = o.getClass().getName();

int dotIndex = classString.lastIndexOf(".");

return classString.substring(dotIndex+1);

}

/*

*Simple dialog containing the actual editing component

*/

class PopupDialog extends JDialog implements ActionListener

{

private JTextArea textArea;

public PopupDialog(String strHeading)

{

super((Frame)null, strHeading, true);

setDefaultLookAndFeelDecorated(false);

textArea = new JTextArea(7, 30);

textArea.setLineWrap( true );

textArea.setWrapStyleWord( true );

KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");

textArea.getInputMap().put(keyStroke, "none");

JScrollPane scrollPane = new JScrollPane( textArea );

getContentPane().add( scrollPane );

JButton cancel = new JButton("Cancel");

cancel.addActionListener( this );

JButton ok = new JButton("Ok");

ok.setPreferredSize( cancel.getPreferredSize() );

ok.addActionListener( this );

JPanel buttons = new JPanel();

buttons.add( ok );

buttons.add( cancel );

getContentPane().add(buttons, BorderLayout.SOUTH);

pack();

getRootPane().setDefaultButton( ok );

}

public void setText(String text) {

textArea.setText( text );

}

/*

*Save the changed text before hiding the popup

*/

public void actionPerformed(ActionEvent e)

{

if ("Ok".equals( e.getActionCommand() ) )

{

currentText = textArea.getText();

}

textArea.requestFocusInWindow();

setVisible( false );

}

}

}

class PopupListener extends MouseAdapter {

JPopupMenu popup;

PopupListener(JPopupMenu popupMenu) {

popup = popupMenu;

}

public void mousePressed(MouseEvent e) {

maybeShowPopup(e);

}

public void mouseReleased(MouseEvent e) {

maybeShowPopup(e);

}

private void maybeShowPopup(MouseEvent e) {

if (e.isPopupTrigger()) {

popup.show(e.getComponent(),

e.getX(), e.getY());

}

}

}

CathInfoa at 2007-7-9 23:10:36 > top of Java-index,Desktop,Core GUI APIs...
# 6
I gave you a suggestion. Where in your code did you implement my suggestion?
camickra at 2007-7-9 23:10:36 > top of Java-index,Desktop,Core GUI APIs...
# 7

I actually tried that -- but it brought up a pop-up window in the middle of the screen, instead of centered on the table cell.

Here is where I attach the MouseListener:

public void createPopupMenu() {

JMenuItem menuItem;

//Create the popup menu.

JPopupMenu contextMenu = new JPopupMenu();

menuItem = new JMenuItem(new DefaultEditorKit.CopyAction());

menuItem.setText("Copy");

menuItem.setMnemonic(KeyEvent.VK_C);

menuItem.addActionListener(this);

contextMenu.add(menuItem);

menuItem = new JMenuItem(new DefaultEditorKit.CutAction());

menuItem.setText("Cut");

menuItem.setMnemonic(KeyEvent.VK_T);

menuItem.addActionListener(this);

contextMenu.add(menuItem);

menuItem = new JMenuItem(new DefaultEditorKit.PasteAction());

menuItem.setText("Paste");

menuItem.setMnemonic(KeyEvent.VK_P);

menuItem.addActionListener(this);

contextMenu.add(menuItem);

//Add listener to the text area so the popup menu can come up.

MouseListener popupListener = new PopupListener(contextMenu);

editorComponent.addMouseListener(popupListener);

popup.addMouseListener(popupListener);

}

CathInfoa at 2007-7-9 23:10:36 > top of Java-index,Desktop,Core GUI APIs...
# 8
Maybe this is what you are trying to do: http://forum.java.sun.com/thread.jspa?forumID=57&threadID=625217
camickra at 2007-7-9 23:10:36 > top of Java-index,Desktop,Core GUI APIs...