Ответ 1
Почему они "забыли" реализовать это, это хороший вопрос. Я бы сказал, что JavaFX все еще находится в разработке (это должно сказать все). Однако мне это было нужно очень давно, и я применил свой собственный подход, используя Command Pattern. Как показано ниже, это не так много усилий и очень просто.
Сначала вам нужно создать интерфейс под названием "Command", чтобы выполнить некоторые операции в вашем приложении.
public interface Command {
/**
* This is called to execute the command from implementing class.
*/
public abstract void execute();
/**
* This is called to undo last command.
*/
public abstract void undo();
}
Далее вам понадобится какой-то класс с именем History, чтобы сохранить выполненные команды и отменить их.
public final class History {
// ...
private static History instance = null;
private final Stack<Command> undoStack = new Stack<Command>();
// ...
public void execute(final Command cmd) {
undoStack.push(cmd);
cmd.execute();
}
public void undo() {
if (!undoStack.isEmpty()) {
Command cmd = undoStack.pop();
cmd.undo();
} else {
System.out.println("Nothing to undo.");
}
}
public static History getInstance() {
if (History.instance == null) {
synchronized (History.class) {
if (History.instance == null) {
History.instance = new History();
}
}
}
return History.instance;
}
private History() { }
}
В своем FXML вы создаете кнопку для своего графического интерфейса, которая должна вызывать отмену функции вашего приложения. В FXML создайте кнопку, например следующую:
<Button fx:id="btnUndo" font="$x2" onAction="#onUndo" prefWidth="75.0"
text="Undo" textAlignment="CENTER" underline="false">
<tooltip>
<Tooltip text="Undo last command" textAlignment="JUSTIFY" />
</tooltip>
<HBox.margin>
<Insets left="5.0" right="5.0" fx:id="x1" />
</HBox.margin>
</Button>
В вашем классе контроллера вы ссылаетесь на кнопку с вашего FXML.
public class Controller {
// ...
@FXML private Button btnUndo;
// ...
@FXML
public void onUndo(ActionEvent event)
{
History.getInstance().undo();
}
}
Как вы можете видеть, лучше всего, что класс History - это Singleton. Таким образом, вы можете получить доступ к классу везде.
Наследовать из интерфейса Command для реализации новой команды. Используйте некоторые кнопки или аналогичные элементы GUI для новых функций и выполните пользовательскую команду, используя свою историю.
// You can give arguments to command constructor if you like
Command someCmd = new SomeCommand();
History.getInstance().execute(someCmd); // Saved to history; now you're able to undo using button
При таком подходе вы сможете отменить свою операцию. Также возможно реализовать некоторые функции повтора. Для этого просто добавьте кнопку повтора в FXML и соответствующий метод в классе History и Command.
Для получения дополнительной информации о шаблоне команд посмотрите здесь.
Счастливое кодирование!