import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.text.TabExpander;
import javax.swing.undo.*;
public class UndoTable
{
public static void main(String[] args)
{
Object data[][] = {
{"AMZN", "Amazon", 41.28, "BUY"},
{"EBAY", "eBay", 41.57, "BUY"},
{"GOOG", "Google", 388.33, "SELL"},
{"MSFT", "Microsoft", 26.56, "SELL"},
{"NOK", "Nokia Corp", 17.13, "BUY"},
{"ORCL", "Oracle Corp.", 12.52, "BUY"},
{"SUNW", "Sun Microsystems", 3.86, "BUY"},
{"TWX", "Time Warner", 17.66, "SELL"},
{"VOD", "Vodafone Group", 26.02, "SELL"},
{"YHOO", "Yahoo!", 37.69, "BUY"}
};
String columns[] = {"Symbol", "Name", "Price", "Guidance"};
final JvUndoableTableModel tableModel = new JvUndoableTableModel(data, columns);
final JTable table = new JTable(tableModel);
JScrollPane pane = new JScrollPane(table);
JvUndoManager undoManager = new JvUndoManager();
tableModel.addUndoableEditListener(undoManager);
JMenu editMenu = new JMenu("Edit");
Action addrowaction = new AbstractAction("Add Row") {
private static final long serialVersionUID = 1433684360133156145L;
public void actionPerformed(ActionEvent e) {
tableModel.insertRow(table.getRowCount(), new Object[]{"YHOO", "Yahoo!", 37.69, "BUY"});
}
};
editMenu.add(undoManager.getUndoAction());
//editMenu.add(undoManager.getRedoAction());
JMenuBar menuBar = new JMenuBar();
menuBar.add(editMenu);
editMenu.add(addrowaction);
JFrame frame = new JFrame("Undoable JTable");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(menuBar);
frame.add(pane, BorderLayout.CENTER);
frame.setSize(300, 150);
frame.setLocation(200, 300);
frame.setVisible(true);
}
}
class JvUndoableTableModel extends DefaultTableModel
{
public JvUndoableTableModel(Object[][] data, Object[] columnNames)
{
super(data, columnNames);
}
public Class getColumnClass(int column)
{
if (column >= 0 && column < getColumnCount())
return getValueAt(0, column).getClass();
return Object.class;
}
@Override
public void setValueAt(Object value, int row, int column)
{
setValueAt(value, row, column, true);
}
public void setValueAt(Object value, int row, int column, boolean undoable)
{
UndoableEditListener listeners[] = getListeners(UndoableEditListener.class);
if (undoable == false || listeners == null)
{
super.setValueAt(value, row, column);
return;
}
Object oldValue = getValueAt(row, column);
super.setValueAt(value, row, column);
JvCellEdit cellEdit = new JvCellEdit(this, oldValue, value, row, column);
UndoableEditEvent editEvent = new UndoableEditEvent(this, cellEdit);
for (UndoableEditListener listener : listeners)
listener.undoableEditHappened(editEvent);
}
//adding new cell to the table
public void insertRow(int row, Object[] rowData){
insertRow(row, rowData, true);
}
public void insertRow(int row,
Object[] rowData,boolean undoable){
UndoableEditListener listeners[] = getListeners(UndoableEditListener.class);
if (undoable == false || listeners == null)
{
super.insertRow(row, rowData);
return;
}
super.insertRow(row, rowData);
JvCellNew cellNew = new JvCellNew(this, rowData, row);
UndoableEditEvent editEvent = new UndoableEditEvent(this, cellNew);
for (UndoableEditListener listener : listeners)
listener.undoableEditHappened(editEvent);
}
//removing row from the table
public void removeRow(int row){
removeRow(row, true);
}
public void removeRow(int row, boolean undoable){
UndoableEditListener listeners[] = getListeners(UndoableEditListener.class);
if (undoable == false || listeners == null)
{
super.removeRow(row);
return;
}
super.removeRow(row);
JvCellNew cellNew = new JvCellNew(this, row);
UndoableEditEvent editEvent = new UndoableEditEvent(this, cellNew);
for (UndoableEditListener listener : listeners)
listener.undoableEditHappened(editEvent);
}
public void addUndoableEditListener(UndoableEditListener listener)
{
listenerList.add(UndoableEditListener.class, listener);
}
}
class JvCellEdit extends AbstractUndoableEdit
{
protected JvUndoableTableModel tableModel;
protected Object oldValue;
protected Object newValue;
protected int row;
protected int column;
public JvCellEdit(JvUndoableTableModel tableModel, Object oldValue, Object newValue, int row, int column)
{
this.tableModel = tableModel;
this.oldValue = oldValue;
this.newValue = newValue;
this.row = row;
this.column = column;
}
@Override
public String getPresentationName()
{
return "Cell Edit";
}
@Override
public void undo() throws CannotUndoException
{
super.undo();
tableModel.setValueAt(oldValue, row, column, false);
}
}
class JvCellNew extends AbstractUndoableEdit
{
/**
*
*/
private static final long serialVersionUID = 1L;
protected JvUndoableTableModel tableModel;
protected Object[] rowData;
protected int row;
public JvCellNew(JvUndoableTableModel tableModel, Object[] rowData, int row)
{
this.tableModel = tableModel;
this.rowData = rowData;
this.row = row;
}
public JvCellNew(JvUndoableTableModel tableModel, int row)
{
this.tableModel = tableModel;
this.row = row;
}
@Override
public String getPresentationName()
{
return "Cell New";
}
public void undo() throws CannotUndoException
{
super.undo();
tableModel.removeRow(row);
}
}
class JvUndoManager extends UndoManager
{
protected Action undoAction;
// protected Action redoAction;
public JvUndoManager()
{
this.undoAction = new JvUndoAction(this);
synchronizeActions(); // to set initial names
}
public Action getUndoAction()
{
return undoAction;
}
@Override
public boolean addEdit(UndoableEdit anEdit)
{
try
{
return super.addEdit(anEdit);
}
finally
{
synchronizeActions();
}
}
@Override
protected void undoTo(UndoableEdit edit) throws CannotUndoException
{
try
{
super.undoTo(edit);
}
finally
{
synchronizeActions();
}
}
protected void synchronizeActions()
{
undoAction.setEnabled(canUndo());
undoAction.putValue(Action.NAME, getUndoPresentationName());
}
}
class JvUndoAction extends AbstractAction
{
protected final UndoManager manager;
public JvUndoAction(UndoManager manager)
{
this.manager = manager;
}
public void actionPerformed(ActionEvent e)
{
try
{
manager.undo();
}
catch (CannotUndoException ex)
{
ex.printStackTrace();
}
}
}
问题似乎与这样一个事实有关:撤消的执行导致一个动作再次被存储为可撤消的动作。(由于移除一行会创建一个新的jvcellnew
,根据名称,它可能表明添加了一个新行,这一点特别令人困惑)
可以通过指定已撤消的操作不能再次撤消来解决“症状”:
class JvCellNew
{
....
public void undo() throws CannotUndoException
{
super.undo();
// Pass in "false" as the second argument here, to indicate
// that this row removal should NOT cause an undoable edit
tableModel.removeRow(row, false);
}
}
在打印一些调试信息时,可以更容易地找到类似的内容,例如
class JvCellNew extends AbstractUndoableEdit
{
....
@Override
public String getPresentationName()
{
return "Cell New "+row; // Print the row number
}
// Provide a useful toString implementation
@Override
public String toString()
{
return getPresentationName();
}
}
class JvUndoManager extends UndoManager
{
....
@Override
public boolean addEdit(UndoableEdit anEdit)
{
try
{
boolean b = super.addEdit(anEdit);
// Print the current state of this manager
System.out.println("After adding "+anEdit);
for (UndoableEdit e : this.edits)
{
System.out.println(e);
}
return b;
}
finally
{
synchronizeActions();
}
}
@Override
protected void undoTo(UndoableEdit edit) throws CannotUndoException
{
try
{
super.undoTo(edit);
// Print the current state of this manager
System.out.println("After undo to "+edit);
for (UndoableEdit e : this.edits)
{
System.out.println(e);
}
}
finally
{
synchronizeActions();
}
}
}
我对这个很陌生,所以也许有什么我错过了,或者只是不知道。
我已经学会了如何在帧中显示JTable,但我不知道如何实际更改数据。我已经读了很多关于这个主题的教程,但似乎没有什么是合适的。你能回答一些关于下面代码的问题吗? 1)在actionListener中,我调用tab.getModel()。getValueAt(1,1)和tab.getValueAt(1,1)。我得到相同的数据,“佩蒂”如果“getModel()”提供相同的数据,它是必要的吗? 我认为
我有一个Jtable,我在其中添加了这样的JComobox。 我像这样添加了一个jtable的鼠标事件。 但是当我点击我添加Jcombobox的单元格时,它并没有给出该行和列的放置。我仍然在组合框点击事件中调用了表的点击事件,但它给出了所有时间行0,甚至列0在这里的屏幕截图。 那么,我如何解决它,这样我就可以有行和列?
问题内容: 我想在第1列的JTable(3,3)内添加JComboBox。但是在第1列中,每一行都有其自己的ComboBox元素集。当我尝试使用 每行都设置为同一组ComboBox值。但是我希望每一行ComboBox都有不同的项目。 问题答案: java2s.com上的示例看起来可以正常工作,然后再进行示例(例如,我将JComboBoxes编码为快速示例,并为今天的Swing添加/更改) 只需添加
问题内容: 我想做的事: 我想列出数据库的一些记录。此列表应显示在 JFrame弹出窗口中。 描述: 我有3节课: Main.java(运行程序) PeopleTableModel.java(保存数据,扩展AbstractTableModel) PeopleTable.java(保存逻辑,扩展JTable) 将JFrame设置为 可见时,为什么会出现ArrayIndexOutOfBoundsExc
我创建了一个表单,其中添加了一个,它有3列。第二列和第三列有编辑器。 我希望当我们选择第二列组合框的第一项时,第三列组合框的第一个组合框也应该被选择,反之亦然。 我该怎么做?