0

我正在制作一个时钟小程序,我几乎完成了,但我还需要做一件事。每次秒针移动时,我都想让时钟“滴答”,但我不知道在哪里放置 *tick* 声音的代码。这是小程序的代码:

import java.applet.*;
import java.awt.*;
import java.util.*;
import java.net.URL;
import java.text.*;

public class ClockApplet extends Applet implements Runnable {
    Ellipse2D line1 = new Ellipse2D.Float(100, 150, 200, 200);

    int width, height;
    Thread t = null;
    boolean threadSuspended;
    int hours = 0, minutes = 0, seconds = 0;
    String timeString = "";

    public void init() {
        width = getSize().width;
        height = getSize().height;
        setBackground(Color.white);
    }

    public void start() {
        if (t == null) {
            t = new Thread(this);
            t.setPriority(Thread.MIN_PRIORITY);
            threadSuspended = false;
            t.start();
        } else {
            if (threadSuspended) {
                threadSuspended = false;
                synchronized (this) {
                    notify();
                }
            }
        }
    }

    public void stop() {
        threadSuspended = true;
    }

    public void run() {
        try {
            while (true) {

                // Here's where the thread does some work:

                Calendar cal = Calendar.getInstance();
                hours = cal.get(Calendar.HOUR_OF_DAY);
                if (hours > 12)
                    hours -= 12;
                minutes = cal.get(Calendar.MINUTE);
                seconds = cal.get(Calendar.SECOND);

                SimpleDateFormat formatter = new SimpleDateFormat("hh:mm:ss",
                        Locale.getDefault());
                Date date = cal.getTime();
                timeString = formatter.format(date);

                // Now the thread checks to see if it should suspend itself
                if (threadSuspended) {
                    synchronized (this) {
                        while (threadSuspended) {
                            wait();
                        }
                    }
                }
                repaint();

                t.sleep(1000); // interval given in milliseconds

            }
        } catch (InterruptedException e) {
        }
    }

    void drawHand(double angle, int radius, Graphics g) {
        angle -= 0.5 * Math.PI;
        int x = (int) (radius * Math.cos(angle));
        int y = (int) (radius * Math.sin(angle));
        g.drawLine(width / 2, height / 2, width / 2 + x, height / 2 + y);
    }

    void drawWedge(double angle, int radius, Graphics g) {
        angle -= 0.5 * Math.PI;
        int x = (int) (radius * Math.cos(angle));
        int y = (int) (radius * Math.sin(angle));
        angle += 2 * Math.PI / 3;
        int x2 = (int) (5 * Math.cos(angle));
        int y2 = (int) (5 * Math.sin(angle));
        angle += 2 * Math.PI / 3;
        int x3 = (int) (5 * Math.cos(angle));
        int y3 = (int) (5 * Math.sin(angle));
        g.drawLine(width / 2 + x2, height / 2 + y2, width / 2 + x, height / 2
                + y);
        g.drawLine(width / 2 + x3, height / 2 + y3, width / 2 + x, height / 2
                + y);
        g.drawLine(width / 2 + x2, height / 2 + y2, width / 2 + x3, height / 2
                + y3);
    }

    void drawCircle(Graphics g) {
        g.drawOval(0, 0, 200, 200);
    }

    public void paint(Graphics g) {
        g.setColor(Color.black);
        drawWedge(2 * Math.PI * hours / 12, width / 5, g);
        drawWedge(2 * Math.PI * minutes / 60, width / 3, g);
        g.setColor(Color.red);
        drawHand(2 * Math.PI * seconds / 60, width / 2, g);
        g.setColor(Color.black);
        g.drawString(timeString + " ET", 10, height - 10);
        g.setFont(new Font("Arial", Font.PLAIN, 30));
        g.drawString("12", 85, 30);
        g.drawString("1", 140, 40);
        g.drawString("2", 170, 70);
        g.drawString("3", 180, 110);
        g.drawString("4", 170, 150);
        g.drawString("5", 140, 180);
        g.drawString("6", 92, 195);
        g.drawString("7", 46, 180);
        g.drawString("8", 16, 150);
        g.drawString("9", 5, 110);
        g.drawString("10", 16, 70);
        g.drawString("11", 46, 40);
        drawCircle(g);
    }

}

这里是 *tick* 声音的代码:

try {
    Clip tick = AudioSystem.getClip();
    URL clipURL = new URL("file://C:/users/owner/desktop/Tick.wav");
    AudioInputStream ais = AudioSystem.getAudioInputStream(clipURL);
    tick.open(ais);
    tick.start();
} catch (Exception e) {
    System.out.println("Error playing sound!");
    }

我只需要知道将声音代码放入小程序代码的位置。我尝试了各种地方,但似乎没有一个工作。

4

1 回答 1

0

这个答案适用于 JApplets 或应用程序。(我自己没有使用过小程序。)

(1) 我会让勾选 Clip 成为实例化顶级类时加载的实例变量。在 JApplet 的上下文中,这将是在 init() 方法期间。我是应用程序的上下文,这可能是通过使时钟图形显示 JComponent 或 JPanel,并在实例化图形容器时实例化 Clip。

(将 Clip 重复加载到内存中是没有意义的!Clip 的重点是执行一次,然后在您希望重用它时重置它。重复加载的 Clip 比 SourceDataLine 需要更长的时间才能开始播放,因为在开始播放之前必须加载整个声音文件。)

(2) 我将创建一个新线程来运行刻度剪辑,方法是将位置重置为剪辑的开头(第 0 帧)然后播放它。

(3) 我会从重绘图形的 while 循环中重复启动这个线程。大概线程一旦完成执行就会死掉。如果咔哒声超过一秒,可能会出现错误。

我并不是说这肯定是“正确的”。通过设置为 1000 毫秒间隔的 util.Timer 启动图形和声音线程的更新可能是有意义的。

于 2013-05-17T06:12:09.850 回答