Как использовать UndoRedoSupport или отменить поддержку glazedlist в JTable?
Я создал JTable с GlazedList eventList. Я искал API, но я не мог понять, как добавить возможность отмены / повторения в эту таблицу. Я нашел в API следующие классы:
UndoRedoSupport undoRedoSupport = new UndoRedoSupport<"what here?">("argument?");
UndoSupport undoSupport = new UndoSupport<"what to write here?">("argument?");
Кто-нибудь знает, как его использовать?
private void createComponents() {
EventList<Dien> eventList = new BasicEventList<Dien>();
actionList = GenericsUtil.makeList();
table = new WebTable();
searchField = new WebTextField(60);
String[] headers = new String[]{"Code", "Name", "Number"};
String[] properties = new String[]{"Code", "Name", "Number"};
TextFilterator<Dien> dienFilterator = new TextFilterator<Dien>() {
public void getFilterStrings(List baseList, Dien dien) {
baseList.add(dien.getCode());
baseList.add(dien.getName());
baseList.add(dien.getNumber());
}
};
MatcherEditor<Dien> textMatcherEditor = new TextComponentMatcherEditor<Dien>(searchField, dienFilterator);
eventList = toolModel.getDiens();
FilterList<Dien> filterList = new FilterList<Dien>(eventList, textMatcherEditor);
TableFormat tableFormat = GlazedLists.tableFormat(properties, headers, new boolean[]{true,true,true});
model = new EventTableModel<Dien>(filterList, tableFormat);
model.addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
if(e.getType()==TableModelEvent.UPDATE){
if(!panel.isPendingChanges())
panel.setPendingChange(true);
}
}
});
selectionModel = new EventSelectionModel<Dien>(filterList);
table.setSelectionModel(selectionModel);
table.setModel(model);
}
1 ответ
Классы Undo/Redo, встроенные в GlazedLists, не поставляются с открытым конструктором; вместо этого вы устанавливаете поддержку для определенного списка событий через 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) с тем же объектом в этом индексе, создает ListEvent, у которого нет соответствующего объекта UndoRedoSupport.Edit. Эти ListEvents игнорируются, потому что им не хватает информации, чтобы отменить или повторить изменение.
В общем, UndoRedoSupport имеет смысл только для использования с BasicEventList или тривиальной оболочкой вокруг BasicEventList, которая не влияет на порядок или тип элементов, таких как ObservableElementList. Расширенные преобразования, такие как SortedList или FilterList, не будут работать должным образом с этим классом UndoRedoSupport, так как их содержимое контролируется информацией вне себя (Comparators and Matchers).