2016-08-22 17 views
7

Linux platformunda, Frame :: getBounds ve Frame :: setBounds tutarlı bir şekilde çalışmıyor. (!):Linux'ta getBounds() ve setBounds() ile ilgili bug_id = 4806603 için geçici çözüm?

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4806603

kolaylık olması açısından, bir hata ile sonuçlanır belirtilen kod basitleştirilmiş ve olarak yapıştırın: Bu zaten 2003 yılında rapor edilmiştir buraya bakın

import java.awt.Button; 
import java.awt.Frame; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

/** Demonstrates a bug in the java.awt.Frame.getBounds() method. 
* @author Mirko Raner, PTSC 
* @version 1.0 (2003-01-22) **/ 
public class GetBoundsBug extends Frame implements ActionListener { 
    public static void main(String[] arg) { 
    GetBoundsBug frame = new GetBoundsBug(); 
    Button button = new Button("Click here!"); 
    button.addActionListener(frame); 
    frame.add(button); 
    frame.setSize(300, 300); 
    frame.setVisible(true); 
    } 

    @Override 
    public void actionPerformed(ActionEvent event) { 
    Rectangle bounds = getBounds(); 
    bounds.y--; 
    setBounds(bounds); 
    bounds.y++; 
    setBounds(bounds); 
    } 
} 

Beklenmeyen davranış: Düğmeye tıklandığında pencere biraz aşağıya kaydırılır! https://youtu.be/4qOf99LJOf8

Bu davranış 13+ yıldır civarında olmuştur, bu yüzden muhtemelen resmi taraftan herhangi bir değişiklik olmayacak:

(. 28 piksel her tıklama ile benim sistemde) Burada bir ekran kaydıdır.

Bu hata için herhangi bir çözümü olan var mı? Özellikle, tüm platformlarda güvenilir bir şekilde önceki konumdaki pencereyi/çerçeveyi/iletişim kutusunu saklamak ve geri yüklemek istiyorum.

PS: My java kurulumu amd64 için jdk1.8.0_102 Oracletarafından Ubuntu 16 Linux üzerindedir. Son zamanlarda Windows'dan Ubuntu'ya geçtiğimden beri, Windows'da, yukarıdaki kodun beklendiği gibi çalıştığını biliyorum.

adaptasyon SwingWorker aynı etkiyi üretir kullanarak Swing:

import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.SwingWorker; 

public class GetBoundsBug extends JFrame implements ActionListener { 
    public static void main(String[] arg) { 
    GetBoundsBug myJFrame = new GetBoundsBug(); 
    JButton myJButton = new JButton("Click here!"); 
    myJButton.addActionListener(myJFrame); 
    myJFrame.setContentPane(myJButton); 
    myJFrame.setSize(300, 300); 
    myJFrame.setVisible(true); 
    } 

    @Override 
    public void actionPerformed(ActionEvent event) { 
    SwingWorker<Void, Void> mySwingWorker = new SwingWorker<Void, Void>() { 
     @Override 
     public Void doInBackground() { 
     Rectangle myRectangle = getBounds(); 
     myRectangle.y--; 
     setBounds(myRectangle); 
     myRectangle.y++; 
     setBounds(myRectangle); 
     return null; 
     } 
    }; 
    mySwingWorker.execute(); 
    } 
} 
+0

Sanırım belirli bir hatanın gördüğünüz şey olduğuna dair bir sonuca varmışsınızdır. Hata, 19 yıl önce yayınlanmış olan ve hatta Ubuntu 16 Linux'la (bilgime) gönderme yapmayan Aydınlanma Penceresi yöneticisinin (e17) üstündeki çalışmalarla ilgili anlaşmalardan bahsetti. –

+0

Sistemimde pencere yöneticisi kullanılıyor: Compiz – datahaki

+0

Sonra e17'ye özgü bir hata sizin için geçerli değil. Sadece OSX'e özgü bir hata bir Windows sistemi için geçerli değildir. Referans verdiğiniz hata, yaklaşık 20 yıl önce özelleştirme yaptığım çok eğlenceli bir şey olan e17 pencere sistemine karşı. Çok, çok az insan şimdi kullanıyor ve düzeltilmeyecek olmasının nedeni, 13 yıl önce ölü bir proje olmasıydı. e20 şu anki sürümdür, ancak henüz kararlı olup olmadığından emin değilim. Özetlemek gerekirse, size uygulanacak hatayı yanlış yorumlamışsınızdır, ancak bu, sizin sorununuz ile% 100 ilişkisizdir. –

cevap

1

Eh, orijinal hata veritabanı girişinde bu "düzeltmek olmaz" olarak işaretlenir ve pencere yöneticisi bir cilvesi olarak açıkladı JDK yerine.

Hangi pencere yöneticisini kullanıyorsunuz?

+0

pencere yöneticisi: Compiz. Ben burada yayınlanan JavaFx ile benzer bir sorun var: http://stackoverflow.com/questions/39086597/first-call-to-javafx-stagesety-inconsistent-on-linux-workaround – datahaki

1

Sadece ek bir not. Kodunuzun Etkinlik Sevk İşlemi'nde çok fazla başarısız olduğunu fark ettim. Java'nın tüm çizim API'leri, tasarım tarafından tekil olarak işlenir; bu, uygulamanızın, GUI güncellemelerini Olay Sevk İpliği'ne göndermediğiniz sürece uygulamanızın doğru bir şekilde çalışması beklenmemesi gerektiği anlamına gelir.

Bu, (ana sisteminizde), değerlendirildiğinde widget'larınızı sunacak ve bunu EDT'ye gönderecek yeni bir Runnable oluşturmanız gerektiği anlamına gelir. Ayrıca, eylem dinleyiciniz, yeniden yazdırma isteğini atlayarak ve EDT'ye gönderilmesini sağlamak için gereken tipik güvenlik önlemlerini göz ardı ederek, eylem içindeki bileşen durumunu eylemde günceller. Üste |

Bu yolların her ikisinde de, kod bir Java ortamında geçerli bir GUI kodu değildir ve tanımladığınız hatanın davranışınız ile ilgisi olmayabilir, çünkü programınız GUI araç takımı tasarımını ihlal etmeden bile bilecektir. böcek etkiliyorsa. Ayrıca, yalnızca bileşenleri kaydırır. Bileşenler yatarsa, yalan, Java'ya damlar. Bu konuda fazla bir şey yapılamıyor (ama artık bunun endişelenecek en önemli şey olduğunu düşünmüyorum). Bundan hoşlanmıyorsanız, çok daha aklı başında olan/kararlı bir ortam olan Swing'i kullanın.

+0

Ben bir kod uyarlama sorusu ekledim Bu salıncak kullanır. Orada, SwingWorker'ı kullanarak ancak başarılı olamadan tavsiyelerinizi denedim. Yanlış kullanıyorum lütfen tavsiye edin ... teşekkürler! – datahaki

+0

Eşzamanlılık ve Swing hakkında öğreticilere dikkat etmeniz gerekir. AWT için de geçerlidir. İşte bağlantı https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html –