Fenster über die Bildschirmgröße nach unten und oben wandern lassen

Hallo Leute,

ich habe ein Fenster erstellt, welches ich per Schleife nach unten und oben wandern lassen möchte. Nach unten wandert das Fenster bereits problemlos. Ich möchte aber, dass, wenn der untere Rand des Fensters am unteren Bildschirmrand ankommt, es wieder nach oben wandert. Das klappt noch nicht wie gewünscht.

Hier mal mein Ansatz, was ich bisher versucht habe (in einigen Varianten):

Dimension d = Toolkit.getDefaultToolkit().getScreenSize().getSize();
			String eingabe=JOptionPane.showInputDialog("Bitte geben Sie ein, wie viele Sekunden der Durchlauf betragen soll:");
			double step=60*Double.parseDouble(eingabe);
			
			for(double i=0, j=0; i<(d.width-b.getWidth()); i = i + ((d.width-b.getWidth()-768)/step),j = j + ((d.height-b.getHeight())/step))
			{
				//wenn das bild b die anliegestelle x erreicht hat, die
				//als bildschirmgröße - der höhe des bildes definiert ist
				//dann soll i sich um die bildschirmgröße minus der höhe des 
				//bildes +768 erhöhen / 60
                                 //auch mit if(d.getSize().getHeight()==...) probiert
				if(b.getAlignmentY()==d.getSize().height()-b.getHeight())
					i = i + ((d.height-b.getHeight()/*+768*/)/step);
				try
				{
					Thread.sleep(10);
				}
				catch (InterruptedException e){}
				b.setLocation((int)i,(int)j);
			}

Für einen Tipp oder eine Lösung wäre ich dankbar.

Lg

der Code wirkt auf mich etwas chaotisch, daher habe ich nicht versucht, ihn zu verstehen.
Aber hier verrechnest Du i (das die x-Koordinate festlegt und mit der Breite verglichen wird) mit irgendwelchen Höhenangaben:

lege Variablen an für Werte wie d.height-b.getHeight(),
gib ihnen Namen, selbst wenn nicht vollständig perfekt, auch ‘abstandUnten’ hilft etwas

die Werte sind hier doch auch über die Schleife unveränderlich, stimmts?


beschreibe in exakten Beispielen, was deiner Meinung nach passieren sollte,
Kommentare schon nicht schlecht, aber noch ausführlicher,

gib konkrete Ausgangsdaten:

  • Breite/ Höhe der Komponente sowie des Bildschirms (wieso ist eigentlich Breite relevant bei Bewegung oben/ unten?),
  • was verwendest du als eingabe, schreibe das übrigens lieber testweise ins Programm statt bei jedem Test neu einzutippen…

wieviele Steps ergeben sich daraus (ungefähr), welchen Werte bekommt ‘abstandUnten’ usw.,
welchen Verlauf erwartest du grob, was genau soll nach 1, 2, 3 Steps passieren,
an welchem Step soll der untere Bildschirmrand erreicht sein,
welche exakten (oder relativen) Positionen erhoffst du dir die 3 Steps davor sowie vor allem danach?


das vorherige wirst du sicher nicht alles aufsagen können, dafür hilft dann die Interaktion mit dem Programm,
LOGGE mit System.out.println(), was du alles an Variablen erhälst, rechne kurz aus wieviele Steps sich wohl ergeben,

LOGGE alle Steps, evtl. später mit if unwichtige Teilbereiche ausklammern um nicht zu viele Daten zu bekommen,
schaude dir genau an, wieviel sich bewegt wird, was genau in kritischen Teilen wie bei Erreichen des unteren Randes passiert,
vergleiche es mit deinen Wünschen, prüfe skeptisch ob deine Befehle zielführend sind


ganz allgemein kann man vielleicht schon wie fast überall sagen, dass du besser nicht i in der Schleife verändern solltest,
vielleicht generell für i auf ordentliche Werte Zahlen 1 bis n wechseln (Anzahl Steps!), Rest davon abhängig berechnen

und außerdem hängt deine Location von i ab, das geht wohl schlecht dass i größer und kleiner wird,
lasse i nur von 1 bis n laufen und entwickle davon abhängig eine Formel, die die richtige Position bestimmt

vielleicht hilft dir ein einfachere Aufgabe:
entwickle eine Schleife über i von 1 bis 10, die die Ausgabe


1 1
2 2
3 3
4 4
5 5
6 4
7 3
8 2
9 1
10 0

erzeugt, als Hilfsmittel sei if genannt

Teilproblem ähnlich, ohne Swing-Schnickschnack drumherum

Mal abgesehen davon: wofuer brauchst du so ein „wanderndes fenster“ ? :smiley:

Weil’s Spaß macht :smiley:

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.util.Random;

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


public class BoingWindowTest
{

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
    
    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.setSize(200,150);
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize().getSize();
        f.setLocation(d.width / 2 - f.getWidth() / 2, d.height - f.getHeight());
        
        final Animator animator = 
            new Animator(new Rectangle(0,0,d.width,d.height), f);
        JButton boingButton = new JButton("Boing!");
        boingButton.addActionListener(new ActionListener()
        {
            Random random = new Random(0);
            
            @Override
            public void actionPerformed(ActionEvent e)
            {
                double dx = -100 + random.nextDouble() * 200;
                double dy = - random.nextDouble() * 400;
                animator.addVelocity(dx, dy);
            }
        });
        f.getContentPane().add(boingButton);
        f.setVisible(true);
    }
}


class Animator
{
    private final Rectangle bounds;
    private final JFrame frame;
    private final Point2D position;
    private final Point2D velocity;
    private final Point2D acceleration;
    
    Animator(Rectangle bounds, JFrame frame)
    {
        this.bounds = new Rectangle(bounds);
        this.frame = frame;
        
        position = new Point2D.Double(frame.getX(), frame.getY());
        velocity = new Point2D.Double();
        acceleration = new Point2D.Double(0, 9.81);
        
        Thread t = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                runAnimation();
            }
        });
        t.setDaemon(true);
        t.start();
    }
    
    void addVelocity(double dx, double dy)
    {
        velocity.setLocation(
            velocity.getX()+dx, 
            velocity.getY()+dy);
    }
    
    
    private void runAnimation()
    {
        long n0 = System.nanoTime();
        while (true)
        {
            long n1 = System.nanoTime();
            double dt = (n1-n0) / 1e9;
            n0 = n1;
            handleMovement(dt);
            handleCollisions();
            final Point p = new Point((int)position.getX(), (int)position.getY());
            SwingUtilities.invokeLater(new Runnable()
            {
                @Override
                public void run()
                {
                    frame.setLocation(p);
                }
            });
            try
            {
                Thread.sleep(30);
            }
            catch (InterruptedException e)
            {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    private void handleMovement(double dt)
    {
        scale(velocity, 0.99);
        scaleAddAssign(velocity, dt*15, acceleration);
        scaleAddAssign(position, dt*15, velocity);
    }

    private void handleCollisions()
    {
        double cd = 0.8;
        double maxX = bounds.getWidth()-frame.getWidth();
        if (position.getX() < 0)
        {
            position.setLocation(-position.getX(), position.getY());
            velocity.setLocation(-velocity.getX()*cd, velocity.getY());
        }
        else if (position.getX() > maxX)
        {
            position.setLocation(maxX+maxX-position.getX(), position.getY());
            velocity.setLocation(-velocity.getX()*cd, velocity.getY());
        }

        double maxY = bounds.getHeight()-frame.getHeight()-1;
        if (position.getY() < 0)
        {
            position.setLocation(position.getX(), -position.getY());
            velocity.setLocation(velocity.getX(), -velocity.getY()*cd);
        }
        else if (position.getY() > maxY)
        {
            position.setLocation(position.getX(), maxY+maxY-position.getY());
            velocity.setLocation(velocity.getX(), -velocity.getY()*cd);
        }
    }
    
    private static void scale(Point2D result, double factor)
    {
        double x = result.getX() * factor;
        double y = result.getY() * factor;
        result.setLocation(x, y);
    }    
    private static void scaleAddAssign(Point2D result, double factor, Point2D addend)
    {
        double x = result.getX() + factor * addend.getX();
        double y = result.getY() + factor * addend.getY();
        result.setLocation(x, y);
    }    
}


Das ist ja ein sehr lustiges Fenster @Marco13