Na platformie Linux, Frame :: getBounds i Frame :: setBounds nie działają konsekwentnie. (!) To już zostało zgłoszone w 2003 roku, patrz tutaj:Obejście problemu bug_id = 4806603 dotyczące getBounds() i setBounds() w systemie Linux?
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4806603
Dla wygody, mam uproszczona podanej kod, który powoduje błędu i wkleić go jako:
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);
}
}
Nieoczekiwane zachowanie: Po kliknięciu przycisku okno jest przesunięte nieco poniżej! (. W moim systemie o 28 pikseli każdy klik)
Oto nagranie ekranu: https://youtu.be/4qOf99LJOf8
To zachowanie zostało około 13+ lat, więc prawdopodobnie nie będzie żadnych zmian z oficjalnej strony.
Czy ktoś ma obejście tego błędu? W szczególności chciałbym przechowywać i przywracać okno/ramkę/dialog w poprzedniej lokalizacji niezawodnie na wszystkich platformach.
PS: Moja instalacja java jest jdk1.8.0_102 dla amd64 przez Oracle na Ubuntu 16 Linux. Odkąd przeprowadziłem migrację z systemu Windows do Ubuntu, wiem, że w systemie Windows powyższy kod działa zgodnie z oczekiwaniami.
Adaptacja do Swing za pomocą SwingWorker daje ten sam efekt:
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();
}
}
Myślę, że doszedłeś do wniosku, że konkretny błąd jest tym, co widzisz. Wspomniany błąd dotyczy gry na menadżerze Enlightenment Window (e17), który został wydany 19 lat temu, a nawet nie jest dostarczany z Ubuntu 16 Linux (według mojej wiedzy). –
mój system używa menedżera okien: Compiz – datahaki
Następnie błąd specyficzny dla e17 nie dotyczy ciebie. Tak jak błąd specyficzny dla OSX nie dotyczy systemu Windows. Błąd, o którym wspomniałeś, jest sprzeczny z systemem okienkowym e17, coś, co miałem dużo zabawy dostosowywania prawie 20 lat temu. Bardzo, bardzo niewielu ludzi go używa teraz, a powodem, dla którego nie zostało to naprawione, było to, że 13 lat temu był to martwy projekt. e20 to aktualna wersja, ale nie jestem pewien, czy jest stabilny. Podsumowując, źle zinterpretowałeś błąd, który możesz zastosować, ale tak nie jest, jest on w 100% niezwiązany z twoim problemem. –