Applet - während Thread.sleep eine Aktion ausführen

N302OO7

Mitglied
Sers,

in Java gibt ja die Funktion:

Code:
try {
Thread.sleep(1000);
} catch (InterruptedException e){}

Diese nutze ich auch in meinem Applet. Wie kann ich das realisieren, dass während des schalfens, eine Text angezeigt wird. Also ich lege meinen Thread z.B. für 5sec auf sleep. Während den 5 sec soll dann ein Text mit
Code:
g2.drawString("Sleep");
ausgegeben werden.

Wie mache ich das Geht das überhaupt mit sleep

greetz
 
Während nen Thread schläft, kann er nix machen. Für eine "aktive" Aktion müsstest du einen zweiten Thread starten. Da es sich dabei aber scheinbar nur um eine Art Statusinfo handelt, lässt du den Text erst zeichen und dann kann der Thread sich aufs Ohr haun. Wenn du das an mehreren Stellen benutzt, dann bietet sich an eine entsprechende Methode zu deklarieren.
 
d.h. konkret

mache ich das dann so:
also ich mache in meine paint methode eine if Abfrage, wenn der eine Spieler einen Punkt erzielt hat, also player1 ++, dann soll er folgendes machen:

Code:
try {
g.drawString("Punkt Spieler1")
Thread.sleep(1000);
} catch (InterruptedException e){}

fals du dass meint, das funnktioniert nicht.


greetz
 
Hi,
du hast hinter deiner Zeichenanweisung an ";" vergessen. Ich nehme mal an, dass g ein Object von Graphics ist, oder? Graphics besitzt aber keine Methode drawString(String s), sondern nur drawString(String s, int x, int y).
Desweiteren wäre es sinnvoll, wenn du uns mal sagen würdest, was nicht funktioniert, denn nach oben beschriebenen Änderngen hat es bei mir funktioniert.

Schönen Abend noch,
DosCoder
 
Die Änderungen werden sehr warscheinlich erst wenn er nach der Methodenabarbeitung Zeit hat gezeichnet. Zumindest unter Swing, unter AWT das ein wenig "besser", so kann man öfters (aber auch nicht immer) direkt wärend einer Methodenabarbeitung repaint aufrufen was manchmal auch zum direkten neu zeichnen verleitet. Würde es aber niemals drauf anlegen.
Ein neuer Thread ist meiner Erfahrung nach bei AWT nicht oft notwendig. Bei Swing zwingend, wenn Änderungen wärend eines Methodenaufrufes stattfinden sollen.

Deinen Source finde ich aber verdammt komisch.

Einerseits, wegen der if, ich würde eine Klasse die von Thread erbt schreiben, die informiert wird wenn der Player einen Punkt macht, der Thread, in dem ne Endlosschleife rennt pausiert und setzt die boolean wieder zurück. Durch eine Methode die die Graphics-Instanz übergeben wird in der Thread-Klasseninstanz würde ich ihm falls es nötig ist den Schriftzug zeichnen lassen.
So wird die paint auf jeden Fall auch schlanker und imho übersichtlicher.

Und das 2. wäre, dass ich es für Blödsinn halte die paint zu pausieren.
Dann sieht man ja nur jede Sekunde ne Änderung. Wenns hoch kommt.

(Über Rechtschreibung und Programmieren sage ich mal nichts.)
 
@DosCoder:

Ja das habe ich ein bisschen falsch kopiert:

Code:
try{
        g.drawString("Spieler1", 100,250);
         Thread.sleep(1000);
       }
       catch (InterruptedException e)
       {
       }

Was genau mein Problem ist, das Programm hällt zwar kurz an (wie es auch sol), aber man sieht keinen Text :P
 
Warum machst du es nicht so, wie ich es vorgeschlagen habe?
Hab ich zwar jetzt nur schnell runtergetippt, aber funktioniert soweit ich gesehen habe einwandfrei.

Java:
package core;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class Main extends JFrame implements KeyListener
{
	private static final long serialVersionUID = 1L;

	/**
	 * Test-Class.
	 * A Key-Press emulating a Point of "Player 0".
	 */
	
	private static PlayerPoint[] playerPoint;
	
	public Main()
	{
		super("Test");
		
		playerPoint = new PlayerPoint[2];
		playerPoint[0] = new PlayerPoint((byte)0, this);
		playerPoint[1] = new PlayerPoint((byte)1, this);
		
		this.addKeyListener(this);
		this.setSize(640, 480);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setResizable(false);
		this.setVisible(true);
	}
	public void paint(Graphics g)
	{
		g.setColor(this.getBackground());
		g.fillRect(0, 0, this.getWidth(), this.getHeight());
		g.setColor(Color.black);
		
		playerPoint[0].draw(g);
		playerPoint[1].draw(g);
	}
	public void keyPressed(KeyEvent e)
	{
		playerPoint[0].makePoint();
	}
	public void keyReleased(KeyEvent e) {}
	public void keyTyped(KeyEvent e) {}
	
	public static void main(String[] args)
	{
		new Main();
	}
}
/////////////////////////////////////////////////////////////////
package core;

import java.awt.Graphics;
import java.awt.Point;

import javax.swing.JFrame;

public class PlayerPoint extends Thread
{
	private static final Point[] TEXT_COORDINATES = {
		new Point(100, 100),
		new Point(200, 200)
	};
	private static final String[] TEXT_STRINGS = {
		"Player 0: Point is Make",
		"Player 1: Point is Make"
	};
	private static final long DELAY_TIME = 50L;
	private static final long POINT_WATCH_TIME = 1000L;
	
	private byte id;
	private boolean pointIsMake;
	private boolean threadRun;
	private JFrame jframe;
	
	public PlayerPoint(byte id, JFrame jframe)
	{
		super("PlayerPoint");
		this.id = id;
		threadRun = true;
		this.jframe = jframe;
		this.start();
	}
	public void run()
	{
		while(threadRun)
		{
			try
			{
				if(pointIsMake)
				{
					Thread.sleep(POINT_WATCH_TIME);
					pointIsMake = false;
					jframe.repaint();
				}
				Thread.sleep(DELAY_TIME);
			}
			catch(InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}
	public void draw(Graphics g)
	{
		if(pointIsMake)
			g.drawString(TEXT_STRINGS[id], (int)TEXT_COORDINATES[id].getX(),
					(int)TEXT_COORDINATES[id].getY());
	}
	public void makePoint()
	{
		pointIsMake = true;
		jframe.repaint();
	}
	public void breakThread()
	{
		threadRun = false;
	}
}

Du könntest wohl direkt in der makePoint() den Thread immer neu starten, dann spaarst du dir die "Endlos"schleife, und die Warte-Zeit dazwischen. Damit hat die CPU mehr Zeit für andere Dinge, und du bist sofort am Anfang des Threads. Wie das bei größeren Projekten wirkt weiß ich aber nicht, da ich keine Ahnung habe was Thread.start() genaugenommen macht.
 
Zuletzt bearbeitet:
Weil ich dich überhaupt nicht verstanden habe, und in deinem Quellcode verstehe ich noch weniger :P Ich hab ein Applet und zwar von dem Spiel Pong, und immer wenn ein Spieler einen Punkt gemacht hat, hällt der ganze Thread kurz an, dann wird der Ball wieder an die Anfangskoordinaten gesetzt und der Thread läuft ganz normal weiter. Nun hätte ich gerne, dass wenn ein Spieler einen Punkt erzielt hat, also wenn i-wo in der run Methode spieler1Punkt++ bzw. spieler2Punkt++ auftaucht, der Thread kurz anhällt und man während dessen den Text "Spierl1 bzw. Spieler2 hat einen Punkt erzielt" sieht. Also ich habe ich in die paint (Graphics g) Methode eine if Abfrage gemacht, wenn spierl1Punkt++ hat, dann die sleep Methode, das funktioniert allerdings nicht.
 
Ach so, sorry. Wenn du eine Zeile nicht verstehst frag ruhig.

Aber ich nehme an, du hast mal die Main-Klasse, die von einen JFrame erbt und in der ein KeyListener registriert ist. In der wird die Paint überschrieben.
Dann gibts noch die Player die vielleicht eigene Klasse haben oder auch direkt einfach per int's darin stehen, ist ja bei so einen kleinen Projekt auch imho egal.
Und dann den Ball. Dieser Bewegt sich warscheinlich in einen eigenen Thread. Würde er das nicht tun, würde das neu zeichnen (mehr oder weniger, kenne mich intern nicht aus) im selben Thread ablaufen. sleep blockiert aber den momentanen Thread, wodurch nicht neu gezeichnet werden kann. Das heißt der Thread würde entweder die Position neu setzen, oder warten, es würde aber keine Zeit bleiben.
Falls der Ball jetzt rausfliegt würde ich einfach eine boolean setzen, neu zeichnen, den Thread des Balles schlafen legen und danach erst den Ball zurücksetzen.

Die Paint zu blockieren würde eventuell beim einfachen überschreiben noch funktionieren. Sofern du aber einen Doppelbuffer schreibst (es wird ein Bild von der Größe des JFrames erstellt, die Graphics womit man darauf schreiben/zeichnen kann genommen und mit dieser die Paint aufgerufen, und am Ende einfach das Bild im Graphicspeicher kopiert) oder sogar Page Flipping verwendet (geht mit der Klasse BufferStrategie, statt dass das Bild kopiert wird wird einfach eine Art "Umleitung" im VRam geschrieben) muss er auf jeden Fall die Methode in einen durcharbeiten.

Und die paint sollte sowieso so schnell wie möglich abgearbeitet werden, da es (meistens) die größte Arbeit ist.
 

Neue Beiträge

Zurück