Fenster um x Pixel bewegen, wenn man auf dem Knopf drückt

TheSepp

Mitglied
Hallo, ich versuche ein Programm zu erstellen, wo sich das Fenster um x Pixel bewegt, wenn man auf einen Knopf drückt. Ich bekomme es irgendwie nicht hin, dass es das tut. Ich würde es gerne über eine innere Klasse durchführen. Hier ist die innere Klasse mit dem Listener. Ich bedanke mich schon mal für die Hinweise.


Java:
// Die innere Klasse
    class Listener extends WindowAdapter implements ActionListener{
        
        @Override
        public void windowOpened(WindowEvent e) {
            
            //fenstergröße setzen
            setSize(300,300);
            //zentriert auf dem Desktop darstellen
            //die Bildschirmauflösung beschaffen und in einer Variablen vom Typ Dimension speichern
            Dimension bGroesse= Toolkit.getDefaultToolkit().getScreenSize();
            //das Fenster positionieren
            setLocationRelativeTo(null);
            x = (int) bGroesse.getHeight();
            y = (int) bGroesse.getWidth();
            
            System.out.println(x);
            System.out.print(y);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getActionCommand().equals("Oben"))
                y += 100;
                x += 100;
                setLocation(x,y);
        }
    }
 
Dann schau einfach einmal, auf was Du x / y setzt. Das ist ja die Größe des Bildschirms. Damit wäre das Fenster schon nicht sichtbar, aber Du verschiebst es noch um 100 Pixel weiter raus ...

Ich würde es gerne über eine innere Klasse durchführen.
Und genau das solltest Du Dir überlegen. Das ist einfach ausgedrückt: unleserlicher Unsinn. Mit Java 8 wurde diesbezüglich nicht ohne Grund einiges an Möglichkeiten gebaut, damit man eben nicht mehr so einen unleserlichen Code schreiben muss.
==> keine innere Klasse, die den Code in erster Linie aufbläht.
==> Kein Mischen von Dingen - Deine Innere Klasse macht ganz offensichtlich mehrere Dinge.
==> Methoden sauber benennen (Was durch diesen Ansatz verhindert wird!)
==> Keine unnötigen if Statements - eine actionPerformed und da musst Du dann das Control auswerten?


Und dann auch immer die Logik gut überlegen. Das dies schon von der Logik her komplett falsch gelaufen ist, habe ich im ersten Satz gezeigt. Aber wie wäre es denn besser?
EIn ebenso wichtiger Punkt: Was ist, wenn der Anwender das Fenster noch manuell verschoben hat? Alleine schon daher sollte die Logik sein:
  • aktuelle Position holen
  • neue Position berechnen
  • neue Position setzen
 
Java:
public void actionPerformed(ActionEvent e) {
            if (e.getActionCommand().equals("Oben") & y != 0) {
                y -= 10;
            }
            if (e.getActionCommand().equals("Rechts")) {
                x += 10;
            }
            if (e.getActionCommand().equals("Unten")) {
                y += 10;
            }
            if (e.getActionCommand().equals("Links") & x != 0) {
                x -= 10;
            }
            setLocation(x,y);

Habe es hinbekommen das sich das Fenster bewegt, danke schonmal dafür! Jetzt möchte ich aber das, wenn das Fenster außerhalb des Bildschirms verschoben wird, sollte es nicht möglich sein. Für den oberen und linken Bereich habe ich das erledigt, für die restlichen zwei bekomme ich das irgendwie nicht hin.
 
Dein Code ist so nicht wirklich gut. Was ist, wenn der y Wert kein vielfaches von 10 ist. y ist z.B. 7.
Dann verschiebst Du auf -3, dann auf -13, -23, -33, ... Das sind ja alles Werte != 0!

Daher: Verändere den Wert, also rechne y -= 10. Dann prüfe: Ist y < 0? Wenn ja, dann ist y=0.
Das wäre doch viel logischer, oder?

Und in die andere Richtung: Du hast ja schon den Code um die Dimensionen des Bildschirms zu erhalten. Und wenn Du die Breite bzw. Höhe des Fensters davon abziehst, dann hast Du den maximalen Wert.

Und wieso machst Du nicht eine Methode wie:
Java:
    public void moveWindow(int dx, int dy) {
        Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
        Point location = frame.getLocation();
        location.x = location.x + dx;
        location.y = location.y + dy;

        if (location.x < 0) location.x = 0;
        if (location.y < 0) location.y = 0;
        if (location.x + frame.getWidth() > dimension.width) location.x = dimension.width - frame.getWidth();
        if (location.y + frame.getHeight() > dimension.height) location.y = dimension.height - frame.getHeight();
        
        frame.setLocation(location);
    }

Und bei den Controls bindest Du diese dann in der Form ein:
obenButton.addActionListener( e -> moveWindow(0, -10));

Wenn der Anwender das Fenster manuell verschiebt, dann wird die neue Position automatisch genommen ... all sowas ...

Alternativ kann man das auch gerne noch Kapseln in Methoden ... z.B.
Java:
    public void moveWindowUp() {
        moveWindow(0, -10);
    }

obenButton.addActionListener( e -> moveWindowUp());

Oder man gibt dem moveWindowUp noch ein ActionEvent Parameter - dann kann man eine einfache Methodenreferenz nutzen:
obenButton.addActionListener( this::moveWindowUp );
 
Danke schon mal. Habe die Logik verstanden. Gäbe es auch eine Möglichkeit, den Code in die innere Klasse umzusetzen? sry für die späte Antwort. 🙂
Java:
@Override
        public void actionPerformed(ActionEvent e) {
            Dimension bGroesse= Toolkit.getDefaultToolkit().getScreenSize();

            if (e.getActionCommand().equals("Oben") & y > 0) {
                y -= 10;
            }
            if (e.getActionCommand().equals("Rechts")) {
                x += 10;
            }
            if (e.getActionCommand().equals("Unten")) {
                y += 10;
            }
            if (e.getActionCommand().equals("Links") & x > 0) {
                x -= 10;
            }
            setLocation(x,y);
 
Gäbe es auch eine Möglichkeit, den Code in die innere Klasse umzusetzen?
Klar, bau die Methoden wie beschrieben und rufe diese dann einfach auf:
Java:
            if (e.getActionCommand().equals("Oben")) {
                moveWindow(0,-10);
            }
            if (e.getActionCommand().equals("Rechts")) {
                moveWindow(10,0);
            }
            if (e.getActionCommand().equals("Unten")) {
                moveWindow(0,10);
            }
            if (e.getActionCommand().equals("Links")) {
                moveWindow(-10,0);
            }
 
Deshalb musst du das Frame an die Methode mit übergeben
Falls diese Methode in deinem Frame steht, verwendes "this" anstatt "frame".
Falls nicht, übergib das Frame an die Methode
PHP:
public voids moveWindos (JFrame frame, int dx, int dy) {}
Deine Listener müssen das Window natürlich kennen. Die selben Regeln gelten hier.
 
Die Frage ist, wo Du das JFrame gespeichert hast. Wenn Du eine Klasse von JFrame abgeleitet hast (Was nicht so gut ist - suche mal in Google nach "Favour Composition over Inheritance"), dann wäre es this (oder in einer inneren Klasse dann etwas wie OuterClass.this - aber innere Klassen solltest Du auch nicht verwenden - das Thema hatten wir ja auch schon incl. Alternativen!).
 

Zurück
Oben