1. 河豚號 > 生活百科 >

gridbagconstraints布局(gridbaglayout布局管理器的用法)

前幾次博客中也是用java實(shí)現(xiàn)錄音機(jī)的各種功能,這次是比先前有了一點(diǎn)優(yōu)化,將錄音的功能單獨(dú)提取出來,這個(gè)程序的實(shí)現(xiàn)用到了編碼器LAME.exe這個(gè)的作用是將錄音得到的wav文件編碼成MP3文件,這樣的結(jié)果是容量大大減少,因?yàn)長AME編碼器經(jīng)測試在編碼過程中路徑中帶有空格問題未能解決,所以只能找了一個(gè)笨的方法,為了將其放到指定的文件夾下(這個(gè)文件夾路徑是帶有空格的),所以只能先存放到D盤,然后利用文件操作將其復(fù)制到指定的路徑下,然后再刪除,程序中還用到了圖片,修改了java的圖標(biāo),所以在運(yùn)行時(shí)可將其注釋掉,寫的很爛,相互學(xué)習(xí)哈!

/*

* 實(shí)現(xiàn)錄音機(jī)的功能

* 1.在原來的基礎(chǔ)上界面更加精簡,字體變大使用戶更加方便

* 2.在停止錄音后便直接保存為.mp3文件

* 3.對停止錄音進(jìn)行改進(jìn),將錄音按鈕設(shè)計(jì)成類似微信的形式,按下時(shí)進(jìn)行錄音,松開即停止錄音并保存即可

* 4.在錄音的時(shí)候在面板上顯示音頻波,表示正在錄音

*/

package com.liuyun.MyRecord6;

import java.awt.*;

import javax.swing.*;

import java.awt.event.*;

import java.io.*;

import javax.sound.sampled.*;

import java.lang.*;

public class MyRecord6 extends JFrame implements MouseListener{

//定義錄音格式

AudioFormat af = null;

//定義目標(biāo)數(shù)據(jù)行,可以從中讀取音頻數(shù)據(jù),該 TargetDataLine 接口提供從目標(biāo)數(shù)據(jù)行的緩沖區(qū)讀取所捕獲數(shù)據(jù)的方法。

TargetDataLine td = null;

//定義源數(shù)據(jù)行,源數(shù)據(jù)行是可以寫入數(shù)據(jù)的數(shù)據(jù)行。它充當(dāng)其混頻器的源。應(yīng)用程序?qū)⒁纛l字節(jié)寫入源數(shù)據(jù)行,這樣可處理字節(jié)緩沖并將它們傳遞給混頻器。

SourceDataLine sd = null;

//定義字節(jié)數(shù)組輸入輸出流

ByteArrayInputStream bais = null;

ByteArrayOutputStream baos = null;

//定義音頻輸入流

AudioInputStream ais = null;

//定義停止錄音的標(biāo)志,來控制錄音線程的運(yùn)行

Boolean stopflag = false;

//記錄開始錄音的時(shí)間

long startPlay;

//設(shè)置一個(gè)播放的標(biāo)志

Boolean playflag;

//每次保存的最后的文件名

File tarFile = null;

//定義音頻波形每次顯示的字節(jié)數(shù)

int intBytes = 0;

//定義每次錄音的時(shí)候每次提取字節(jié)來畫音頻波

byte audioDataBuffer[] = null;

//定義所需要的組件

JPanel jp1,jp2,jp3;

JLabel jl1=null;

JButton captureBtn;

//設(shè)置畫波形線程的終止的標(biāo)志

boolean flag = true;

//定義播放錄音時(shí)的一個(gè)計(jì)數(shù)值

int cnt;

//定義播放錄音時(shí)一個(gè)緩沖數(shù)組

byte btsPlay[] = null;

int gridx, gridy, gridwidth, gridheight, anchor, fill, ipadx, ipady;

double weightx, weighty;

Insets inset;

GridBagConstraints c;

public static void main(String[] args) {

//創(chuàng)造一個(gè)實(shí)例

MyRecord6 mr = new MyRecord6();

}

//構(gòu)造函數(shù)

public MyRecord6()

{

//組件初始化

jp1 = new JPanel();

jp2 = new JPanel();

jp3 = new JPanel();

//定義jp1的字體

Font jpFont = new Font(“華文新魏”,Font.BOLD,40);

jl1 = new JLabel(“請留下您想說的話”);

jl1.setFont(jpFont);

jl1.setForeground(Color.red);

jp1.add(jl1);

//定義按鈕上面的字體

Font btFont = new Font(“華文新魏”,Font.BOLD,40);

captureBtn = new JButton(“按住 說話”);

//setForeground可以設(shè)置按鈕上面字體的顏色

captureBtn.setForeground(Color.RED);

captureBtn.setFont(btFont);

//對開始錄音按鈕進(jìn)行鼠標(biāo)監(jiān)聽

captureBtn.addMouseListener(this);

this.add(jp1,BorderLayout.NORTH);

this.add(jp2,BorderLayout.CENTER);

this.add(jp3,BorderLayout.SOUTH);

GridBagLayout gridbag = null;

jp3.setLayout(gridbag = new GridBagLayout());

gridx=1;

gridy=2;

gridwidth=1;

gridheight=1;

weightx=1;

weighty=1;

anchor=GridBagConstraints.CENTER;

fill=GridBagConstraints.HORIZONTAL;

inset=new Insets(1,1,1,1);

ipadx=0;

ipady=30;

c = new GridBagConstraints(gridx, gridy, gridwidth, gridheight,

weightx, weighty, anchor, fill, inset, ipadx, ipady);

gridbag.setConstraints(captureBtn, c);

jp3.add(captureBtn);

//設(shè)置窗口的屬性

this.setSize(800,500);

this.setTitle(“錄音機(jī)”);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//設(shè)置窗口居中

this.setLocationRelativeTo(null);

//將窗口的邊框去掉

this.setUndecorated(true);

this.setVisible(true);

//設(shè)置窗口上的圖標(biāo)

Image img = this.getToolkit().getImage(getClass().getResource(“/image/Recorder.jpg”));

this.setIconImage(img);

//設(shè)置窗口在最前端顯示

this.setAlwaysOnTop(true);

}

public void mouseClicked(MouseEvent e) {

}

public void mousePressed(MouseEvent e) {

//當(dāng)開始錄音按鈕被按下時(shí)就開始錄音

if(e.getSource().equals(captureBtn))

{

//改變按鈕上面的字的內(nèi)容

captureBtn.setText(“松開 結(jié)束”);

//調(diào)用錄音的方法

capture();

//記錄開始錄音的時(shí)間

startPlay = System.currentTimeMillis();

}

}

public void mouseReleased(MouseEvent e) {

//當(dāng)松開錄音按鈕時(shí)停止錄音并保存錄音的文件

if(e.getSource().equals(captureBtn))

{

//調(diào)用停止錄音的方法

stop();

//當(dāng)松開按鈕后對顯示波形的面板進(jìn)行清空

jp2.repaint();

//改變按鈕上面的字的內(nèi)容

captureBtn.setText(“按住 說話”);

//調(diào)用保存錄音的方法

save();

//將其放到指定的路徑下

//定義最終要存放的文件路徑

String destPath = “D:/Program Files/apache-tomcat-6.0.35/webapps/XWZ/tempFile/”;

copyFile(“D:/”+tarFile.getName(), destPath);

System.exit(0);

}

}

public void mouseEntered(MouseEvent e) {

}

public void mouseExited(MouseEvent e) {

}

//開始錄音

public void capture()

{

try {

//af為AudioFormat也就是音頻格式

af = getAudioFormat();

DataLine.Info info = new DataLine.Info(TargetDataLine.class,af);

td = (TargetDataLine)(AudioSystem.getLine(info));

//打開具有指定格式的行,這樣可使行獲得所有所需的系統(tǒng)資源并變得可操作。

td.open(af);

//允許某一數(shù)據(jù)行執(zhí)行數(shù)據(jù) I/O

td.start();

//啟動(dòng)顯示波形的進(jìn)程

RecordWave aw = new RecordWave();

Thread t2 = new Thread(aw);

t2.start();

//把顯示波形的進(jìn)程標(biāo)志設(shè)為true

flag = true;

Record record = new Record();

Thread t1 = new Thread(record);

t1.start();

} catch (Exception ex) {

ex.printStackTrace();

return;

}

}

//停止錄音

public void stop()

{

stopflag = true;

//將畫波形的進(jìn)程終止

flag = false;

}

//保存錄音

public void save()

{

af = getAudioFormat();

byte audioData[] = baos.toByteArray();

bais = new ByteArrayInputStream(audioData);

ais = new AudioInputStream(bais,af, audioData.length / af.getFrameSize());

//定義最終保存的文件名

File file = null;

//寫入文件

try {

//以當(dāng)前的時(shí)間命名錄音的名字

//將錄音的文件存放到F盤下語音文件夾下

File filePath = new File(“D:/AudioFile”);

String tarPath = “D:/”;

if(!filePath.exists())

{//如果文件不存在,則創(chuàng)建該目錄

filePath.mkdirs();

}

long time = System.currentTimeMillis();

file = new File(filePath+”/”+time+”.wav”);

AudioSystem.write(ais, AudioFileFormat.Type.WAVE, file);

//將錄音產(chǎn)生的wav文件轉(zhuǎn)換為容量較小的mp3格式

//定義產(chǎn)生后文件名

tarFile = new File(tarPath+time+”.mp3″);

Runtime run = null;

//測試當(dāng)前的路徑

try {

run = Runtime.getRuntime();

//調(diào)用編碼器來將wav文件轉(zhuǎn)換為mp3文件

//把編碼得到的mp3文件先存放到D盤下,然后利用文件拷貝函數(shù)將它放到指定的文件夾下同時(shí)將D盤下的文件刪除

Process p=run.exec(filePath+”/”+”lame -b 16 “+filePath+”/”+file.getName()+” “+tarPath+tarFile.getName()); //16為碼率,可自行修改

//釋放進(jìn)程

p.getOutputStream().close();

p.getInputStream().close();

p.getErrorStream().close();

//等待

p.waitFor();

// //刪除之前保存的的wav文件

// if(file.exists())

// {

// file.delete();

// }

// //定義最終要存放的文件路徑

// String destPath = “D:/Program Files/apache-tomcat-6.0.35/webapps/XWZ/tempFile/”;

// copyFile(tarPath+tarFile.getName(), destPath);

} catch (Exception e) {

e.printStackTrace();

}finally{

//最后都要執(zhí)行的語句

//run調(diào)用lame解碼器最后釋放內(nèi)存

run.freeMemory();

}

} catch (Exception e) {

e.printStackTrace();

}finally{

//關(guān)閉流

try {

if(bais != null)

{

bais.close();

}

if(ais != null)

{

ais.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

//文件拷貝方法

public void copyFile(String srcPath , String destPath)

{

File srcFile = new File(srcPath);

//如果目的文件夾沒有則創(chuàng)建目的文件夾

(new File(destPath)).mkdirs();

//在目的文件夾下創(chuàng)建要復(fù)制的文件

File destFile = new File(destPath+”/”+srcFile.getName());

if(srcFile.isFile() && srcFile.exists())

{

InputStream in = null;

OutputStream out = null;

try {

in = new FileInputStream(srcFile);

out = new FileOutputStream(destFile);

//設(shè)置緩沖數(shù)組

byte[] buff = new byte[1024*5];

int len = 0;

while ((len = in.read(buff)) != -1)

{

out.write(buff, 0, len);

}

// //測試該函數(shù)是否執(zhí)行

// System.out.println(“ok1”);

} catch(Exception e) {

e.printStackTrace();

}finally{

//關(guān)閉流,先開的后關(guān)閉

try {

if(out != null)

{

out.close();

}

if(in != null)

{

in.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

//復(fù)制過后刪除源文件夾中的的文件

if(srcFile.exists())

{

srcFile.delete();

}

}

//設(shè)置AudioFormat的參數(shù)

public AudioFormat getAudioFormat()

{

//下面注釋部分是另外一種音頻格式,兩者都可以

AudioFormat.Encoding encoding = AudioFormat.Encoding.

PCM_SIGNED ;

float rate = 8000f;

int sampleSize = 16;

String signedString = “signed”;

boolean bigEndian = true;

int channels = 1;

return new AudioFormat(encoding, rate, sampleSize, channels,

(sampleSize / 8) * channels, rate, bigEndian);

// //采樣率是每秒播放和錄制的樣本數(shù)

// float sampleRate = 16000.0F;

// // 采樣率8000,11025,16000,22050,44100

// //sampleSizeInBits表示每個(gè)具有此格式的聲音樣本中的位數(shù)

// int sampleSizeInBits = 16;

// // 8,16

// int channels = 1;

// // 單聲道為1,立體聲為2

// boolean signed = true;

// // true,false

// boolean bigEndian = true;

// // true,false

// return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,bigEndian);

}

//錄音類,因?yàn)橐玫組yRecord類中的變量,所以將其做成內(nèi)部類

class Record implements Runnable

{

//定義存放錄音的字節(jié)數(shù)組,作為緩沖區(qū)

byte bts[] = new byte[10000];

//將字節(jié)數(shù)組包裝到流里,最終存入到baos中

//重寫run函數(shù)

public void run() {

baos = new ByteArrayOutputStream();

try {

stopflag = false;

while(stopflag != true)

{

//當(dāng)停止錄音沒按下時(shí),該線程一直執(zhí)行

//從數(shù)據(jù)行的輸入緩沖區(qū)讀取音頻數(shù)據(jù)。

//要讀取bts.length長度的字節(jié),cnt 是實(shí)際讀取的字節(jié)數(shù)

int cnt = td.read(bts, 0, bts.length);

if(cnt > 0)

{

baos.write(bts, 0, cnt);

}

//開始從音頻流中讀取字節(jié)數(shù)

byte copyBts[] = bts;

bais = new ByteArrayInputStream(copyBts);

ais = new AudioInputStream(bais, af, copyBts.length/af.getFrameSize());

try{

DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, af);

sd = (SourceDataLine) AudioSystem.getLine(dataLineInfo);

sd.open(af);

sd.start();

//從音頻流中讀取

int Buffer_Size = 10000;

audioDataBuffer = new byte[Buffer_Size];

int outBytes;

intBytes = ais.read(audioDataBuffer, 0,audioDataBuffer.length);

// 不寫到混頻器中這樣就不會播放

// if (intBytes >= 0) {

// outBytes = sd.write(audioDataBuffer, 0,audioDataBuffer.length);

// }

}catch (Exception e) {

e.printStackTrace();

}

}

} catch (Exception e) {

e.printStackTrace();

}finally{

try {

//intBytes = -1;

//關(guān)閉打開的字節(jié)數(shù)組流

if(baos != null)

{

baos.close();

}

} catch (Exception e) {

e.printStackTrace();

}finally{

//下面這句td.drain()不能要,這樣如果不播放數(shù)據(jù)就阻塞再次錄音會出現(xiàn)其他程序訪問錯(cuò)誤

//td.drain();

td.close();

//刷新顯示波形的面板

jp2.repaint();

}

}

}

}

//畫波形的類

//因?yàn)橐褂靡恍┲骱瘮?shù)中的數(shù)據(jù),所以做成內(nèi)部類

class RecordWave extends JPanel implements Runnable

{

//用畫筆畫出波形

public void paint(Graphics g)

{

super.paint(g);

g.fillRect(jp2.getX(),jp2.getY() , 800, 380);

if( audioDataBuffer != null)

{

g.drawLine(jp2.getWidth() / 256, 700, jp2.getWidth() / 256, 700);

for(int i=0; i

{

g.setColor(Color.RED);

g.drawLine(i * jp2.getWidth() / 256, (int)audioDataBuffer[i]+200 , (i + 1)

* jp2.getWidth() / 256, (int)audioDataBuffer[i+1]+200);

}

}

}

public void run()

{

//刷新波形

while(true)

{

//System.out.println(“ok”);

try {

synchronized (this) {

//隔多長時(shí)間獲取

Thread.sleep(300);

}

} catch (Exception e) {

e.printStackTrace();

}

this.paint(jp2.getGraphics());

//終止線程

if(flag == false)

{

break;

}

}

}

}

}

本文由網(wǎng)上采集發(fā)布,不代表我們立場,轉(zhuǎn)載聯(lián)系作者并注明出處:http://m.zltfw.cn/shbk/39030.html

聯(lián)系我們

在線咨詢:點(diǎn)擊這里給我發(fā)消息

微信號:15705946153

工作日:9:30-18:30,節(jié)假日休息