GlazedLists 内置的 Undo/Redo 类不带有公共构造函数;相反,您通过静态方法安装对特定事件列表的支持。UndoRedoSupport.install()
当然,如果您使用的是 Swing,那么利用 Swing 的UndoManager
类是有意义的,而 GlazedLists 为其UndoSupport
类提供了一个简单的包装器。同样,这只是用它的install()
方法初始化。
我创建了一个简单的 Swing 示例应用程序作为示例来说明如何使用这些类。在我的示例中,我使用了一个简单EventList
的字符串和一个 JList。但它同样适用于任何 GlazedList 支持的组件——UndoRedoSupport
适用于EventList
自身而不是 Swing 组件。
import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.swing.EventListModel;
import ca.odell.glazedlists.swing.UndoSupport;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.undo.UndoManager;
public class GlazedListsUndoSample {
private JFrame mainFrame;
private JButton addItemButton;
private JButton undoButton;
private JButton redoButton;
private UndoManager undoManager;
private EventList<String> eventList = new BasicEventList<String>();
public GlazedListsUndoSample() {
//populateAvailableBooks();
createGui();
mainFrame.setVisible(true);
}
private void updateButtons() {
//addBookButton.setEnabled(!books.isEmpty());
undoButton.setEnabled(undoManager.canUndo());
redoButton.setEnabled(undoManager.canRedo());
}
private void createGui() {
undoManager = new UndoManager();
UndoSupport.install(undoManager, eventList);
mainFrame = new JFrame("GlazedLists Undo Example");
mainFrame.setSize(600, 400);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
EventListModel model = new EventListModel(eventList);
JList list = new JList(model);
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(new JScrollPane(list), BorderLayout.CENTER);
JPanel addBookPanel = new JPanel(new BorderLayout());
addBookPanel.add(new JLabel("Item"), BorderLayout.WEST);
final JTextField titleTextField = new JTextField(50);
addBookPanel.add(titleTextField, BorderLayout.CENTER);
addItemButton = new JButton("Add Item");
addItemButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
eventList.add(titleTextField.getText());
updateButtons();
}
});
addBookPanel.add(addItemButton, BorderLayout.EAST);
JPanel buttonPanel = new JPanel();
undoButton = new JButton("Undo");
undoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (undoManager.canUndo()) {
undoManager.undo();
}
updateButtons();
}
});
redoButton = new JButton("Redo");
redoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (undoManager.canRedo()) {
undoManager.redo();
}
updateButtons();
}
});
updateButtons();
buttonPanel.add(undoButton);
buttonPanel.add(redoButton);
mainPanel.add(addBookPanel, BorderLayout.NORTH);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
mainFrame.getContentPane().setLayout(new BorderLayout());
mainFrame.getContentPane().add(mainPanel, BorderLayout.CENTER);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new GlazedListsUndoSample();
}
});
}
}
值得注意的是,文档确实强烈暗示了它的功能限制:
并非 ListEvent 中描述的每个更改都会导致可撤消的编辑。具体来说,列表元素 IN PLACE 的突变不会产生可撤消的编辑。例如,观察元素变化的 ObservableElementList 或在该索引处使用相同对象调用 List.set(int, E) 会产生没有对应 UndoRedoSupport.Edit 对象的 ListEvent。这些 ListEvent 被忽略,因为它们缺乏足够的信息来撤消或重做更改。
一般来说,UndoRedoSupport 仅适用于 BasicEventList 或 BasicEventList 周围的普通包装器,它不会影响元素的顺序或类型,例如 ObservableElementList。高级转换,例如 SortedList 或 FilterList 将无法按预期使用此 UndoRedoSupport 类,因为它们的内容由它们自身之外的信息(比较器和匹配器)控制。