2015-06-15 26 views
10

Kısa bir süre önce Swing'te deneyimledikten sonra JavaFX API'sini öğrenmeye başladım. sınıfların bile çok zaten iyi AWT ve Swing yerine getirildiğinden emin fark ettim Neden JavaFX bir geri alma özelliği içermiyor

, onlar etkili JavaFX yeniden uygulanmıştır. Bunlar:

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

vs

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

ve çok daha fazlası, kolayca bunlarıkullanmayı gerektiren olabilirdi rağmen. Bunun farz edelim ki, bu:

  • JavaFX'i diğer kütüphanelerden mümkün olan en fazla çözme (yeni geliştiricilerin varlığından haberdar olmamalıdır ..., tamam).
  • Java 8 lambda ifadelerinden yararlanın.
  • Java 5 jenerik ve enum türlerinden faydalanın.
  • FXML ile tasarlayın.
  • Bağlantılar ... JavaFX'in sihir sürümü.

benim varsayımlar doğruysa, bunlar yeni bir uygulama içermiyordu neden:

javax.swing.undo 

pakette? geri

anlıyorum rağmen çok Swing ile ilgisi yoktur, kullanıcı arayüzü ile yapmak gerçekten ilgisi yoktur, bu yüzden. Herhangi bir nedenle, javax.swing paketine dahil etmeye karar verdiyse, bunu JavaFX'e dahil edebilirler.

+0

Bu ilginç bir soru. Kullanılabilirlikle ilgili bir çok kişi, geri alma/yineleme işleminin kullanıcı arayüzleri ile büyük bir ilgisi olduğunu tartışabilirdi, çünkü bir kullanıcı bir UI'yi araştırmak için, istenmeyen bir duruma dönüşen herhangi bir işlevi tersine çevirebileceğini bilerek daha rahattır. Ve javax.swing.undo için dokümanlar okumak, kendini uygulamanın önemsiz olmaktan uzak olduğunu açıkça ortaya koymaktadır. – VGR

+3

[openjfx-dev postalama listesi] 'ni (http://mail.openjdk.java.net/mailman/listinfo/openjfx-dev) isteyebilirsiniz. [UndoFX] (https://github.com/TomasMikula/UndoFX), JavaFX ile kullanılmak üzere tasarlanmış üçüncü parti açık kaynak kodlu bir alternatiftir. UndoFX, [RichTextFX] (https://github.com/TomasMikula/RichTextFX), JavaFX tabanlı bir metin editörü olarak kullanılır. – jewelsea

+0

@jewelsea - neden cevap yazmıyorsun ?! – Deian

cevap

5

Bunu neden "unutmuş" lar, iyi bir soru. Tartışacağım, JavaFX'in hala geliştirilme aşamasında olduğunu (bu herşeyi söylemelidir). Ancak, uzun zaman önce buna ihtiyacım vardı ve Komuta Paternini kullanarak kendi yaklaşımımı uyguluyorum. Aşağıda gösterildiği gibi, bu çok çaba ve çok basit değildir.

İlk olarak uygulamanızdaki bazı işlemleri yürütmek için Komutu adlı bir Arabirim oluşturmanız gerekecektir.

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

Sonraki size idam komutları kaydetmek ve bunları geri almak Tarih adlandırılan bazı sınıf gerekecektir.

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

sizin FXML size bu şifreyi uygulamanın geri alma işlevini çağırmak gerekir GUI'nizin için bir düğme oluşturabilirsiniz. senin FXML böyle aşağıdaki biri olarak, bir düğme oluşturmak:

<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> 

Denetleyiciniz sınıfta size FXML düğmeyi atıfta bulunur.

public class Controller { 
    // ... 
    @FXML private Button btnUndo; 
    // ... 

    @FXML 
    public void onUndo(ActionEvent event) 
    { 
     History.getInstance().undo(); 
    } 
} 

Gördüğünüz gibi, en iyi şey Tarih sınıf bir Singleton olmasıdır. Böylece her yere sınıftan ulaşabilirsiniz.

Yeni bir komut uygulamak için Komutu arabiriminden devralın. Yeni işlevler için bazı düğmeleri veya benzer GUI öğelerini kullanın ve geçmişinizi kullanarak özel komutu çalıştırın.

// 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 

Bu yaklaşımla, işleminizi geri alabilirsiniz. Bazı yineleme işlevselliği uygulamak da mümkündür. Bunun için FXML'de bir yinele düğmesi ve Tarihi sınıfı ve Komutu arabiriminde uygun yöntem ekleyin.

Komut düzeni hakkında daha fazla bilgi için, here'a bakın.

Mutlu Kodlama!

+0

Güzel bir çözüm, ancak teknik olarak javax.swing.undo 'hala JavaFX için geçerlidir. Daha sağlam olduğu için bunu yapmayı tercih ederim. Yine de resmi sürümde JavaFX için - UndoFX olarak - özel bir uygulama olmasını bekliyorum. – Mordechai

+0

Evet, bu hoş bir çözüm gibi görünüyor ... ama neden sadece mevcut 'swing.undo' paketini kullanmadınız? Swing paketleri hala Java ile paketlenmiş, bu nedenle tekerleği yeniden icat eden klasik bir durum değil mi? Yoksa başka bir gerekçeniz var mı? –