Verschiebung eines Fensters über Button

melaniemueller

Aktives Mitglied
Guten Abend,
ich verzweifle gerade an meiner Aufgabe.

Folgende Aufgabenstellung:
Erstellen Sie eine Anwendung, in der Sie die Position des Fensters der Anwendung über vier Schaltflächen verändern können. Eine Schaltfläche soll das Fenster um 10 Pixel nach oben verschieben, eine um 10 Pixel nach unten und die beiden anderen um je 10 Pixel nach links beziehungsweise rechts.

Beachten Sie bei der Umsetzung bitte die folgenden Vorgaben:

• Erstellen Sie für den Listener eine innere Klasse in der Klasse mit dem Fenster der Anwendung. Der Listener soll die Ereignisse aller vier Schaltflächen verarbeiten können.

• Setzen Sie das Fenster der Anwendung fest auf die Größe 300 × 300 und positionieren Sie es zunächst an einer beliebigen Stelle auf dem Desktop.

• Ordnen Sie die Schaltflächen in einem BorderLayout mit einem Abstand von 25 Pixeln an.

• Stellen Sie sicher, dass das Fenster nicht aus dem Desktop herausgeschoben werden kann. Ermitteln Sie dazu die aktuelle Größe des Desktops und berechnen Sie dann die maximal möglichen Koordinaten für die Verschiebung nach rechts und nach unten. Für die Verschiebung nach links beziehungsweise oben können Sie den Wert 0 als Grenze verwenden.

Ein kleiner Tipp:

Wie Sie die aktuelle Größe des Desktops ermitteln können, finden Sie in diesem Studienheft beim Zentrieren eines Fensters auf dem Desktop. Sehen Sie dort gegebenenfalls noch einmal nach.

Nun hab ich mir das Grundgerüst aufgebaut, Button erstellt, BorderLayout erstellt, etc. Nun scheitert es aber an der Verschiebung. Mein Gedanke dazu war, über if Bedingungen den gedrückten Button finden, durch getActionCommand(). Beim jeweiligen Button dann die derzeitige Positions des Fensters ermitteln und dann über setLocation um 10px verschieben. Nun ist aber mein Problem, dass ich zum derzeitigen Lernstand nichts in meinem Heft zur Ermittlung der aktuellen Position gefunden habe. Logisch empfand ich hier die Methode getLocation. Jedoch zeigt er mir hier irgendwas mit Point an, was mir aktuell noch gar nichts sagt und ich darüber nichts gelernt habe, somit kann dies nicht der gewünschte Weg sein. Ich habe auch hier im Forum recherchiert und etwas gefunden, jedoch wird hier auch getLocation mit Point empfohlen.

Ich komm nicht weiter - wer hat eine andere Idee??

Hier noch mein unvollständiger Code zur besseren Verständlichkeit:

Java:
package einsendeaufgabe;

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

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

public class Positionswechsel extends JFrame {
    
    private JButton schaltflächeOben;
    private JButton schaltflächeUnten;
    private JButton schaltflächeRechts;
    private JButton schaltflächeLinks;
    
    class Listener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            //ab hier scheitert es - wie erfolgt die Verschiebung???
            if (e.getActionCommand().equals("Nach oben")){
                 }
            
                
            
        }
        
    }
    

    public Positionswechsel (String titel) {
        super (titel);
        JButton schaltflächeOben = new JButton ("Nach oben");
        JButton schaltflächeUnten = new JButton ("Nach unten");
        JButton schaltflächeRechts = new JButton ("Nach rechts");
        JButton schaltflächeLinks = new JButton ("Nach Links");
        
        setLayout(new BorderLayout());
        
        add(BorderLayout.NORTH,schaltflächeOben);
        add(BorderLayout.SOUTH, schaltflächeUnten);
        add(BorderLayout.EAST, schaltflächeRechts);
        add(BorderLayout.WEST, schaltflächeLinks);
        
        setSize(300,300);
        setLocationRelativeTo(null);
        setVisible(true);
    }

}
 
Du hast ja die 4 JButton Instanzvariablen in der äußeren Klasse (und darauf hat die innere Klasse Zugriff!).
ActionEvent hat die Methode getSource(), welches das Control angibt, das das Event ausgelöst hat.

Somit kannst Du e.getSource() == schaltflächeOben prüfen.
 
Du hast ja die 4 JButton Instanzvariablen in der äußeren Klasse (und darauf hat die innere Klasse Zugriff!).
ActionEvent hat die Methode getSource(), welches das Control angibt, das das Event ausgelöst hat.

Somit kannst Du e.getSource() == schaltflächeOben prüfen.
Du meinst e.getSource() anstatt getActionCommand()? Aber damit erhalte ich ja auch nicht die aktuelle Position des Fensters oder sondern welcher Button geklickt wurde?
 
Du setzt doch das Fenster an eine von dir festgelegte Stelle. Die kannst du dir ja merken und wenn das Fenster verschiebt auch mit aktualisieren.
Somit müsste du die pos auch haben ohne die abzufragen.
 
Mit dem letzten Tipp deiner Aufgaben Stellung. Solltest du wissen wo an welcher Stelle auf dem Desktop das Fenster Beim erstellt ist.

Bin mir nicht ganz sicher. Der von dir ermittelte Punkt müßte die obere linke Ecke vom Fenster sein.
 
Zuletzt bearbeitet:
Hab jetzt mal einiges verändert, aber irgendwie passiert nichts wenn ich auf einen Button klicke? Den Listener hab ich hinzugefügt, also was fehlt hier noch damit was umgesetzt wird 🤨
Java:
package einsendeaufgabe;

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

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

public class Positionswechsel extends JFrame {
    
    
    private JButton schaltflächeOben;
    private JButton schaltflächeUnten;
    private JButton schaltflächeRechts;
    private JButton schaltflächeLinks;
    private int x,y;

    class Listener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {           
            if (e.getSource() == schaltflächeOben){
                y = y - 10;
                 }
            if (e.getSource() == schaltflächeUnten){
                y = y + 10;
                 }
            if (e.getSource() == schaltflächeRechts){
                x = x + 10;
                 }
            if (e.getSource() == schaltflächeLinks){
                x = x - 10;
                 }
        }
        
    }
    
    public Positionswechsel (String titel) {
        super (titel);
        JButton schaltflächeOben = new JButton ("Nach oben");
        JButton schaltflächeUnten = new JButton ("Nach unten");
        JButton schaltflächeRechts = new JButton ("Nach rechts");
        JButton schaltflächeLinks = new JButton ("Nach Links");
        x = 300;
        y = 300;
        
        setLayout(new BorderLayout());
        setSize(300,300);
        setLocation(x,y);
        add(BorderLayout.NORTH,schaltflächeOben);
        add(BorderLayout.SOUTH, schaltflächeUnten);
        add(BorderLayout.EAST, schaltflächeRechts);
        add(BorderLayout.WEST, schaltflächeLinks);
        schaltflächeOben.addActionListener(new Listener());
        schaltflächeUnten.addActionListener(new Listener());
        schaltflächeRechts.addActionListener(new Listener());
        schaltflächeLinks.addActionListener(new Listener());
        setVisible(true);
    }

}
 
Mit dem letzten Tipp deiner Aufgaben Stellung. Solltest du wissen wo an welcher Stelle auf dem Desktop das Fenster Beim erstellt ist.

Bin mir nicht ganz sicher. Der von dir ermittelte Punkt müßte die obere linke Ecke vom Fenster sein.
Mit dem letzten Teil der Aufgabe hab ich mich noch gar nicht beschäftigt muss ich zugeben 😅 Ich dacht mir das ergänze ich zum Schluss wenn die Buttons dann mal funktionieren.
Die aktuelle Bildschirmauflösung erhalte ich dann aber über Toolkit.getDefaultToolKit().getScreenSize()
 
Du hast ein JFrame. Und da hast du getLocation und setLocation.

Damit kannst du die Position holen, anpassen und erneut setzen.
 
Ja, du hattest das schon richtig gesagt: Oben links ist (0,0) und man gibt an, wo dann die linke obere Ecke plaziert werden soll.
 
Du hast ein JFrame. Und da hast du getLocation und setLocation.

Damit kannst du die Position holen, anpassen und erneut setzen.
Wie ganz zu Anfang beschrieben, habe ich noch kein getLocation gelernt und darf es nicht verwenden. Daher hab ich es jetzt über x und y gemacht und dort die Werte bei setLocation gespeichert. Trotzdem passiert nichts. Ich hab nun im Listener unterhalb der if Bedingungen nochmals setLocation aufgerufen und trotzdem passiert nichts. Auch wenn ichs in jede if Bedingung setze nicht....😒
Wieso?

Java:
package einsendeaufgabe;

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

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

public class Positionswechsel extends JFrame {
    
    
    private JButton schaltflächeOben;
    private JButton schaltflächeUnten;
    private JButton schaltflächeRechts;
    private JButton schaltflächeLinks;
    private int x,y;

    class Listener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {           
            if (e.getSource() == schaltflächeOben){
                y = y - 10;
                 }
            if (e.getSource() == schaltflächeUnten){
                y = y + 10;
                 }
            if (e.getSource() == schaltflächeRechts){
                x = x + 10;
                 }
            if (e.getSource() == schaltflächeLinks){
                x = x - 10;
              }               
            setLocation(x,y);
        }
        
    }
    
    public Positionswechsel (String titel) {
        super (titel);
        JButton schaltflächeOben = new JButton ("Nach oben");
        JButton schaltflächeUnten = new JButton ("Nach unten");
        JButton schaltflächeRechts = new JButton ("Nach rechts");
        JButton schaltflächeLinks = new JButton ("Nach Links");
        x = 300;
        y = 300;
        
        setLayout(new BorderLayout());
        setSize(300,300);
        setLocation(x,y);
        add(BorderLayout.NORTH,schaltflächeOben);
        add(BorderLayout.SOUTH, schaltflächeUnten);
        add(BorderLayout.EAST, schaltflächeRechts);
        add(BorderLayout.WEST, schaltflächeLinks);
        schaltflächeOben.addActionListener(new Listener());
        schaltflächeUnten.addActionListener(new Listener());
        schaltflächeRechts.addActionListener(new Listener());
        schaltflächeLinks.addActionListener(new Listener());
        setVisible(true);
    }

}
 
Du hast Instanzvariablen in der Klasse deklariert aber diese werden nie initialisiert. Was nutzt Du für eine IDE? Ich würde Dir empfehlen, eine IDE wie IntelliJ zu nutzen, die Dir sowas anzeigt. IntelliJ wird dir z.B. bei den Instanzvariablen die Warnung anzeigen: "Private field 'xxx' is never assigned"

Das Problem ist - wie @mihe7 schon sagte, dass Du in dem Konstruktor nicht den Instanzvariablen etwas zuweist, sondern neue lokale Variablen erstellst. Das Ergebnis ist, dass bei einem Click das getSource() immer mit null verglichen wird.

Lösung ist, da keine neuen Variablen zu deklarieren - also das JButton weg zu lassen. Sprich:
JButton schaltflächeOben = new JButton ("Nach oben");
 
Eclipse ist eigentlich bei so Warnungen auch relativ gut. Bei unbenutzen Variablen würde es warnen. Aber ich muss gestehen, dass ich mich mit Eclipse nicht so gut auskenne.

Da einfach mal drauf schauen: Wird eine Zeile anders dargestellt als sonst? Üblich sind Dinge wie:
- Etwas wird unterstrichen (rot oder gelb)
- Etwas wird nur grau angezeigt
- Am rechten oder Linken Rang werden Symbole eingeblendet

Sowas kann man sich in der Regel ansehen, wenn man mit der Maus drauf geht. Also Maus drauf und kurz warten. Dann sollte die Fehlermeldung eingeblendet werden.

Mein Tipp ist: So Hinweisen immer nachgehen. Das sind in der Regel Hinweise, das etwas falsch ist (rote Darstellung) oder etwas unüblich ist (Gelb und teilweise andere Farben).

Diesen Hinweisen muss man nicht nachgehen. IntelliJ schlägt teilweise Verbesserungen vor, wie Umwandlung in Lambda Ausdrücke oder so. Die kann man dann ignorieren. Aber immer erst verstehen: Was will die IDE von mir? Auch ruhig ansehen und ggf. (hier im Forum) nachfragen. (IntelliJ bietet oft schnelle Fixe an. Dann stellt die IDE einem Codeteile um. Wird Eclipse aber vermutlich ebenso haben.)
 
Da ich hier gerade noch ein uraltes Eclipse rumliegen habe: unter Window -> Preferences -> Java -> Compile -> Errors/Warnings gibt es einen Abschnitt "Name shadowing and conflicts". Dort kann man bei "Local variable declaration hides another field or variable" auf "Warning" stellen. Danach sind die vier Variablen auch gelb unterringelt:

Bildschirmfoto von »2021-07-30 10:01:19«.png
 
Du hast Instanzvariablen in der Klasse deklariert aber diese werden nie initialisiert. Was nutzt Du für eine IDE? Ich würde Dir empfehlen, eine IDE wie IntelliJ zu nutzen, die Dir sowas anzeigt. IntelliJ wird dir z.B. bei den Instanzvariablen die Warnung anzeigen: "Private field 'xxx' is never assigned"

Das Problem ist - wie @mihe7 schon sagte, dass Du in dem Konstruktor nicht den Instanzvariablen etwas zuweist, sondern neue lokale Variablen erstellst. Das Ergebnis ist, dass bei einem Click das getSource() immer mit null verglichen wird.

Lösung ist, da keine neuen Variablen zu deklarieren - also das JButton weg zu lassen. Sprich:
JButton schaltflächeOben = new JButton ("Nach oben");
sie will doch nicht die Schaltfächen verschiben sonder das JFrame (fenster) dafür hat sie die x un y Werte als instanzvariablen .
du greifst bestimmt nicht mit setLocation(x,y); auf das Fester JFrame zu .

ob du mit setLocation(x,y); das neu zeichnen des Festers anstösst bin ich mir jetzt nicht sicher.
 
Zuletzt bearbeitet:
sie will doch nicht die Schaltfächen verschiben sonder das JFrame dafür hat sie die x un y Werte als instanzvariable .
du greifst bestimmt nicht mit setLocation(x,y); auf das Fester JFrame zu .
Stimmt.
Die Felder
Java:
    private JButton schaltflächeOben;
    private JButton schaltflächeUnten;
    private JButton schaltflächeRechts;
    private JButton schaltflächeLinks;
sind nicht notwendig.
 
Nun dachte ich eigentlich der letzte Teil der Aufgabe sei einfach. Vielleicht ist er dass auch und nur mir kommt es so kompliziert vor...
Ich möchte nun einstellen dass es nicht aus dem Bildschirm hinaus verschoben werden kann. Also habe ich als erstes die Bildschirmgröße mit
Java:
Dimension bgrösse = Toolkit.getDefaultToolkit().getScreenSize();
ermittelt.

Unter bgrösse.height wäre dann die Höhe und width die Breite abgespeichert. Bei oben und links soll auf 0 überprüft werden, da das Fenster ja oben links die Koordinaten 0 hat. Also hab ich bei der if Bedingung ergänzt
Java:
if (e.getSource() == schaltflächeOben && y != 0){
Das funktioniert auch super!

Nur irgendwie komm ich nicht drauf wie ich jetzt das Ganze für die anderen 2 Bereiche ausrechne???? 😵
 
Da ich hier gerade noch ein uraltes Eclipse rumliegen habe: unter Window -> Preferences -> Java -> Compile -> Errors/Warnings gibt es einen Abschnitt "Name shadowing and conflicts". Dort kann man bei "Local variable declaration hides another field or variable" auf "Warning" stellen. Danach sind die vier Variablen auch gelb unterringelt:

Anhang anzeigen 15918
Super danke stelle ich gleich um!
 
sie will doch nicht die Schaltfächen verschiben sonder das JFrame (fenster) dafür hat sie die x un y Werte als instanzvariablen .
du greifst bestimmt nicht mit setLocation(x,y); auf das Fester JFrame zu .
Natürlich wird mit dem setLocation die Position des Fensters gesetzt. Und die Schaltflächen werden auch nicht verschoben (Was auch nicht wirklich gehen würde, da sie ja ein Border Layout hat 🙂 )

Nur irgendwie komm ich nicht drauf wie ich jetzt das Ganze für die anderen 2 Bereiche ausrechne???? 😵
Du hattest doch schon geschrieben, wie Du die Bildschirm Auflösung bekommen kannst.
Die Größe des Fensters kennst Du auch.
x + Breite des Fensters muss <= der Auflösung in der Breite sein.

Gleiches gilt für die Höhe.
 
Nun dachte ich eigentlich der letzte Teil der Aufgabe sei einfach. Vielleicht ist er dass auch und nur mir kommt es so kompliziert vor...
Ich möchte nun einstellen dass es nicht aus dem Bildschirm hinaus verschoben werden kann. Also habe ich als erstes die Bildschirmgröße mit
Java:
Dimension bgrösse = Toolkit.getDefaultToolkit().getScreenSize();
ermittelt.

Unter bgrösse.height wäre dann die Höhe und width die Breite abgespeichert. Bei oben und links soll auf 0 überprüft werden, da das Fenster ja oben links die Koordinaten 0 hat. Also hab ich bei der if Bedingung ergänzt
Java:
if (e.getSource() == schaltflächeOben && y != 0){
Das funktioniert auch super!

Nur irgendwie komm ich nicht drauf wie ich jetzt das Ganze für die anderen 2 Bereiche ausrechne???? 😵
wie gross dein Fenster ist weisst du ja (300) also ist die rechte Kante 300 keiner als die rechte Seite des Bildschirms.
oder das max x vom Bildschirm
 

Neue Themen


Zurück
Oben