Ich   Entwicklung   Lösungen Apache PHP mySQL  
 

Ein Thread-gesteuertes Java-Applet

Das folgende Applet blendet Nachrichtentexte ein und aus und öffnet dazugehörige URLs (soweit vom Nutzer und Browser erlaubt).

Quelltext des Applets

Im Folgenden wird der Quelltext des Applets, in gekürzter Form, beschrieben:

public class NewsTicker extends Applet implements Runnable, MouseListener {

Die Klasse NewsTicker ist ein Applet, das Runnable implementiert, um als Thread ausgeführt werden zu können, und MouseListener, um auf Mausereignisse durch den Benutzer zu reagieren.

    public static final Color DEFAULT_BG_COLOR = Color.WHITE;
    public static final Color DEFAULT_FG_COLOR = Color.BLACK;
    public static final int DEFAULT_SPEED = 5;
    public static final String DEFAULT_TEXT = "Created by Jens Becker";
    public static final String DEFAULT_URL = "http://www.intermitto.net/";

    public static final Font font = new Font("Verdana", Font.BOLD, 12);

Zunächst werden einige Standardwerte festgelegt. Dem Applet werden als Parameter (in HTML) Hinter- und Vordergrundfarbe, Geschwindigkeit und Nachrichten inklusive derer URLs übergeben. Für nicht übergebene Parameter werden weiter unten diese Standardwerte genutzt.

    private int speed;
    private ArrayList news;
    private Color bgColor;
    private Color fgColor;

    private int rDiff;
    private int gDiff;
    private int bDiff;

    private double currentColorFactor; // 0..1
    private double step = 0.025;
    private int currentNewsIndex;
    private boolean ascending;

    private Thread runnable;

speed gibt die Geschwindigkeit an, mit der Nachrichten ein- und ausgeblendet werden. Der Wert sollte zwischen 1 und 10 liegen, wie weiter unten ersichtlich. Die weiteren Attribute dienen dem Ein- und Ausblenden.

    public void init() {
        initParams();
        setBackground(bgColor);
        this.currentNewsIndex = 0;
        this.currentColorFactor = 0;
        this.ascending = true;
        this.rDiff = fgColor.getRed() - bgColor.getRed();
        this.gDiff = fgColor.getGreen() - bgColor.getGreen();
        this.bDiff = fgColor.getBlue() - bgColor.getBlue();
        this.addMouseListener(this);
    }

init wird vom Browser aufgerufen, um das Applet zu initialisieren. In initParams (siehe unten) werden die übergebenen Parameter eingelesen. Nachdem die Hintergrundfarbe gesetzt wurde, werden die für das Ein-/Ausblenden nötigen Attribute gesetzt. Die Attribute xDiff werden mit den Differenzen zwischen den Vorder- und Hintergrundfarben belegt. Schließlich wird festgelegt, dass auf Mausereignisse gehört werden soll.

    public void mouseClicked(MouseEvent e) {
        Object[] obj = (Object[])news.get(currentNewsIndex);
        getAppletContext().showDocument((URL)obj[1], "news");
    }

    public void mouseEntered(MouseEvent e) {
        getAppletContext().showStatus("NewsTicker by Jens Becker jb@intermitto.net");
        this.setCursor(new Cursor(Cursor.HAND_CURSOR));
    }

    public void mouseExited(MouseEvent e) {
        getAppletContext().showStatus("");
        this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    }

    public void mousePressed(MouseEvent e) {
        getAppletContext().showStatus("Mausklick öffnet Newsdokument");
    }

    public void mouseReleased(MouseEvent e) {
        mouseEntered(e);
    }

Nun folgen die Schnittstellen-Operationen des MouseListener. Bei Mausklick soll der aktuelle News-URL geöffnet werden. Hier könnte vorsichtshalber noch ein null-URL abgefangen werden. Bei Betreten und Verlassen des Applets mit der Maus werden Statustext und Mauszeiger geändert.

    public void start() {
        if(this.runnable == null) {
            this.runnable = new Thread(this);
            this.runnable.start();
        }
    }

    public void stop() {
        if(this.runnable != null) {
            this.runnable.interrupt();
        }
    }

start wird vom Browser aufgerufen, wenn das Applet gestartet wird. Wenn noch kein Thread läuft, wird einer initialisiert und gestartet. Dadurch wird run aufgerufen (siehe unten). stop beendet den Thread.

    public void paint(Graphics g) {}

    public void update(Graphics g) {
        FontMetrics fontMetrics = getFontMetrics(font);
        g.setFont(this.font);

        int rCurr = bgColor.getRed() + (int)(currentColorFactor * rDiff);
        int gCurr = bgColor.getGreen() + (int)(currentColorFactor * gDiff);
        int bCurr = bgColor.getBlue() + (int)(currentColorFactor * bDiff);
        g.setColor(new Color(rCurr, gCurr, bCurr));

        Object[] obj = (Object[])news.get(currentNewsIndex);
        String currText = (String)obj[0];
        g.drawString(currText, (getWidth() - fontMetrics.stringWidth(currText)) / 2, (getHeight() + fontMetrics.getAscent()) / 2);
    }

paint und update wurden überschrieben, um im Applet den Nachrichtentext darzustellen. Nach Setzen von font und color wird der Nachrichtentext horizontal und vertikal zentriert gezeichnet.

    public void run() {
        while(true) {
            try {
                actualize();
                repaint();
                Thread.sleep(75 - 5 * speed);
            } catch(InterruptedException e) {

            }
        }
    }

Dies ist die Startoperation des Threads. Zunächst wird actualize aufgerufen, um die in update benötigten Attribute abhängig von der verstrichenen Zeit neu zu berechnen, dann wird über repaint die Operation update aufgerufen. Schließlich schläft die Anwendung einige Millisekunden, bevor wieder neu gezeichnet wird.

    private void actualize() {
        currentColorFactor = (ascending ? currentColorFactor + step : currentColorFactor - step);
        if(currentColorFactor <= 0 || currentColorFactor >= 1) {
            ascending = !ascending;
            if(ascending && (++currentNewsIndex >= news.size())) currentNewsIndex = 0;
            if(!ascending) {
                try {
                    Thread.sleep(40 - 2 * speed);
                } catch(InterruptedException e) {

                }
            }
        }
    }

Zunächst wird der currentColorFactor schrittweise erhöht/gesenkt - abhängig davon, ob der Text gerade eingeblendet (ascending) wird oder ausgeblendet.
Falls der Faktor 0 bzw. 1 erreicht hat, wird die Blend-Richtung umgekehrt. Falls gerade ausgeblendet wurde und nun eingeblendet werden soll, wird currentNewsIndex auf die folgenden Nachrichten gesetzt. Falls das Ende der Nachrichtenliste erreicht ist, springt der Index wieder zur ersten Nachricht. Falls gerade ein- und nun ausgeblendet wird, schläft der Thread einige Millisekunden und zeigt solange den Nachrichtentext an - damit nach dem vollständigen Einblenden nicht sofort wieder das Ausblenden folgt.

    private void initParams() {
        String param, url;
        int rParam, bParam, gParam, newsIndex = 0;
        news = new ArrayList();

        param = getParameter("bgcolor");
        if(param == null || param.length() != 6) {
            bgColor = DEFAULT_BG_COLOR;
        } else {
            try {
                rParam = Integer.parseInt(param.substring(0, 2), 16);
                gParam = Integer.parseInt(param.substring(2, 4), 16);
                bParam = Integer.parseInt(param.substring(4), 16);
                bgColor = new Color(rParam, gParam, bParam);
            } catch(Exception e) {
                bgColor = DEFAULT_BG_COLOR;
            }
        }

        param = getParameter("fgcolor");
        if(param == null || param.length() != 6) {
            fgColor = DEFAULT_FG_COLOR;
        } else {
            try {
                rParam = Integer.parseInt(param.substring(0, 2), 16);
                gParam = Integer.parseInt(param.substring(2, 4), 16);
                bParam = Integer.parseInt(param.substring(4), 16);
                fgColor = new Color(rParam, gParam, bParam);
            } catch(Exception e) {
                fgColor = DEFAULT_FG_COLOR;
            }
        }

        param = getParameter("speed");
        if(param == null) {
            speed = DEFAULT_SPEED;
        } else {
            try {
                speed = Integer.parseInt(param);
                if(speed < 1) {
                    speed = 1;
                } else if(speed > 10) {
                    speed = 10;
                }
            } catch(Exception e) {
                speed = DEFAULT_SPEED;
            }
        }

        while(true) {
            param = getParameter("text" + newsIndex);
            if(param == null) {
                if(newsIndex == 0) {
                    try {
                        news.add(new Object[] {DEFAULT_TEXT, new URL(DEFAULT_URL)});
                    } catch(MalformedURLException e) {
                        news.add(new Object[] {DEFAULT_TEXT, null});
                    }
                }
                break;
            }
            url = getParameter("url" + newsIndex);
            if(url == null) {
                news.add(new Object[] {param, null});
            } else {
                try {
                    news.add(new Object[] {param, new URL(url)});
                } catch(MalformedURLException e) {
                    news.add(new Object[] {param, null});
                }
            }
            ++newsIndex;
        }
    }
}

In initParams werden schließlich die durch HTML übergebenen Parameter eingelesen. Falls nötig werden Standardwerte gesetzt.

Aufruf

Der folgende Code muss in ein HTML-Dokument eingebaut werden:


<applet code="NewsTicker" width="400" height="50">
     <param name="bgcolor" value="000000" />
     <param name="fgcolor" value="ffffff" />
     <param name="speed" value="5" />
     <param name="text0" value="www.intermitto.net" />
     <param name="url0" value="http://www.intermitto.net/" />
     <param name="text1" value="Apache Tutorial" />
     <param name="url1" value="http://www.intermitto.net/apache/" />
     <param name="text2" value="PHP Tutorial" />
     <param name="url2" value="http://www.intermitto.net/php/" />
     <param name="text3" value="und vieles mehr..." />
     <param name="url3" value="http://www.intermitto.net/" />
</applet>

Es können weitere Nachrichtentexte über Parameter text4 bzw. url4 usw. übergeben werden.

URL: www.intermitto.net/loesungen/artikel/appletthread/
© 2004-05 Jens Becker - intermitto.net v5.1
Letzte Änderung: 23.08.2005

Home - Kontaktformular - Downloads - Suche und Sitemap - Impressum
Entwicklung - Problemlösungen - Tutorials: Apache PHP mySQL

user  pass