Splash Screen

Hi,
probier ich grad mal nicht aus. Aber kurz nach meiner Frage habe ich etwas bemerkt in dem ersten Code von Dir:

Code:
	class ExitSplashTask extends TimerTask {

		private JFrame frm;

		public ExitSplashTask(JFrame frm) {
			this.frm = frm;
		}
		/* (non-Javadoc)
		 * @see java.util.TimerTask#run()
		 */
		public void run() {
			// TODO Auto-generated method stub
			frm.setVisible(false);
			frm.dispose();
			/* 
			 * Dieser Aufruf beendet hier die VM!
			 * Hier würde also normalerweise entweder die Klasse des Hauptprogramms
			 * 
			 */
			System.exit(0);
		}

	}

Hätte ich verstanden bzw. sorgsam gelesen, was da steht, kann man problemlos an Stelle des System.exit(0); einen eigenen Frame konstruieren und aufrufen. ;)
So geht es erst einmal. Interessant wäre die Frage nach verschiedenen SplashScreens
Und mich würde interessieren, warum das System.exit(0); erst aufgerufen wird, wenn die Zeit abgelaufen ist. Erklär mal. :)
 
*Ditsch*
Warum ist die Banane krum? Weil sie krumm ist. ;-P
Also noch einmal:
Warum wird die run()-Methode erst aufgerufen, wenn die Zeit (=5 Sekunden in dem Beispiel) abgelaufen ist?
 
Hallo!

Code:
		/* Hier wird einer neuer Timer instanziert ... gleichzeitig wird "intern"
		 * ein neuer Thread gestartet der für die Ausführung zukünftiger TimerTasks 
		 * bzw. genauer gesagt deren run() Methode zuständig ist. Zu diesem Zweck überprüft  
		 * dieser Thread immer die interne TaskQueue nach TimerTasks die ausgeführt 
		 * werden wollen und wartet natürlich bei einer leeren TaskQueue.
		 * Findet der Thread einen TimerTask wartet er die im TimerTask angegebene Zeit ab
		 * und ruft dann die dort definierte run() Methode auf.
		 */
		Timer timer = new Timer();
		//Hier wird eben ein solcher TimerTask erzeugt und in die interne TimerQueue aufgenommen
		timer.schedule(new TimerTask(){
			public void run() {
				dispose();
			}},l);
		//Siehe dazu sources von java.util.Timer, java.util.TimerTask, java.util.TaskQueue, java.util.TimerThread und ff

M.a.W.:
Weil die run() Methode des TimerTasks erst aufgerufen wird wenn die 5 Sekunden um sind. ;-)

Gruß Tom
 
Alternatives starten der Hauptanwendung mittels Reflection...:

Code:
/*
 * Created on 21.10.2004
 */
package de.tutorials;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

/**
 * @author Darimont
 *  
 */
public class SplashScreen extends JFrame {

    private static final long serialVersionUID = -8617628157371474745L;

    BufferedImage image;

    int w, h;

public SplashScreen(final String file, final long ms, final Method target) {
        super();
        setUndecorated(true);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        try {
            image = ImageIO.read(new File(file));
        } catch (IOException e) {
            e.printStackTrace();
        }
        w = image.getWidth();
        h =image.getHeight();
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(w,h);
        setLocation((d.width - w)/2,(d.height-h)/2);
        
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                try {
                    dispose();
                    image = null;
                    target.invoke(null, new Object[1]);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }, ms);
        
        setVisible(true);
    }    public void paint(Graphics g) {
        super.paint(g);
        g.drawImage(image, 0, 0, this);
    }

    public static void main(String[] args) {
        try {
            //Datei energy.jpg als Bildanzeigen,
            // 5000ms -> 5s warten
            // main-Methode der Klasse de.tutorials.Main ausführen...
            new SplashScreen("C:/energy.jpg", 5000L, Class.forName(
                    "de.tutorials.Main").getMethod("main",
                    new Class[] { String[].class }));
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Gruß Tom
 
Hallo,
habe eben durch Zufall diesen Thread gefunden und auch gleich den Code für einen pseudotransparenten Splashscreen ausprobiert. Allerdings ist mir aufgefallen, dass das Bild welches übergeben wird in der rechten unteren Ecke des Rechtecks plaziert wird, welches den Screenshot des Desktops beinhaltet.
Starte ich (oder ein User) also ein Programm welches einen Splashscreen zaubert und minimiere dann ein dahinter liegendes Programm, so tritt folgender Effekt auf.
Liegt z.b. auf dem Desktop eine Verknüpfung zum Programm und man öffnet darüber das Programm, wird der Splashscreen ja sofort fokusiert wodurch dann, wenn die Verknüpfung ungünstig liegt, ein Teil des Verknüpfungsicons hell und der andere Dunkel ist.
Wie kann ich das Feld welches den Screenshot beinhaltet verkleinern ? Jegliche Versuche meinerseits scheiterten, weil ich dann mein Splashbild aus dem sichtbaren Bereich geschoben habe oder aber der Splash nur in einer Auflösung wirklich zentriert war.

mfg TheYak :)

*btw.* erster Post hier im Forum :D
 
Hallo!

Also dieser Splashscreen ist ja gerade deshalb transparent, weil vor dem Anzeigen ein Screenshot vom "Desktop" gemacht und das eigentliche Bild darauf gezeichnet wird. Dies erweckt dann den "Anschein" eines Tansaprenten Splashscreens. Wenn du in der zwischen Zeit natürlich den Hintergrund veränderst während das Splash-Fenster im Vordergrund wandelt kommt es zu dem von dir beobachteten Effekt.

Verändern kannst du den Gecaptured-ten Desktop Bereich mittels:
Code:
Rectangle rect = new Rectangle(frmX, frmY, newW, newH);
			capture = rob.createScreenCapture(rect);

Die Anmerkungen beziehen sich übrigens auf Post Nr.: 3

*btw.* erster Post hier im Forum
Willkommen an Board ;)

Gruß Tom
 
Hallo,
erstmal ein herzliches Dankeschön für die nette Begrüßung. :)

Wenn ich das richtig verstehe geben doch frmX und frmY die linke obere Ecke des "Screenshots" an und newW und newH die Ausmaße des Screenshots.
Nun schaffe ich es allerdings nicht, den Screenshotbereich auf folgende Größe zu reduzieren: *klick*. Dadurch würde es optisch schöner aussiehen wenn man ein dahinterliegendes Fenster minimieren würde.
Ändere ich nun die o.g. Variablen so schiebe ich das Fenster entweder aus der Zentrierung in der Mitte des Bildschirmes oder aber mein Splashbild verschwindet oder ist nur zum Teil sichtbar.
Es kann allerdings auch sein das ich gerade auf dem Schlauch stehe, weil ich seit 3 Stunden versuche das Fenster zu verkleinern.

mfg TheYak :)
 
Ok,
habs doch noch hinbekommen. Musste marginwidth und height verändern sowie einige andere variablen :D

gruß TheYak
 
Hallo Tom,

erstmal danke für deinen netten Post mit dem "CoolSplash"!
Ich habe versucht das ganze ein wenig weiterzuspinnen und möchte mir jetzt eine kleine Anwendung zusammenbasteln, die mit dieser Technik ein transparentes Fenster vortäuscht.

Ich habe mir also ein transparentes Bild erstellt, die Methode initBackgroundImage (entspricht im wesentlichen dem Konstruktor aus deinem Bsp.-code) aufgerufen und somit mein "transparentes" Hintergrundbild gesetzt:

Code:
this.getContentPane().setLayout(null); 
bgImage = new File("Test.png"); 
initBackgroundImage(bgImage,600,600);

Funktioniert soweit alles wunderbar, aber jetzt muss ich, wenn ich das Fenster verschiebe, minimiere, etc. das Fenster ja wieder neu zeichnen, D.h. ich muss also wieder die Methode initBackgroundImage(...) aufrufen um den "transparenten" Hintergrund zu refreshen. Ich dachte mir ... kein Problem ... in der paint-Methode aufrufen und gut ist:

Code:
public void paint(Graphics g) {
       initBackgroundImage(...);	
       if (picture != null && capture != null) {
			capture.getGraphics().drawImage(picture,
					0 + defaultScreenWidthMargin / 2,
					0 + defaultScreenHeightMargin / 2, this);
			g.drawImage(capture, 0, 0, this);
		}
	}

Das Problem dabei ist, dass ich jetzt keinen Screenshot mehr vom Desktopbereich unterhalb von meinem Fenster machen kann, sondern der Bereich, welcher transparent dargestellt werden sollte auf einmal nur als grau erscheint (mein Fenster erscheint im Screenshot also grau)!
Weiss jemand eine Lösung wie ich dieses Problem angehen kann?

Schonmal vielen Dank ...
Grüssle Jens
 
Zurück