SUN的经典JAVA钢琴程序 2
public JButton createButton(String name, JPanel p) {
JButton b = new JButton(name);
b.addActionListener(this);
p.add(b);
return b;
}
private JCheckBox createCheckBox(String name, JPanel p) {
JCheckBox cb = new JCheckBox(name);
cb.addItemListener(this);
p.add(cb);
return cb;
}
private JSlider createSlider(String name, JPanel p) {
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 127, 64);
slider.addChangeListener(this);
TitledBorder tb = new TitledBorder(new EtchedBorder());
tb.setTitle(name + " = 64");
slider.setBorder(tb);
p.add(slider);
p.add(Box.createHorizontalStrut(5));
return slider;
}
private JSlider create14BitSlider(String name, JPanel p) {
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 16383, 8192);
slider.addChangeListener(this);
TitledBorder tb = new TitledBorder(new EtchedBorder());
tb.setTitle(name + " = 8192");
slider.setBorder(tb);
p.add(slider);
p.add(Box.createHorizontalStrut(5));
return slider;
}
public void stateChanged(ChangeEvent e) {
JSlider slider = (JSlider) e.getSource();
int value = slider.getValue();
TitledBorder tb = (TitledBorder) slider.getBorder();
String s = tb.getTitle();
tb.setTitle(s.substring(0, s.indexOf('=')+1) + s.valueOf(value));
if (s.startsWith("Velocity")) {
cc.velocity = value;
} else if (s.startsWith("Pressure")) {
cc.channel.setChannelPressure(cc.pressure = value);
} else if (s.startsWith("Bend")) {
cc.channel.setPitchBend(cc.bend = value);
} else if (s.startsWith("Reverb")) {
cc.channel.controlChange(REVERB, cc.reverb = value);
}
slider.repaint();
}
public void itemStateChanged(ItemEvent e) {
if (e.getSource() instanceof JComboBox) {
JComboBox combo = (JComboBox) e.getSource();
cc = channels[combo.getSelectedIndex()];
cc.setComponentStates();
} else {
JCheckBox cb = (JCheckBox) e.getSource();
String name = cb.getText();
if (name.startsWith("Mute")) {
cc.channel.setMute(cc.mute = cb.isSelected());
} else if (name.startsWith("Solo")) {
cc.channel.setSolo(cc.solo = cb.isSelected());
} else if (name.startsWith("Mono")) {
cc.channel.setMono(cc.mono = cb.isSelected());
} else if (name.startsWith("Sustain")) {
cc.sustain = cb.isSelected();
cc.channel.controlChange(SUSTAIN, cc.sustain ? 127 : 0);
}
}
}
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
if (button.getText().startsWith("All")) {
for (int i = 0; i < channels.length; i++) {
channels[i].channel.allNotesOff();
}
for (int i = 0; i < keys.size(); i++) {
((Key) keys.get(i)).setNoteState(OFF);
}
} else if (button.getText().startsWith("Record")) {
if (recordFrame != null) {
recordFrame.toFront();
} else {
recordFrame = new RecordFrame();
}
}
}
} // End class Controls
/**
* A frame that allows for midi capture & saving the captured data.
*/
class RecordFrame extends JFrame implements ActionListener, MetaEventListener {
public JButton recordB, playB, saveB;
Vector tracks = new Vector();
DefaultListModel listModel = new DefaultListModel();
TableModel dataModel;
JTable table;
public RecordFrame() {
super("Midi Capture");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {recordFrame = null;}
});
sequencer.addMetaEventListener(this);
try {
sequence = new Sequence(Sequence.PPQ, 10);
} catch (Exception ex) { ex.printStackTrace(); }
JPanel p1 = new JPanel(new BorderLayout());
JPanel p2 = new JPanel();
p2.setBorder(new EmptyBorder(5,5,5,5));
p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
recordB = createButton("Record", p2, true);
playB = createButton("Play", p2, false);
saveB = createButton("Save...", p2, false);
getContentPane().add("North", p2);
final String[] names = { "Channel #", "Instrument" };
dataModel = new AbstractTableModel() {
public int getColumnCount() { return names.length; }
public int getRowCount() { return tracks.size();}
public Object getValueAt(int row, int col) {
if (col == 0) {
return ((TrackData) tracks.get(row)).chanNum;
} else if (col == 1) {
return ((TrackData) tracks.get(row)).name;
}
return null;
}
public String getColumnName(int col) {return names[col]; }
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
public boolean isCellEditable(int row, int col) {
return false;
}
public void setValueAt(Object val, int row, int col) {
if (col == 0) {
((TrackData) tracks.get(row)).chanNum = (Integer) val;
} else if (col == 1) {
((TrackData) tracks.get(row)).name = (String) val;
}
}
};
table = new JTable(dataModel);
TableColumn col = table.getColumn("Channel #");
col.setMaxWidth(65);
table.sizeColumnsToFit(0);
JScrollPane scrollPane = new JScrollPane(table);
EmptyBorder eb = new EmptyBorder(0,5,5,5);
scrollPane.setBorder(new CompoundBorder(eb,new EtchedBorder()));
getContentPane().add("Center", scrollPane);
pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int w = 210;
int h = 160;
setLocation(d.width/2 - w/2, d.height/2 - h/2);
setSize(w, h);
setVisible(true);
}
public JButton createButton(String name, JPanel p, boolean state) {
JButton b = new JButton(name);
b.setFont(new Font("serif", Font.PLAIN, 10));
b.setEnabled(state);
b.addActionListener(this);
p.add(b);
return b;
}
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
if (button.equals(recordB)) {
record = recordB.getText().startsWith("Record");
if (record) {
track = sequence.createTrack();
startTime = System.currentTimeMillis();
// add a program change right at the beginning of
// the track for the current instrument
createShortEvent(PROGRAM,cc.col*8+cc.row);
recordB.setText("Stop");
playB.setEnabled(false);
saveB.setEnabled(false);
} else {
String name = null;
if (instruments != null) {
name = instruments[cc.col*8+cc.row].getName();
} else {
name = Integer.toString(cc.col*8+cc.row);
}
tracks.add(new TrackData(cc.num+1, name, track));
table.tableChanged(new TableModelEvent(dataModel));
recordB.setText("Record");
playB.setEnabled(true);
saveB.setEnabled(true);
}
} else if (button.equals(playB)) {
if (playB.getText().startsWith("Play")) {
try {
sequencer.open();
sequencer.setSequence(sequence);
} catch (Exception ex) { ex.printStackTrace(); }
sequencer.start();
playB.setText("Stop");
recordB.setEnabled(false);
} else {
sequencer.stop();
playB.setText("Play");
recordB.setEnabled(true);
}
} else if (button.equals(saveB)) {
try {
File file = new File(System.getProperty("user.dir"));
JFileChooser fc = new JFileChooser(file);
fc.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
if (f.isDirectory()) {
return true;
}
return false;
}
public String getDescription() {
return "Save as .mid file.";
}
});
if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
saveMidiFile(fc.getSelectedFile());
}
} catch (SecurityException ex) {
//JavaSound.showInfoDialog(); remove by wangbo
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public void meta(MetaMessage message) {
if (message.getType() == 47) { // 47 is end of track
playB.setText("Play");
recordB.setEnabled(true);
}
}
public void saveMidiFile(File file) {
try {
int[] fileTypes = MidiSystem.getMidiFileTypes(sequence);
if (fileTypes.length == 0) {
System.out.println("Can't save sequence");
} else {
if (MidiSystem.write(sequence, fileTypes[0], file) == -1) {
throw new IOException("Problems writing to file");
}
}
} catch (SecurityException ex) {
//JavaSound.showInfoDialog(); remove by wangbo
} catch (Exception ex) {
ex.printStackTrace();
}
}
class TrackData extends Object {
Integer chanNum; String name; Track track;
public TrackData(int chanNum, String name, Track track) {
this.chanNum = new Integer(chanNum);
this.name = name;
this.track = track;
}
} // End class TrackData
} // End class RecordFrame
public static void main(String args[]) { final MidiSynth midiSynth = new MidiSynth(); midiSynth.open(); JFrame f = new JFrame("Midi Synthesizer"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); f.getContentPane().add("Center", midiSynth); f.pack(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int w = 760; int h = 470; f.setLocation(screenSize.width/2 - w/2, screenSize.height/2 - h/2); f.setSize(w, h); f.setVisible(true); }}