Циклический импорт завершается, но вам нужно быть осторожным, чтобы не использовать циклически импортированные модули во время инициализации модуля.
Рассмотрим следующие файлы:
a.py:
print "a in"
import sys
print "b imported: %s" % ("b" in sys.modules, )
import b
print "a out"
b.py:
print "b in"
import a
print "b out"
x = 3
Если вы выполните a.py, вы получите следующее:
$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
b out
a out
Во втором импортировании b.py (во втором a in
) интерпретатор Python не импортирует b
еще раз, потому что он уже существует в модуле dict.
Если вы попытаетесь получить доступ к b.x
из a
во время инициализации модуля вы получите AttributeError
.
Добавьте следующую строку к a.py
:
print b.x
Затем на выходе:
$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
Traceback (most recent call last):
File "a.py", line 4, in <module>
import b
File "/home/shlomme/tmp/x/b.py", line 2, in <module>
import a
File "/home/shlomme/tmp/x/a.py", line 7, in <module>
print b.x
AttributeError: 'module' object has no attribute 'x'
Это связано с тем, что модули выполняются при импорте и в момент доступа к b.x
линия x = 3
еще не выполнена, что произойдет только после b out
.
Я решил эту проблему, и логика, лежащая в основе этого решения: -
public class UndoRedo {
private SpreadsheetCell cell;
private String oldValue;
private String newValue;
public UndoRedo(SpreadsheetCell cell, String oldValue, String newValue) {
this.cell = cell;
this.oldValue = oldValue;
this.newValue = newValue;
}
public SpreadsheetCell getCell() {
return cell;
}
public void setCell(SpreadsheetCell cell) {
this.cell = cell;
}
public String getOldValue() {
return oldValue;
}
public void setOldValue(String oldValue) {
this.oldValue = oldValue;
}
public String getNewValue() {
return newValue;
}
public void setNewValue(String newValue) {
this.newValue = newValue;
}
}
добавить событие в SpreadSheet для добавления объекта в список любой операции изменения в ячейке.
mGridBase.addEventHandler(GridChange.GRID_CHANGE_EVENT, (GridChange e) -> {
isCellEdited = true;
SpreadsheetCell cell = mGridBase.getRows().get(e.getRow()).get(e.getColumn());
String oldValue = lastValue;
UndoRedo undoRedo = new UndoRedo(cell, oldValue, cell.getText());
undoRedoList.add(undoRedo);
});
Теперь добавьте событие Key в
Ctrl + Z
blockquote>для отмены последних изменений
if (KeyCode.Z == event.getCode() && event.isControlDown()) { if (!undoRedoList.isEmpty()) { UndoRedo undoRedo = undoRedoList.remove(undoRedoList.size() - 1); undoRedo.getCell().setItem(undoRedo.getOldValue()); mSpreadsheet.getSelectionModel().clearAndSelect(undoRedo.getCell().getRow(), mSpreadsheet.getColumns().get(undoRedo.getCell().getColumn())); } }
И теперь оно работает отлично и надежно тогда
Grid grid = ...; Stack<GridChange> undoStack = ...; grid.addEventHandler(GridChange.GRID_CHANGE_EVENT, new EventHandler<GridChange>() { public void handle(GridChange change) { undoStack.push(change); } });