2015-06-15 4 views
10

Недавно я начал изучать API JavaFX после того, как я уже знаком с Swing.Почему JavaFX не включает средство отмены?

Я заметил, что даже много классов были хорошо реализованы в AWT и Swing, они были эффективно реализованы в JavaFX. Это включает в себя:

javafx.scene.paint.Color 
javafx.event.ActionEvent 

против

java.awt.Color 
java.awt.event.ActionEvent 

и многое другое, даже если он мог бы легко требовать, чтобы использовать их . Я предполагаю, что это:

  • Отключить JavaFX от возможных библиотек (так что новые разработчики не должны даже знать об их существовании ..., ОК).
  • Плечо Java 8 лямбда-выражения.
  • Использовать генераторы и типы перечислений Java 5.
  • Дизайн с FXML в виду.
  • Bindings ... версия волшебства JavaFX.

Если мои предположения верны, то почему они не включают в себя новую реализацию:

javax.swing.undo 

пакет?

Хотя я понимаю, что отмена не имеет никакого отношения к пользовательскому интерфейсу, поэтому она не имеет ничего общего с Swing. Если по какой-либо причине они решили включить его в пакет javax.swing, они могли бы включить его в JavaFX.

+0

Это интересный вопрос. Многие пользователи юзабилити утверждают, что undo/redo имеет большое отношение к пользовательским интерфейсам, поскольку пользователю значительно удобнее исследовать пользовательский интерфейс, зная, что он может отменить любую функцию, которая оказывается нежелательной. И чтение документов для javax.swing.undo дает понять, что реализация его сама по себе далека от тривиальной. – VGR

+3

Возможно, вы захотите спросить [список рассылки openjfx-dev] (http://mail.openjdk.java.net/mailman/listinfo/openjfx-dev). [UndoFX] (https://github.com/TomasMikula/UndoFX) является альтернативной альтернативой для сторонних разработчиков с открытым исходным кодом, разработанной для использования с JavaFX. UndoFX используется в [RichTextFX] (https://github.com/TomasMikula/RichTextFX), текстовом редакторе на основе JavaFX. – jewelsea

+0

@jewelsea - почему вы не ответили? – Deian

ответ

5

Почему они «забыли» реализовать это, это хороший вопрос. Я бы сказал, что JavaFX все еще находится в разработке (это должно сказать все). Однако мне это было нужно очень давно, и я применил свой собственный подход, используя Command Pattern. Как показано ниже, это не так много усилий и очень просто.

Сначала вам нужно создать интерфейс под названием Команда, чтобы выполнить некоторые операции в вашем приложении.

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(); 
} 

Далее вам понадобится некоторый класс под названием История, чтобы сохранить выполненные команды и отменить их.

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(); 
    } 
} 

Как вы можете видеть, самое лучшее, что История класс является Singleton. Таким образом, вы можете получить доступ к классу всюду.

Inherit from Команда интерфейс для реализации новой команды. Используйте несколько кнопок или аналогичные элементы 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 и соответствующий метод в История класс и Команда интерфейс.

Для получения дополнительной информации о шаблоне команды, посмотрите here.

Счастливое кодирование!

+0

Хорошее решение, но технически 'javax.swing.undo' по-прежнему применимо к JavaFX. Я бы предпочел придерживаться этого, поскольку он более надежный. Тем не менее, я ожидаю, что специальная реализация для JavaFX - как UndoFX - в официальном выпуске. – Mordechai

+0

Да, это похоже на приятное решение ... но почему же вы не просто использовали существующий пакет 'swing.undo'? Пакеты Swing все еще связаны с Java, так разве это не классический случай повторного создания колеса? Или у вас есть другое оправдание? –

 Смежные вопросы

  • Нет связанных вопросов^_^