Java:根据播放的音乐在JFrame上绘制随机形状
我正在Java:根据播放的音乐在JFrame上绘制随机形状,java,swing,for-loop,jframe,javax.sound.midi,Java,Swing,For Loop,Jframe,Javax.sound.midi,我正在尝试在播放音乐时绘制JFrame,这些形状是随机创建的,无需计算,当播放了一些音乐时,会弹出一个JFrame并在那里绘制这些形状,问题是,当我运行此代码时,没有音乐声音和图形绘制,只有一个框架弹出,没有其他内容,请检查此代码并帮助我更正 public class MusicBeatsDrawing { static JFrame frame; DrawPanel dp =new DrawPanel(); public static void main(Strin
尝试在播放音乐时绘制JFrame
,这些形状是随机创建的,无需计算,当播放了一些音乐时,会弹出一个JFrame并在那里绘制这些形状,
问题是,当我运行此代码时,没有音乐声音和图形绘制,只有一个框架弹出,没有其他内容,请检查此代码并帮助我更正
public class MusicBeatsDrawing {
static JFrame frame;
DrawPanel dp =new DrawPanel();
public static void main(String[] args)
{
MusicBeatsDrawing mbd= new MusicBeatsDrawing();
mbd.go();
}
public void SetGui(){
frame= new JFrame("Simple frame ; ");
frame.setBounds(100, 100, 200, 200);
frame.setContentPane(dp);
frame.setVisible(true);
}
public void go()
{
SetGui();
try
{
Sequencer sequencer = MidiSystem.getSequencer();
sequencer.open();
Sequence seq= new Sequence(Sequence.PPQ, 4);
sequencer.addControllerEventListener(dp,new int [] {127});
Track track = seq.createTrack();
int r = 0;
for (int i = 0; i < 60 ; i+= 4) {
r = (int) Math.random()*50;
track.add(MakeEvent(144,1,r,100,i));
track.add(MakeEvent(176,1,127,0,i));
track.add(MakeEvent(128,1,r,100,i ));
}
sequencer.setSequence(seq);
sequencer.start();
}
catch(Exception e)
{e.printStackTrace(); }
}
public MidiEvent MakeEvent(int one , int two , int three , int four , int tick)
{
MidiEvent event= null;
try
{
ShortMessage sm= new ShortMessage();
sm.setMessage(one,two, three, four);
event= new MidiEvent(sm , tick );
} catch (InvalidMidiDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return event;
}
class DrawPanel extends JPanel implements ControllerEventListener
{
boolean msg= false ;
public void paintComponent(Graphics g)
{
if(msg){ Graphics2D g2d= (Graphics2D) g;
int red= (int) (Math.random()*255);
int green= (int) (Math.random()*255) ;
int blue= (int) (Math.random()*255);
g.setColor(new Color(red, green , blue));
int height= (int)Math.random()*255;
int width= (int)Math.random()*255;
int x= (int)Math.random()*255;
int y= (int)Math.random()*255;
g.fillRect(height, width, x, y);
msg = false;
}
}
@Override
public void controlChange(ShortMessage event) {
msg= true;
repaint();
}}
}
公共类音乐播放{
静态JFrame;
DrawPanel dp=新的DrawPanel();
公共静态void main(字符串[]args)
{
MusicBeatsDrawing mbd=新建MusicBeatsDrawing();
mbd.go();
}
公共void SetGui(){
框架=新的JFrame(“简单框架;”);
框架.立根(100100200200);
frame.setContentPane(dp);
frame.setVisible(true);
}
公开作废go()
{
SetGui();
尝试
{
Sequencer Sequencer=MidiSystem.getSequencer();
sequencer.open();
Sequence seq=新序列(Sequence.PPQ,4);
sequencer.addControllerEventListener(dp,new int[]{127});
Track Track=seq.createTrack();
int r=0;
对于(int i=0;i<60;i+=4){
r=(int)Math.random()*50;
添加(MakeEvent(144,1,r,100,i));
track.add(MakeEvent(1761127,0,i));
track.add(MakeEvent(128,1,r,100,i));
}
序列器。设置序列(seq);
sequencer.start();
}
捕获(例外e)
{e.printStackTrace();}
}
公共MidiEvent MakeEvent(int-one、int-two、int-three、int-four、int-tick)
{
MidiEvent=null;
尝试
{
短消息sm=新短消息();
设置消息(一,二,三,四);
事件=新事件(sm,勾号);
}捕获(InvalidMidiDataE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回事件;
}
类DrawPanel扩展JPanel实现ControllerEventListener
{
布尔值msg=false;
公共组件(图形g)
{
如果(msg){Graphics2D g2d=(Graphics2D)g;
int red=(int)(Math.random()*255);
绿色整数=(整数)(Math.random()*255);
蓝色整数=(整数)(Math.random()*255);
g、 setColor(新颜色(红色、绿色、蓝色));
int height=(int)Math.random()*255;
int width=(int)Math.random()*255;
int x=(int)Math.random()*255;
int y=(int)Math.random()*255;
g、 fillRect(高度、宽度、x、y);
msg=假;
}
}
@凌驾
公共无效控制更改(短消息事件){
msg=真;
重新油漆();
}}
}
Swing GUI对象应仅在上构造和操作。通过此更改,您的程序可以正常工作。一个明显的症状是,当您调整帧大小时,程序会运行,这会导致系统反复调用repaint()
增编:还有一些问题值得注意
- 使
lastsetVisible()
- sequencer启动延迟可能值得移到后台
- 使用命名常量,例如
短消息。请注意
,而不是
- 实例化
,供以后使用Random
- 遵循Java命名约定
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.sound.midi.ControllerEventListener;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @see http://stackoverflow.com/a/17767350/230513
*/
public class MidiDrawing {
private static final Random R = new Random();
public static void main(String[] args) {
EventQueue.invokeLater(new MidiDrawing()::display);
}
public void display() {
JFrame frame = new JFrame("Midi Drawing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawPanel dp = new DrawPanel();
frame.add(dp);
Sequencer sequencer = initSequencer(dp);
JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT));
p.add(new JButton(new AbstractAction("Start") {
@Override
public void actionPerformed(ActionEvent e) {
sequencer.setTickPosition(0);
sequencer.start();
}
}));
frame.add(p, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private Sequencer initSequencer(DrawPanel dp) {
try {
Sequencer sequencer = MidiSystem.getSequencer();
Sequence seq = new Sequence(Sequence.PPQ, 3);
Track track = seq.createTrack();
int n = 60; // middle C
for (int i = 0; i < 3 * 12; i += 3) {
track.add(new MidiEvent(new ShortMessage(ShortMessage.CONTROL_CHANGE, 0, 0, n), i));
track.add(new MidiEvent(new ShortMessage(ShortMessage.NOTE_ON, 0, n, 127), i));
track.add(new MidiEvent(new ShortMessage(ShortMessage.NOTE_ON, 0, n + 3, 127), i));
track.add(new MidiEvent(new ShortMessage(ShortMessage.NOTE_OFF, 0, n, 127), i + 3));
track.add(new MidiEvent(new ShortMessage(ShortMessage.NOTE_OFF, 0, n + 3, 127), i + 3));
n++;
}
sequencer.open();
sequencer.setSequence(seq);
sequencer.addControllerEventListener(dp, new int[]{0});
return sequencer;
} catch (InvalidMidiDataException | MidiUnavailableException e) {
e.printStackTrace(System.err);
}
return null;
}
private static class DrawPanel extends JPanel implements ControllerEventListener {
private final Font font = this.getFont().deriveFont(24f);
private int data;
@Override
public void paintComponent(Graphics g) {
g.setColor(Color.getHSBColor(R.nextFloat(), 1, 1));
g.fillRect(0, 0, getWidth(), getHeight());
g.setFont(font);
g.setColor(Color.black);
g.drawString(String.valueOf(data), 8, g.getFontMetrics().getHeight());
}
@Override
public void controlChange(ShortMessage event) {
data = event.getData2();
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(256, 128);
}
}
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.FlowLayout;
导入java.awt.Font;
导入java.awt.Graphics;
导入java.awt.event.ActionEvent;
导入java.util.Random;
导入javax.sound.midi.ControllerEventListener;
导入javax.sound.midi.InvalidMidiDataException;
导入javax.sound.midi.MidiEvent;
导入javax.sound.midi.midi系统;
导入javax.sound.midi.MidiUnavailableException;
导入javax.sound.midi.Sequence;
导入javax.sound.midi.Sequencer;
导入javax.sound.midi.ShortMessage;
导入javax.sound.midi.Track;
导入javax.swing.AbstractAction;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
/**
*@见http://stackoverflow.com/a/17767350/230513
*/
公共类MIDI绘图{
私有静态最终随机R=新随机();
公共静态void main(字符串[]args){
invokeLater(新的MidiDrawing()::display);
}
公共空间显示(){
JFrame=新的JFrame(“Midi图形”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawPanel dp=新的DrawPanel();
帧。添加(dp);
定序器定序器=初始定序器(dp);
JPanel p=newjpanel(newflowlayout(FlowLayout.RIGHT));
p、 添加(新JButton(新抽象操作(“开始”){
@凌驾
已执行的公共无效操作(操作事件e){
定序器。设定滴答位置(0);
sequencer.start();
}
}));
框架。添加(p,边界布局。南部);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
专用定序器初始化定序器(DrawPanel dp){
试一试{
Sequencer Sequencer=MidiSystem.getSequencer();
Sequence seq=新序列(Sequence.PPQ,3);
Track Track=seq.createTrack();
int n=60;//中间C
对于(int i=0;i<3*12;i+=3){
添加(新MidiEvent(新短消息(ShortMessage.CONTROL_CHANGE,0,0,n),i));
添加(新的MidiEvent(新的短消息(ShortMessage.NOTE_ON,0,n,127),i));
添加(新的MidiEvent(新的短消息(ShortMessage.NOTE_ON,0,n+3127),i));