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实现统一登录与权限控制的示例代码”的详细攻略: 1. 简介 Spring Security是一款基于Spring框架的身份验证和访问控制框架,它为Java应用程序提供了全面而强大的安全解决方案。它可以帮助我们通过实现统一登录和权限控制功能来增强应用程序的安全性。 2. 实现步骤 2.1 引入Spring Securi…

    Java 2023年6月3日
    00
  • IDEA2020.2.3 “reading maven projects”卡住的问题

    问题描述: 在使用IntelliJ IDEA 2020.2.3进行Maven项目的读取时,出现了卡在”Reading Maven Projects”阶段的情况,无法继续进行下一步操作。 解决方案: 清空本地Maven仓库 首先尝试清空本地Maven仓库,步骤如下: 1)在命令行使用以下命令清空本地Maven仓库: mvn dependency:purge-l…

    Java 2023年5月20日
    00
  • Java中解密微信加密数据工具类

    Java中解密微信加密数据工具类 – 完整攻略 对于开发微信小程序的开发者而言,解密微信加密数据是一个重要的任务。为了提供更好的开发体验,我们可以利用Java来解密微信加密数据,本文将详细讲解Java中解密微信加密数据的完整攻略。 前置条件 在开始讲解如何在Java中解密微信加密数据之前,我们需要做好以下几个前置条件: 在微信官方平台上注册自己的小程序,并获…

    Java 2023年5月23日
    00
  • 详解SpringBoot+Thymeleaf 基于HTML5的现代模板引擎

    Sure,下面我会详细讲解“详解SpringBoot+Thymeleaf 基于HTML5的现代模板引擎”的完整攻略。 简介 Thymeleaf 是一个用于 Web 与独立环境的现代服务器端 Java 模板引擎。Thymeleaf 的主要目标是提供一种优雅和高度可维护的创建 XHTML / HTML5 的模板的方式;同时也可以非常轻松地拓展为JSP等模板引擎,…

    Java 2023年6月15日
    00
  • 详解在Java的Struts2框架中配置Action的方法

    下面我将详细讲解在Java的Struts2框架中配置Action的方法。在Struts2框架中,可以通过配置struts.xml文件或注解的方式来配置Action。 1. 配置struts.xml文件 1.1 新建Action类 首先需要新建一个Action类,通常继承com.opensymphony.xwork2.ActionSupport类。例如: pu…

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

    以下是关于Spring Boot的@ConfigurationPropertiesBinding的作用与使用方法的完整攻略,包含两个示例: Spring Boot的@ConfigurationPropertiesBinding是什么? @ConfigurationPropertiesBinding是Spring Boot中的一个注解,用于将自定义类型的属性绑…

    Java 2023年5月5日
    00
  • Java四种常用线程池的详细介绍

    Java四种常用线程池的详细介绍 线程池的作用 在高并发处理场景下,线程的创建、销毁以及上下文切换会消耗大量的CPU和内存资源,从而影响系统的性能。为了解决这个问题,Java提供了线程池来管理线程,使得线程的创建、销毁、复用和调度都可以由线程池来完成,从而减少线程的创建和销毁带来的开销,提高系统的并发处理能力。 Java中线程池的实现 Java中的线程池是通…

    Java 2023年5月18日
    00
  • SpringMVC上传文件FileUpload使用方法详解

    下面是详细讲解“SpringMVC上传文件FileUpload使用方法详解”的完整攻略: 什么是SpringMVC文件上传? SpringMVC文件上传就是通过SpringMVC框架提供的功能,实现将文件从客户端传输到服务器端并存储到指定位置的过程。文件上传是Web应用程序经常使用的功能之一。通过SpringMVC文件上传,我们可以轻松地完成文件上传的处理,…

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