Java多媒体编程应用
1. 声音文件的播放
1.1 在Applet中播放声音
在Applet中,可以使用AudioClip来播放声音,它非常简单,只有三个方法:play()、loop()和stop()。
例1.1 利用AudioClip播放声音文件。
package duomeiti; import java.applet.Applet; import java.applet.AudioClip; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; public class playMusic extends Applet implements ActionListener { AudioClip clip = null; JButton playBtn,loopBtn,stopBtn; public void init(){ playBtn = new JButton("播放"); loopBtn = new JButton("循环"); stopBtn = new JButton("停止"); playBtn.addActionListener(this); loopBtn.addActionListener(this); stopBtn.addActionListener(this); add(playBtn); add(loopBtn); add(stopBtn); clip = getAudioClip(getCodeBase(),"test.wav"); } public void actionPerformed(ActionEvent e) { if(e.getSource()==playBtn) clip.play(); else if(e.getSource()==loopBtn) clip.loop(); else clip.stop(); } }
1.2 在Application中播放声音
它的一般用法是,先用AudioStream创建一个音频流对象,而后将此对象作为参数传递给AudioPlayer.player.start()方法以便播放。虽然AudioPlayer.player中只有start()和stop()两个方法,但是start()方法会从音频流对象上次停止播放的位置开始播放,而不是从头开始播放。所以用stop()暂停一个音频流的播放后,可以使用start()继续播放。
例1.2 在Application中播放声音文件。
package duomeiti; import java.awt.Container; import java.awt.FlowLayout; import java.awt.HeadlessException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import javax.swing.*; import sun.audio.AudioPlayer; import sun.audio.AudioStream; public class playAudio implements ActionListener { protected JTextField fileField; protected JButton openBtn,startBtn,pauseBtn,resumBtn,stopBtn; protected Container con; protected JFrame jf; protected AudioStream as; protected FileInputStream fis; public playAudio(){ jf = new JFrame("播放声音"); con = jf.getContentPane(); con.setLayout(new FlowLayout()); fileField = new JTextField(); fileField.setColumns(30); openBtn = new JButton("选择文件"); startBtn = new JButton("开始播放"); pauseBtn = new JButton("暂停播放"); resumBtn = new JButton("继续播放"); stopBtn = new JButton("停止播放"); openBtn.addActionListener(this); startBtn.addActionListener(this); pauseBtn.addActionListener(this); resumBtn.addActionListener(this); stopBtn.addActionListener(this); con.add(fileField); con.add(openBtn); con.add(startBtn); con.add(pauseBtn); con.add(resumBtn); con.add(stopBtn); jf.setSize(500, 400); jf.setLocation(300, 200); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e) { Object obj; obj = e.getSource(); try { if(obj==openBtn) openfile(); else if(obj==startBtn){ if(fis!=null) fis.close(); fis = new FileInputStream(fileField.getText()); as = new AudioStream(fis); AudioPlayer.player.start(as); }else if(obj==pauseBtn) AudioPlayer.player.stop(as); else if(obj==resumBtn) AudioPlayer.player.start(as); else if(obj==stopBtn){ AudioPlayer.player.stop(as); as.close(); fis.close(); fis = null; } } catch (FileNotFoundException e1) { JOptionPane.showMessageDialog(jf, "文件没有找到!"); } catch (IOException e1) { JOptionPane.showMessageDialog(jf, "无法播放文件!"); } } private void openfile() { try { JFileChooser chooser = new JFileChooser(); if(chooser.showOpenDialog(jf)==JFileChooser.APPROVE_OPTION) fileField.setText(chooser.getSelectedFile().toString()); } catch (Exception e) { JOptionPane.showMessageDialog(jf, "无法加载文件!"); } } public static void main(String[] args) { new playAudio(); } }
2. 基本图形处理
2.1 图形的缩放
例2.1 缩放图形示例
package duomeiti; import java.awt.Color; import java.awt.Graphics; import javax.swing.*; public class ResizeOval { JFrame jf; MyCanvas palette; public class MyCanvas extends JPanel{ protected void paintComponent(Graphics g) { int height,width; height = getHeight(); width = getWidth(); g.setColor(Color.RED); g.fillOval(0, 0, width, height); } } public ResizeOval(){ jf = new JFrame("图形缩放示例"); palette = new MyCanvas(); jf.getContentPane().add(palette); jf.setSize(500, 400); jf.setLocation(300,200); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new ResizeOval(); } }
2.2 淡入淡出效果
要实现淡入淡出效果方法非常简单,只要采用HSB(色调-饱和度-亮度)模式设置色彩,其中的色调和亮度不必变化,只要调整饱和度的值即可。如果是淡入,则让饱和度逐步增加;如果是淡出,则让饱和度逐步减少。
例2.2 淡入淡出效果示例。
package duomeiti; import java.awt.Color; import java.awt.Container; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; public class fadeInOut { JFrame jf; JPanel jp; Container con; dealPushBtn handleBtn; JButton btn; public class dealPushBtn implements ActionListener{ public void actionPerformed(ActionEvent e) { Graphics g = jp.getGraphics(); float h = 0.0f; float s = 0.0f; float b = 1.0f; for(int i=0;i<100;i++){ g.setColor(Color.getHSBColor(h, s, b)); g.fillRect(0, 50, 300, 300); try { Thread.sleep(50); } catch (InterruptedException e1) { e1.printStackTrace(); } s+=0.01; } for(int i=0;i<100;i++){ g.setColor(Color.getHSBColor(h, s, b)); g.fillRect(0, 50, 300, 300); try { Thread.sleep(50); } catch (InterruptedException e1) { e1.printStackTrace(); } s-=0.01; } } } public fadeInOut(){ jf = new JFrame("色彩淡入淡出示例"); jp = new JPanel(); jp.setLayout(new FlowLayout()); handleBtn = new dealPushBtn(); btn= new JButton("开始"); btn.addActionListener(handleBtn); con = jf.getContentPane(); jp.add(btn); con.add(jp); jf.setSize(300, 300); jf.setLocation(300, 200); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new fadeInOut(); } }
2.3 透明效果
设置前景色的透明度,可以使得前景色和后景色能够混合起来,这需要使用Graphics2D类。
例2.3 色彩混合效果示例。
package duomeiti; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import javax.swing.*; public class TransparencyExample extends JPanel { private static int gap=10, width=40, offset=10,deltax=gap+width+offset; private Rectangle blueSquare = new Rectangle(gap+offset,gap+offset,width,width), redSquare = new Rectangle(gap,gap,width,width); //创建一个指定alpha值的AlphaComposite对象 private AlphaComposite makeComposite(float alpha){ int type = AlphaComposite.SRC_OVER; return (AlphaComposite.getInstance(type, alpha)); } //用指定的alpha值来绘制前景色 private void drawSquares(Graphics2D g2d,float alpha){ Composite originalComposite = g2d.getComposite(); //用默认透明度绘制背景蓝色 g2d.setPaint(Color.blue); g2d.fill(blueSquare); //设置透明度,准备绘制前景红色 g2d.setComposite(makeComposite(alpha)); g2d.setPaint(Color.red); g2d.fill(redSquare); //将透明度设置回默认的模式 g2d.setComposite(originalComposite); } //分别用不同的透明度来绘制颜色 public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2d = (Graphics2D)g; for(int i=0;i<11;i++){ //alpha值逐步增大,透明度逐步减小 drawSquares(g2d,i*0.1F); g2d.translate(deltax, 0); } } }
package duomeiti; import javax.swing.*; import java.awt.*; public class mixing { JFrame jf; TransparencyExample palette; public mixing(){ jf = new JFrame("色彩混合示例"); palette = new TransparencyExample(); jf.getContentPane().add(palette); jf.setSize(700, 400); jf.setLocation(300, 200); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new mixing(); } }
3. 字体的处理
3.1 确定可用字体
例3.1 获取系统中安装的字体示例。
package duomeiti; import java.awt.GraphicsEnvironment; import javax.swing.*; public class GetFonts { private JFrame jf; private JList nameList; private JScrollPane nameSPane; public GetFonts(){ jf = new JFrame("获取系统字体"); //获得GraphicsEnvironment类型的对象引用 GraphicsEnvironment eq = GraphicsEnvironment.getLocalGraphicsEnvironment(); //获取所有的字体家族名 String[] availableFonts = eq.getAvailableFontFamilyNames(); //存放到列表框中 nameList = new JList(availableFonts); nameSPane = new JScrollPane(nameList); jf.add(nameSPane); jf.setSize(500, 400); jf.setLocation(300, 200); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new GetFonts(); } }
3.2 创建字体对象
例3.2 创建和使用字体示例。
package duomeiti; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class ShowFonts implements ActionListener { private JFrame jf; private JComboBox nameBox,styleBox; private JTextField sizeText; private JLabel fontLabel; private JButton showBtn; private JPanel panel; public ShowFonts(){ jf = new JFrame("显示指定字体"); //显示系统可用字体 GraphicsEnvironment eq = GraphicsEnvironment.getLocalGraphicsEnvironment(); String[] availableFonts = eq.getAvailableFontFamilyNames(); nameBox = new JComboBox(availableFonts); nameBox.setEditable(true); nameBox.setSelectedItem("宋体"); //显示字体风格由用户选择 String[] style = {"正常","粗体","斜体","粗斜体"}; styleBox = new JComboBox(style); styleBox.setEditable(false); //由用户输入想要的字体尺寸 sizeText = new JTextField("12"); sizeText.setColumns(4); //标签用于显示用户选择的字体 fontLabel = new JLabel("字体示例"); //创建按钮并安装监听器 showBtn = new JButton("显示字体"); showBtn.addActionListener(this); //在窗口中排列组件 panel = new JPanel(); panel.setLayout(new FlowLayout()); panel.add(nameBox); panel.add(styleBox); panel.add(sizeText); jf.add(panel, BorderLayout.NORTH); jf.add(fontLabel, BorderLayout.CENTER); jf.add(showBtn, BorderLayout.SOUTH); jf.setSize(500, 400); jf.setLocation(300, 200); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e) { //分别获取用户选择输入的字体信息 int styleIndex = styleBox.getSelectedIndex(); String fontStr = (String)nameBox.getSelectedItem(); int fontSize = Integer.parseInt(sizeText.getText()); //组合字体对象 Font userFont = new Font(fontStr,styleIndex,fontSize); //为标签设置新的字体并显示 fontLabel.setFont(userFont); } public static void main(String[] args) { new ShowFonts(); } }
4. 字体的展示处理
例4.1 自行管理字体示例。
package duomeiti; import javax.swing.*; import java.awt.*; public class FontsCanvas extends JPanel { private String msg; public FontsCanvas(String s){ msg = s; setBackground(Color.white); } public FontsCanvas(){ this("自行管理字体示例"); } public void paintComponent(Graphics g){ int maxWidth = getWidth(); //获取画布的宽度 int showX; //文字输出的横坐标位置 int showY = 0; //文字输出的纵坐标位置 int descent = 0; //文字下半部所占位置 int ascent = 0; //文字上半部所占位置 int leading = 0; //行间距 int totalWidth; //字符串所占宽度 FontMetrics fm; //用于自行管理字体 Font myFonts [] = new Font[4]; //创建不同的字体准备显示 myFonts[0] = new Font("宋体",Font.PLAIN,12); myFonts[1] = new Font("仿宋",Font.BOLD,24); myFonts[2] = new Font("黑体",Font.ITALIC,48); myFonts[3] = new Font("楷体_GB2312",Font.ITALIC|Font.BOLD,60); //用上述4种不同的字体显示同一个字符串,右对齐 for(int i=0;i<myFonts.length;i++){ g.setFont(myFonts[i]); fm = g.getFontMetrics(); totalWidth = fm.stringWidth(msg); showX = maxWidth - totalWidth; ascent = fm.getMaxAscent(); showY = showY + descent + ascent + leading; descent = fm.getMaxDescent(); leading = fm.getLeading(); g.drawString(msg, showX, showY); } } }
package duomeiti; import javax.swing.*; import java.awt.*; public class ManageFonts { private JFrame jf; private FontsCanvas palette; //可以显示多种文字的画布 public ManageFonts(){ jf = new JFrame("自行管理字体示例"); palette = new FontsCanvas(); jf.add(palette); jf.setSize(500, 400); jf.setLocation(300, 200); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new ManageFonts(); } }
5. 字体的特效显示
例5.1 字体特效显示示例。
package duomeiti; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Timer; import java.util.TimerTask; import javax.swing.*; public class LightingLiteral implements ActionListener { String title = "光照文字"; //显示的文字 Font myFont = new Font("宋体",Font.BOLD,48); //显示的字体 JPanel palette; JFrame jf; JButton startBtn; Container con; Timer myTimer; Refresh task; boolean startFlag; public LightingLiteral(){ jf = new JFrame(title); palette = new JPanel(); startBtn = new JButton("开始"); startFlag = true; startBtn.addActionListener(this); con = jf.getContentPane(); con.add(palette, BorderLayout.CENTER); con.add(startBtn, BorderLayout.NORTH); jf.setSize(500, 400); jf.setLocation(300, 200); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e) { if(startFlag){ myTimer = new Timer(); task = new Refresh(); myTimer.schedule(task, 50, 50); //启动定时器,时间间隔为50毫秒 startBtn.setText("停止"); }else{ myTimer.cancel(); myTimer = null; task = null; startBtn.setText("开始"); } startFlag = !startFlag; } //用定时器来绘图 class Refresh extends TimerTask{ int pos = 0; int blink_width = 20; //光条的宽度 Graphics g = palette.getGraphics(); //注意画笔的获取方式 FontMetrics myFM = g.getFontMetrics(myFont); int height = myFM.getHeight(); //计算文字的高度 int top = myFM.getAscent(); int width = myFM.stringWidth(title); public Refresh(){ g.setFont(myFont); } public void run() { g.setColor(Color.blue); g.drawString(title, 0, top); //第一遍显示 g.clipRect(pos, 0, blink_width, height); //设置裁剪区域 g.setColor(Color.yellow); g.drawString(title, 0, top); //第二遍显示,它只会显示在裁剪区域中 pos = (pos + 5) % width; //移动裁剪区域的位置 g.setClip(null); //让裁剪区域失效,准备重新绘制蓝色文字 } } public static void main(String[] args) { new LightingLiteral(); } }