Java swing实现支持录音等功能的钢琴程序

如何实现Java Swing支持录音等功能的钢琴程序?

  1. 导入所需库文件

实现这个功能的Java库有很多,我们可以使用Java Sound API、Java Media Framework、JLGui和JLayer。为了方便起见,我们在这里使用Java Sound API来实现这个功能。我们需要导入下面的库文件:

<dependency>
    <groupId>javax.sound</groupId>
    <artifactId>javax.sound.sampled</artifactId>
    <version>1.0.3</version>
</dependency>
  1. 创建GUI

创建Java Swing GUI界面,以及添加相应的组件,例如钢琴键和录音按钮等。

示例代码:

// 导入Swing库
import javax.swing.*;

public class PianoProgram extends JFrame {

    // 定义录音按钮
    private JButton recordButton;

    public PianoProgram() {
        // 设置标题
        super("Java Swing Piano Program");

        // 创建录音按钮,并添加点击事件监听器
        recordButton = new JButton("Record");
        recordButton.addActionListener(new RecordButtonListener());

        // 把钢琴键和录音按钮添加到界面上
        getContentPane().add(PianoKeysPanel.createPanel());
        getContentPane().add(recordButton);

        // 设置布局管理器
        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));

        // 设置窗口大小
        setSize(500, 300);

        // 设置关闭窗口时的行为
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 设置窗口可见
        setVisible(true);
    }

    // 录音按钮的事件监听器
    private class RecordButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO: 开始录音
        }
    }

    public static void main(String[] args) {
        new PianoProgram();
    }

}
  1. 配置录音

现在,我们需要在“Record”按钮的事件监听器中添加录音的代码。首先,我们需要找到“TargetDataLine”和“AudioFormat”:

// 查找支持录音的MixerDevice,初始化AudioFormat
Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
for (Mixer.Info info : mixerInfo) {
    Mixer mixer = AudioSystem.getMixer(info);
    Line.Info[] lineInfos = mixer.getTargetLineInfo();
    for (Line.Info lineInfo : lineInfos) {
        Line line = null;
        boolean opened = true;
        try {
            line = mixer.getLine(lineInfo);
            opened = line.isOpen() || line instanceof Clip;
            if (!opened) {
                line.open();
            }
            AudioFormat[] formats = line.getFormats();
            for (AudioFormat format : formats) {
                if (format.getSampleSizeInBits() == 16
                    && format.getChannels() == 1
                    && format.getEncoding() == AudioFormat.Encoding.PCM_SIGNED) {
                        // 找到支持的目标格式
                        AudioFormat dataFormat = format;
                        TargetDataLine targetDataLine;
                        targetDataLine = (TargetDataLine) mixer.getLine(
                            new DataLine.Info(TargetDataLine.class, dataFormat));
                    }
            }
        } catch (LineUnavailableException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // Ignore
        } finally {
            if (line != null && !opened) {
                line.close();
            }
        }
    }
}
  1. 开始录音

现在,我们已经找到了“TargetDataLine”和“AudioFormat”,接下来我们可以编写代码开始录音。我们可以使用线程来执行录音。

// 开始录音
RecordThread recordThread = new RecordThread(targetDataLine, dataFormat);
recordThread.start();

示例代码:

private void startRecording() {
    try {
        // 查找支持录音的MixerDevice,初始化AudioFormat
        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
        for (Mixer.Info info : mixerInfo) {
            Mixer mixer = AudioSystem.getMixer(info);
            Line.Info[] lineInfos = mixer.getTargetLineInfo();
            for (Line.Info lineInfo : lineInfos) {
                Line line = null;
                boolean opened = true;
                try {
                    line = mixer.getLine(lineInfo);
                    opened = line.isOpen() || line instanceof Clip;
                    if (!opened) {
                        line.open();
                    }
                    AudioFormat[] formats = line.getFormats();
                    for (AudioFormat format : formats) {
                        if (format.getSampleSizeInBits() == 16 && format.getChannels() == 1
                                && format.getEncoding() == AudioFormat.Encoding.PCM_SIGNED) {
                            // 找到支持的目标格式
                            AudioFormat dataFormat = format;
                            TargetDataLine targetDataLine;
                            targetDataLine = (TargetDataLine) mixer.getLine(
                                    new DataLine.Info(TargetDataLine.class, dataFormat));
                            RecordThread recordThread = new RecordThread(targetDataLine, dataFormat);
                            recordThread.start();
                        }
                    }
                } catch (LineUnavailableException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    // Ignore
                } finally {
                    if (line != null && !opened) {
                        line.close();
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
  1. 实现录音线程

现在,我们需要实现一个线程来执行录音。这个线程将录制用户的声音,然后将它保存到一个 WAV 文件中。

实现录音的线程示例代码:

public class RecordThread extends Thread {
    private TargetDataLine targetDataLine;
    private AudioFormat dataFormat;

    public RecordThread(TargetDataLine targetDataLine, AudioFormat dataFormat) {
        this.targetDataLine = targetDataLine;
        this.dataFormat = dataFormat;
    }

    public void run() {
        AudioInputStream audioStream = new AudioInputStream(targetDataLine);
        File audioFile = new File("record.wav");
        try {
            AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, audioFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  1. 结束录音

确认录音已经完成后,我们需要停止录音线程并保存录音。

示例代码:

private void stopRecording() {
    targetDataLine.stop();
    targetDataLine.close();
}

示例代码:

// 停止录音
StopRecording stopRecording = new StopRecording(targetDataLine);
stopRecording.start();
public class StopRecording extends Thread {
    private TargetDataLine targetDataLine;

    public StopRecording(TargetDataLine targetDataLine) {
        this.targetDataLine = targetDataLine;
    }

    public void run() {
        // 打断线程
        targetDataLine.stop();
        targetDataLine.close();

        // TODO: 保存录音
    }
}
  1. 保存录音

我们已经准备好了录音,现在我们需要将它保存到文件中。

示例代码:

private void saveRecording() {
    FileDialog fileDialog = new FileDialog(this, "Save Recording", FileDialog.SAVE);
    fileDialog.setFile("record.wav");
    fileDialog.setVisible(true);
    String filename = fileDialog.getFile();
    if (filename != null) {
        try {
            File selectedFile = new File(fileDialog.getDirectory() + "/" + fileDialog.getFile());
            FileInputStream fileInputStream = new FileInputStream("record.wav");
            FileOutputStream fileOutputStream = new FileOutputStream(selectedFile);
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, bytesRead);
            }
            fileInputStream.close();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

至此,我们已经实现了Java Swing支持录音等功能的钢琴程序。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java swing实现支持录音等功能的钢琴程序 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • Spring Security账户与密码验证实现过程

    下面是详细讲解”Spring Security账户与密码验证实现过程”的完整攻略。 Spring Security账户与密码验证实现过程 Spring Security 是一个功能强大的权限验证框架,它提供了多种认证方式,其中最常用的是账户与密码验证方式。本文将介绍实现 Spring Security 账户与密码验证的完整过程。 步骤一:添加 Spring …

    Java 2023年5月20日
    00
  • springmvc整合ssm配置的详细代码

    下面我将为您详细讲解如何在Spring MVC框架下整合SSM(Spring + SpringMVC + MyBatis)框架,并提供两个示例说明。 步骤一:创建Maven项目 首先,您需要创建一个Maven项目,以便引入所需的库和依赖项。创建完成后,在pom.xml中添加以下依赖: <dependencies> <!– Spring M…

    Java 2023年6月15日
    00
  • JAVA后端学习精华之网络通信项目进阶

    JAVA后端学习精华之网络通信项目进阶攻略 网络通信是JAVA后端开发中重要的一环,本文将从网络通信的概念、常见协议以及实现原理等方面进行详细讲解,以帮助读者深入了解JAVA网络通信技术,并指导初学者系统学习网络通信项目的开发过程。 网络通信基础知识 什么是网络通信? 网络通信是指在计算机网络中实现信息交换的过程,包括数据传输和信息处理两个环节。具体而言,在…

    Java 2023年5月24日
    00
  • Lambda表达式的使用及注意事项

    Lambda表达式是Java8新引入的一种语法形式,可以用于简洁地定义匿名函数,常用于对集合进行筛选、映射等操作。下面将详细讲解Lambda表达式的使用及注意事项。 Lambda表达式的语法 Lambda表达式由三部分组成:参数列表、箭头符号和表达式或语句块。其基本格式为: (参数列表) -> {表达式或语句块} 例如,下面是一个Lambda表达式的例…

    Java 2023年5月19日
    00
  • Spring AOP实现功能权限校验功能的示例代码

    让我来为您介绍一下Spring AOP实现功能权限校验的攻略。 简介 Spring AOP是Spring框架中的一个模块,可以实现面向切面编程(AOP)的功能。通过Spring AOP可以实现功能权限校验的功能,实现对用户的操作进行安全控制并保护业务数据的安全性。 实现步骤 步骤一:定义权限校验的切面 在Spring AOP中,切面是对应用程序中横切关注点的…

    Java 2023年5月20日
    00
  • OpenJDK源码调试图文教程

    首先需要明确的是,OpenJDK的源码调试需要借助GDB来实现,具体步骤如下: 步骤一:下载OpenJDK源码 可以到OpenJDK的官网(https://jdk.java.net/16/)下载源码压缩包,选择源码版本为当前使用的JDK版本对应的源码版本。下载后解压缩。 步骤二:为OpenJDK编译符号表 使用如下命令编译OpenJDK: bash conf…

    Java 2023年5月23日
    00
  • Java中打乱一个数组的2种公平算法分享

    下面是“Java中打乱一个数组的2种公平算法分享”的完整攻略。 一、算法1:Fisher–Yates算法 1.算法原理 Fisher-Yates算法,又叫Knuth Shuffle算法,使用的是下标随机交换的方法,每次迭代时随机一个在当前位置及以后的位置(包括当前位置)之间的任意一个索引,然后将当前位置与该索引处的元素进行交换。该算法类似于每次从未处理的数据…

    Java 2023年5月19日
    00
  • Sprint Boot @NotNull使用方法详解

    @NotNull是Spring Boot中的一个注解,用于标记一个字段或方法参数不能为空。在本文中,我们将详细介绍@NotNull注解的作用和使用方法,并提供两个示例说明。 @NotNull注解的作用 @NotNull注解用于标记一个字段或方法参数不能为空。当使用@NotNull注解标记一个字段或方法参数时,如果该字段或方法参数为null,则会抛出javax…

    Java 2023年5月5日
    00
合作推广
合作推广
分享本页
返回顶部