# Auf Tastendruck warten



## A-Stern (21. Feb 2012)

Ich suche eine Möglichkeit, mit der ich das Programm pausieren kann, bis der Anwender eine Taste drückt. (kann auch eine beliebige sein, weil ich mit dem Programm "nur" den A-Stern-Algorithmus teste.)

Also so ähnlich, wie 
	
	
	
	





```
try
{
    Thread.sleep(300);
}
catch (InterruptedException e){}
```
, aber nur, dass ich eine Taste drücke, statt eine gewisse Zeit zu warten.

Ich brauche die Lösung so, weil ich einfach eine Gewisse Zeit brauche, um mir das anzusehen, was mir mein Computer da anzeigt. Ich kann deshalb kein langes Delay verwenden, weil die Zeit einfach zu unterschiedlich ist und ich nicht sagen kann, wie lange ich dafür brauche.


----------



## bERt0r (21. Feb 2012)

```
class MyThread extends Thread
{
   boolean isPaused=false;
   boolean isRunning=false;
   public void run()
   {
      isRunning=true;
      while(isRunning)
      {
          if(!isPaused)
          {
            doCoolCalculations();
          }
         else
         {
            yield();
         }
      }
   }
}
```


----------



## A-Stern (21. Feb 2012)

Hilft mir nicht sehr weiter.

Ich bin noch ein absoluter Java-Noob 

Ich suche mehr nach einer Möglichkeit wie:


```
while(true)          //Jetzt nur ein Beispiel
{
    warten();   // Hier die Pause

    //Hier mein Restlicher Code
}
```

Geht das?


----------



## Michael... (21. Feb 2012)

A-Stern hat gesagt.:


> Ich suche eine Möglichkeit, mit der ich das Programm pausieren kann, bis der Anwender eine Taste drückt. (kann auch eine beliebige sein, weil ich mit dem Programm "nur" den A-Stern-Algorithmus teste.)
> 
> Also so ähnlich, wie
> 
> ...


Aktives "Warten" ist ungünstig. Was heißt "Pausieren" an einer bestimmten Stelle pausieren oder in einem beliebigen Zyklus einer Schleife pausieren?


A-Stern hat gesagt.:


> Ich brauche die Lösung so, weil ich einfach eine Gewisse Zeit brauche, um mir das anzusehen, was mir mein Computer da anzeigt.


Das interpretiere ich: Es wird etwas bestimmtes angezeigt und das Programm soll erst nach Tastendruck zur nächsten Anzeige fortfahren. Kann man dann den Prozess nicht in einzelen Teile zerlegen, die dann aktiv aus einem KeyListener heraus aufgerufen werden?


----------



## SlaterB (21. Feb 2012)

am leichtesten wäre noch System.in.read() bzw. in diese Richtung,
reagiert aber nur auf die Enter-Taste, nicht beliebige,
edit: ach ja, das Konsolenfenster muss auch aktiviert sein, auch mit Haken,

bei einer GUI hat man auch immer die Frage des Focus, schwierig,
besser wäre mit Maus und Button zu arbeiten

falls du selber weder Ahnung noch Geld investieren willst, musst du wohl Kompromisse eingehen, es gibt nicht alles


----------



## A-Stern (21. Feb 2012)

Michael... hat gesagt.:


> Das interpretiere ich: Es wird etwas bestimmtes angezeigt und das Programm soll erst nach Tastendruck zur nächsten Anzeige fortfahren. Kann man dann den Prozess nicht in einzelen Teile zerlegen, die dann aktiv aus einem KeyListener heraus aufgerufen werden?


1. Ja, das ist richtig und
2. Das wäre _theoretisch_ möglich, aber sehr unpraktisch, da ich

1. Kaum/Kein Erfahrung mit sowas habe.
2. Mein Code mittlerweile sehr lang ist.
Hier:

```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Yannick
 */

package a.star.special;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import java.util.Random;
import java.util.Vector;
 
public class AStarSpecial
{
    static private Random r = new Random();
    // Die Map
    static private Map map = new Map(20, 18);
    static private Vector<Line> lines = new Vector<Line>();
    // Fenster erstellen
    static private JFrame frame = new JFrame("A-Star-Special");
    static private Vector<Open> offen = new Vector<Open>();
    static private Vector<Closed> gesch = new Vector<Closed>();
    static private Vector<Coord> hindernisse = new Vector<Coord>();
    
    public static void main(String args[])
    {   
        int wall;
        
        for(int i = 0; i < map.get_x_size(); i++)
        {
            for(int j = 0; j < map.get_y_size(); j++)
            {
                wall = (r.nextInt(3) == 0)? 1 : 0;
                
                map.set(i, j, wall);
                
                if(wall != 0)
                {
                    hindernisse.add(new Coord(i, j));
                }
            }
        }
        
        Coord start = new Coord(r.nextInt(map.get_x_size()), r.nextInt(map.get_y_size()));
        Coord ziel = new Coord(r.nextInt(map.get_x_size()), r.nextInt(map.get_y_size()));
        
        start = new Coord(0, 0);                                            //Manuelle Festlegung
        ziel = new Coord(map.get_x_size() - 1, map.get_y_size() - 1);
        
        map.set(start.x, start.y, 2);   // Start
        map.set(ziel.x, ziel.y, 3);     // Ziel
        
        hindernisse.remove(start);
        hindernisse.remove(ziel);
        
        // Das Erzeugen des GUIs muss auf dem
        // Event-Dispatch-Thread ausgeführt
        // werden:
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
        
        Coord cur_pos = start;
        
        offen.add(new Open(start, start, 0.0, ziel));
        
        int size, j;
        Open best, cur;
        Closed geschlossen;
        
        
        do
        {
            try
            {
                Thread.sleep(3000);
            }
            catch (InterruptedException e)
            {
            }
            
            size = offen.size();
            
            j = 0;
            best = offen.get(0);
            
            for(int i = 1; i < size; i++)
            {
                cur = offen.get(i);
                
                if(cur.calc_way() < best.calc_way())
                {
                    best = cur;
                    j = i;
                }
                
                if((cur.pos.x == ziel.x) && (cur.pos.y == ziel.y))
                {
                    best = cur;
                    j = i;
                    break;
                }
            }
            
            geschlossen = offen.remove(j).toClosed();
            gesch.add(geschlossen);
            
            removeLineAt(geschlossen.pos);
            
            lines.add(new Line(
                new Color(0, 128, 0),
                    geschlossen.from.x, geschlossen.from.y, geschlossen.pos.x, geschlossen.pos.y, true
                ));
            
            cur_pos = geschlossen.pos;
            if(map.read(cur_pos) == 4)
            {
                map.set(cur_pos, 5);
            }
            
            if(map.read(cur_pos) == 3)
            {
                update(1);
                
                size = 1;
                
                break;
            }

            for(int i = 0; i < map.get_x_size(); i++)
            {
                for(j = 0; j < map.get_y_size(); j++)
                {
                    int x = i;
                    int y = j;
                    Coord pos = new Coord(x, y);

                    if(checkForWall(cur_pos, pos))
                    {
                        int tmp = map.read(x, y);

                        if((0 == tmp) || (3 == tmp))
                        {
                            offen.add(new Open(pos, cur_pos, geschlossen.calc_way(), ziel));
                            lines.add(new Line(
                                new Color(128, 255, 128),
                                    cur_pos.x, cur_pos.y, pos.x, pos.y, true
                                ));

                            if(tmp == 0)
                            {
                                map.set(pos, 4);
                            }
                        }

                        if(tmp == 4)
                        {
                            Open alt = findAtPos(pos);
                            Open neu = new Open(pos, cur_pos, geschlossen.calc_way(), ziel);

                            if(neu.calc_way() < alt.calc_way())
                            {
                                offen.remove(alt);

                                removeLineAt(pos);

                                offen.add(neu);
                                lines.add(new Line(
                                    new Color(128, 255, 128),
                                        cur_pos.x, cur_pos.y, pos.x, pos.y, true
                                    ));
                            }
                        }
                    }
                }
            }

            size = offen.size();

            update();
            
        }   while((map.read(cur_pos) != 3) && (size != 0));
        
        if(size == 0)
        {
            update(-1);
        }
        else
        {
            Closed ob = gesch.lastElement();
            
            Vector<Closed> way = new Vector<Closed>();

            while(!((ob.pos.x == start.x) && (ob.pos.y == start.y)))
            {
                way.add(ob);
                lines.add(new Line(
                    new Color(255, 20, 20),
                    ob.pos.x, ob.pos.y, ob.from.x, ob.from.y, false));

                ob = findClosedAtPos(ob.from);

                update(1);

                try
                {
                    Thread.sleep(300);
                }
                catch (InterruptedException e)
                {
                }

            }
        }
    }
 
    // Erzeugt ein Fenster, das ein PaintPanel enthält,
    // und macht das Fenster sichtbar
    private static void createAndShowGUI()
    {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        // PaintPanel erstellen und in das Fenster legen
        PaintPanel paintPanel = new PaintPanel(map, lines, offen, gesch, 0);
        paintPanel.setPreferredSize(new Dimension(map.get_x_size() * 52 + 200 + 2, map.get_y_size() * 52 + 2));
        frame.getContentPane().add(paintPanel);
 
        // Fenster zentrieren und anzeigen
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    /**
     * Aktualisiert das Fenster
     */
    
    private static void update(int i)
    {
        // PaintPanel erstellen und in das Fenster legen
        PaintPanel paintPanel = new PaintPanel(map, lines, offen, gesch, i);     
        paintPanel.setPreferredSize(new Dimension(map.get_x_size() * 52, map.get_y_size() * 52));
        frame.getContentPane().add(paintPanel);
        
        // Fenster zentrieren und anzeigen
        frame.setVisible(true);
    }
    
    private static void update()
    {
        update(0);
    }
    
    private static Open findAtPos(Coord pos)
    {
        int size = offen.size();
        
        for(int i = 0; i < size; i++)
        {
            Coord pos_offen = offen.get(i).pos;
            
            if((pos_offen.x == pos.x) && (pos_offen.y == pos.y))
            {
                return offen.get(i);
            }
        }
        
        return null;
    }
    
    private static Closed findClosedAtPos(Coord pos)
    {
        int size = gesch.size();
        
        for(int i = 0; i < size; i++)
        {
            Coord pos_gesch = gesch.get(i).pos;
            
            if((pos_gesch.x == pos.x) && (pos_gesch.y == pos.y))
            {
                return gesch.get(i);
            }
        }
        
        return null;
    }
    
    private static void removeLineAt(Coord pos)
    {
        int size = lines.size();
        
        for(int i = 0; i < size; i++)
        {
            Line line = lines.get(i);
            
            if((line.finish_x == pos.x) && (line.finish_y == pos.y))
            {
                lines.remove(line);
                
                return;
            }
        }
    }
    
    private static boolean checkForWall(Coord pos1, Coord pos2)
    {
        int size = hindernisse.size();
        
        for(int i = 0; i < size; i++)
        {
            Coord cur = hindernisse.get(i);
            
            double distance = dist(pos1, pos2, cur);
            
            
            if((distance < 1) && inRange(pos1, pos2, cur, distance))
            {
                return false;
            }
        }
        
        return true;
    }
    
    private static double modulu(double divident, double divisor)
    {
        return divident - (divisor * ((double)((int)(divident / divisor))));
    }
    
    private static double dist(Coord P, Coord Q, Coord X)
    {
        double l = X.distance(P);
        double alpha;
        
        Coord x = new Coord(X.x - P.x, X.y - P.y);
        Coord q = new Coord(Q.x - P.x, Q.y - P.y);
        
        alpha = Math.acos(((x.x * q.x) + (x.y * q.y)) / (x.distance() * q.distance()));
        
        return l * Math.sin(alpha);
    }
    
    private static boolean inRange(Coord P, Coord Q, Coord X, double dist)
    {
        double dist_1 = P.distance(Q);
        double dist_2 = P.distance(X);
        double dist_3 = X.distance(Q);
        
        dist_2 *= dist_2;       //Quadrieren
        dist_3 *= dist_3;
        dist *= dist;
        
        return dist_1 == (Math.sqrt(dist_2 - dist) + Math.sqrt(dist_3 - dist));
    }
}
```
Das ist jetzt nur dei Hauptdatei, um das ganze kurz zu halten.


----------



## bERt0r (21. Feb 2012)

Wenn du einfach nur willst, dass an der stelle wo "  do{ try {  Thread.sleep(3000);   }   catch(InterruptedException e)   {  }" steht auf eine Taste gewartet wird mach:
System.in.read();


----------



## A-Stern (21. Feb 2012)

ist ja ne GUI, aber ist auch ne Lösung...


----------



## bERt0r (21. Feb 2012)

Bei einer GUI musst du dirch für intensive Berechnungen zwangsläufig mit Threads auseinandersetzten. Das geht nicht anders.


----------



## Andi_CH (22. Feb 2012)

Also wenn Gui, dann frage ich mich, ob es denn eine Taste sein muss?
Ein Button "weiter" ist möglicherweise einfacher zu realisieren.

Bei einem GUI das ich hier habe, wird mit der Taste "Enter" genau dasselbe gemacht wie mit dem "Ok" Button:

Was genau hier passiert (hab ich nicht selbst geschrieben) kann sicher jemand genauer erklären.
(Ob so etwas auch ohne Bindung an einen Button möglich ist, würde mich auch interessieren)


```
mButtonOK.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
			KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
			ACTION_ENTER_PRESSED
	);
	mButtonOK.getActionMap().put(ACTION_ENTER_PRESSED,
			new AbstractAction(ACTION_ENTER_PRESSED) {
		public void actionPerformed(ActionEvent evt) {
			okButtonAction();
		}
	});
```


----------

