2011-02-07 50 views
8

Swing'de bazı işlemler yaptıktan sonra kullanıcı arayüzünü güncellemenin doğru yolu nedir? Örneğin, bir düğmeyi tıkladıktan sonra hemen hemen anında veya birkaç saniye sürebilen bir yöntem çağrılır. Örneğin; Aslında, tüm uygulama mantığı bir web servisi aracılığıyla uzaktan yapılır, bu yüzden uygulamanın yanıt vermesi için biraz beklemek normaldir. Bir düğme içinSalınım, UI'nin düzgün şekilde nasıl güncelleştirileceği

Benim eventhandler bu gibi görünebilir:

myButton.addActionListener(new java.awt.event.ActionListener() { 
    public void actionPerformed(java.awt.event.ActionEvent evt) { 
     //callWebService(); 
     //do stuff 
     //updateUI(); // <----- repaint? revalidate? what? 
    } 
}); 

Benim şu anki uygulama dahili olarak geçerli hale getirmesi() çağırın ve UI tutan ana bileşenine() yeniden boyamak updateUI yöntemini çağırır. Bu çalışır, ancak bazen ekran titriyor görebilirsiniz. Yanlış mı yapıyorum? Bunu yapmanın daha iyi bir yolu var mı?

+0

http://en.wikipedia.org/wiki/SwingWorker – qwerty

+0

Anladığım kadarıyla, bu soru, kullanıcı arabirimini (UI) yanıtlamak için başka bir iş parçacığı yapmaktan ziyade bir şey yaptıktan sonra UI'yi güncellemekle ilgilidir. Yine de, yöntemin yürütme süresinin neden bahsedildiğini anlamıyorum. –

+0

Yürütme süresinden bahsetmiştim çünkü Swing'in bileşenleri yüklemeye çalışırken biraz farklı davranması ve yükün çok uzun sürmesi, dolayısıyla belki de ekranın yeniden çizilmesini gerektiriyor. – Hectoret

cevap

0

Normalde hiçbir şey yapmanız gerekmez: swing bileşenlerini veya model yöntemlerini kullanırsanız, gerekli olaylar tetiklenir ve GUI kendini otomatik olarak güncelleştirmelidir.

kendi modellerini define (ve gerekli etkinlikleri tetikleyebilir unutma, ama sonra modellerinizden bir hata varsa bu durum söz konusu olmayacak ve orada sabit olmalıdır.

+0

GUI olay işleme iş parçacığında JSpinner.setValue() yöntemini çağırırsam, UI otomatik olarak güncelleştirmeli mi? Bazen uygulamalardan birinde bunu yapmadığını hatırlıyorum. Pencereyi hareket ettirdiysem veya onu geçersiz kılacak bir şey yapsaydım (başka bir pencereyi geçici olarak gizlemek gibi), o zaman güncelleme yapardı. JRE'deki bir böcek miydi? –

+0

Evet, ti GUI'yi otomatik olarak güncellemelidir (olay gönderme iş parçasında (EDT) başka bir şey olmadığında) ve EDT'de yöntemi çağırdığınızdan emin olmanız gerekir. Uygulamanızın birinde neden çalışmadığını söyleyemem, ama yapmalı. –

1

uzun çalışan atın Farklı bir iş parçacığı için bir görev.Daha olayları, GUI'yi java.awt.EventQueue.invokeLater ile güncelleştirmek için olayları geri gönder (EDT)

5

SwingWorker'ı kullanmak için doğru olanı kullanmaktır, ancak el ile yapmak isterseniz Aşağıdaki deseni uygulamak için:

Yeniden boya/yeniden doğrulama sorusu için normal olarak revalidate() ve repaint() numaralı telefonu arayın. Bu, elbette, sadece elle çizdiğiniz bileşen için geçerlidir. Yeniden kullandığınız bileşenler için değer değiştirme yöntemlerini çağırın.

+0

Neden SwingWorker bunu "doğru" şekilde kullanmıyor? Tüm geri çağırma işlerini sizin için ele alan güzel ve kullanımı kolay bir arabirim sağlar ve görev tamamlandığında kullanıcı arayüzünü güncellemenin kolay bir yolunu sağlar. – berry120

+2

@berry, "SwingWorker olmaksızın, bunu yapmanın doğru yolu bu" ifadesinin "Swing çalışanı kullanmak doğru yoldur, ancak bunu kullanmadan yapmak istiyorsanız ..." şeklinde düşünülmüştür. " –

+1

Ah, görüyorum - biraz belirsiz olsa da, sanırım her iki şekilde de alınabilir! – berry120

4

Ben şahsen diğer yorum/bazı yanıtlar rağmen bunun için SwingWorker kullanmak:

  • UI duyarlı tutmak rağmen orijinal sorunun parçası değil, bunu yapmak iyi bir uygulamadır Her neyse (EDT'yi uzun bir işlemle kilitlemek için tek bir iyi neden düşünemiyorum.)
  • Görev tamamlandığında EDT'de yürütülecek olan bir done() yöntemini sağlar; invokeLater()
  • 'daki öğeleri elle kaydırma gereksinimi daha fazla Gerektiğinde, daha sonra istenirse ilerlemenin daha kolay eklenebileceği şekilde bilgi vermek için çerçeveyi sağlamak.

Son zamanlarda genel olarak bir çok SwingWorker nefreti gördüm ve nedenini anlamıyorum. Özellikle iyi çalışan bu gibi amaçlar için güzel tasarlanmış, genişletilebilir bir sınıftır. Evet, iş parçacığına bir şeyler koyabilir ve onları fırlatabilir ve diğer yöntemleri invokeLater()'da tamamlayabilirsin, ama daha iyi bir tane var mı, neden tekerleği yeniden icat etsin?

İlgili konular