GlazedLists に組み込まれている Undo/Redo クラスには、パブリック コンストラクターが付属していません。代わりに、静的メソッドを介して特定のイベント リストにサポートをインストールします。UndoRedoSupport.install()
もちろん、Swing を使用している場合は、Swing のUndoManager
クラスを活用するのが理にかなっており、GlazedLists はそのUndoSupport
クラスに単純なラッパーを提供します。繰り返しますが、これはそのinstall()
メソッドで単純に初期化されます。
これらのクラスの使用方法を説明するための例として、単純な Swing サンプル アプリケーションを作成しました。私の例では、単純なEventList
文字列と JList を使用しています。しかし、GlazedList に裏打ちされたコンポーネントにも同じことが適用されます。つまり、Swing コンポーネントではなく、それ自体にUndoRedoSupport
適用されます。EventList
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 を生成します。これらの ListEvents は、変更を元に戻したりやり直したりするのに十分な情報がないため、無視されます。
一般に、UndoRedoSupport は、ObservableElementList などの要素の順序や型に影響を与えない BasicEventList または BasicEventList の簡単なラッパーで使用する場合にのみ意味があります。SortedList や FilterList などの高度な変換は、この UndoRedoSupport クラスでは期待どおりに機能しません。これは、その内容が外部の情報 (コンパレーターとマッチャー) によって制御されるためです。