Java swing实现支持录音等功能的钢琴程序

今天给大家介绍一下Java实现钢琴的小程序,程序虽小,功能挺多,支持循环播放,录音等功能,首先简单介绍下源码结构:

先看看钢琴界面实现,添加相应滴监听事件:

/*

* @(#)MidiSynth.java 1.15 99/12/03

*

* Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.

*

* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,

* modify and redistribute this software in source and binary code form,

* provided that i) this copyright notice and license appear on all copies of

* the software; and ii) Licensee does not utilize the software in a manner

* which is disparaging to Sun.

*

* This software is provided "AS IS," without a warranty of any kind. ALL

* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY

* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR

* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE

* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING

* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS

* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,

* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER

* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF

* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE

* POSSIBILITY OF SUCH DAMAGES.

*

* This software is not designed or intended for use in on-line control of

* aircraft, air traffic, aircraft navigation or aircraft communications; or in

* the design, construction, operation or maintenance of any nuclear

* facility. Licensee represents and warrants that it will not use or

* redistribute the Software for such purposes.

*/

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.border.*;

import javax.swing.table.*;

import javax.swing.event.*;

import javax.sound.midi.*;

import java.util.Vector;

import java.io.File;

import java.io.IOException;

/**

* Illustrates general MIDI melody instruments and MIDI controllers.

*

* @version @(#)MidiSynth.java 1.15 99/12/03

* @author Brian Lichtenwalter

*/

public class MidiSynth extends JPanel implements ControlContext {

final int PROGRAM = 192;

final int NOTEON = 144;

final int NOTEOFF = 128;

final int SUSTAIN = 64;

final int REVERB = 91;

final int ON = 0, OFF = 1;

final Color jfcBlue = new Color(204, 204, 255);

final Color pink = new Color(255, 175, 175);

Sequencer sequencer;

Sequence sequence;

Synthesizer synthesizer;

Instrument instruments[];

ChannelData channels[];

ChannelData cc; // current channel

JCheckBox mouseOverCB = new JCheckBox("mouseOver", true);

JSlider veloS, presS, bendS, revbS;

JCheckBox soloCB, monoCB, muteCB, sustCB;

Vector keys = new Vector();

Vector whiteKeys = new Vector();

JTable table;

Piano piano;

boolean record;

Track track;

long startTime;

RecordFrame recordFrame;

Controls controls;

public MidiSynth() {

setLayout(new BorderLayout());

JPanel p = new JPanel();

p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));

EmptyBorder eb = new EmptyBorder(5,5,5,5);

BevelBorder bb = new BevelBorder(BevelBorder.LOWERED);

CompoundBorder cb = new CompoundBorder(eb,bb);

p.setBorder(new CompoundBorder(cb,eb));

JPanel pp = new JPanel(new BorderLayout());

pp.setBorder(new EmptyBorder(10,20,10,5));

pp.add(piano = new Piano());

p.add(pp);

p.add(controls = new Controls());

p.add(new InstrumentsTable());

add(p);

}

public void open() {

try {

if (synthesizer == null) {

if ((synthesizer = MidiSystem.getSynthesizer()) == null) {

System.out.println("getSynthesizer() failed!");

return;

}

}

synthesizer.open();

sequencer = MidiSystem.getSequencer();

sequence = new Sequence(Sequence.PPQ, 10);

} catch (Exception ex) { ex.printStackTrace(); return; }

Soundbank sb = synthesizer.getDefaultSoundbank();

if (sb != null) {

instruments = synthesizer.getDefaultSoundbank().getInstruments();

synthesizer.loadInstrument(instruments[0]);

}

MidiChannel midiChannels[] = synthesizer.getChannels();

channels = new ChannelData[midiChannels.length];

for (int i = 0; i < channels.length; i++) {

channels[i] = new ChannelData(midiChannels[i], i);

}

cc = channels[0];

ListSelectionModel lsm = table.getSelectionModel();

lsm.setSelectionInterval(0,0);

lsm = table.getColumnModel().getSelectionModel();

lsm.setSelectionInterval(0,0);

}

public void close() {

if (synthesizer != null) {

synthesizer.close();

}

if (sequencer != null) {

sequencer.close();

}

sequencer = null;

synthesizer = null;

instruments = null;

channels = null;

if (recordFrame != null) {

recordFrame.dispose();

recordFrame = null;

}

}

/**

* given 120 bpm:

* (120 bpm) / (60 seconds per minute) = 2 beats per second

* 2 / 1000 beats per millisecond

* (2 * resolution) ticks per second

* (2 * resolution)/1000 ticks per millisecond, or

* (resolution / 500) ticks per millisecond

* ticks = milliseconds * resolution / 500

*/

public void createShortEvent(int type, int num) {

ShortMessage message = new ShortMessage();

try {

long millis = System.currentTimeMillis() - startTime;

long tick = millis * sequence.getResolution() / 500;

message.setMessage(type+cc.num, num, cc.velocity);

MidiEvent event = new MidiEvent(message, tick);

track.add(event);

} catch (Exception ex) { ex.printStackTrace(); }

}

/**

* Black and white keys or notes on the piano.

*/

class Key extends Rectangle {

int noteState = OFF;

int kNum;

public Key(int x, int y, int width, int height, int num) {

super(x, y, width, height);

kNum = num;

}

public boolean isNoteOn() {

return noteState == ON;

}

public void on() {

setNoteState(ON);

cc.channel.noteOn(kNum, cc.velocity);

if (record) {

createShortEvent(NOTEON, kNum);

}

}

public void off() {

setNoteState(OFF);

cc.channel.noteOff(kNum, cc.velocity);

if (record) {

createShortEvent(NOTEOFF, kNum);

}

}

public void setNoteState(int state) {

noteState = state;

}

} // End class Key

/**

* Piano renders black & white keys and plays the notes for a MIDI

* channel.

*/

class Piano extends JPanel implements MouseListener {

Vector blackKeys = new Vector();

Key prevKey;

final int kw = 16, kh = 80;

public Piano() {

setLayout(new BorderLayout());

setPreferredSize(new Dimension(42*kw, kh+1));

int transpose = 24;

int whiteIDs[] = { 0, 2, 4, 5, 7, 9, 11 };

for (int i = 0, x = 0; i < 6; i++) {

for (int j = 0; j < 7; j++, x += kw) {

int keyNum = i * 12 + whiteIDs[j] + transpose;

whiteKeys.add(new Key(x, 0, kw, kh, keyNum));

}

}

for (int i = 0, x = 0; i < 6; i++, x += kw) {

int keyNum = i * 12 + transpose;

blackKeys.add(new Key((x += kw)-4, 0, kw/2, kh/2, keyNum+1));

blackKeys.add(new Key((x += kw)-4, 0, kw/2, kh/2, keyNum+3));

x += kw;

blackKeys.add(new Key((x += kw)-4, 0, kw/2, kh/2, keyNum+6));

blackKeys.add(new Key((x += kw)-4, 0, kw/2, kh/2, keyNum+8));

blackKeys.add(new Key((x += kw)-4, 0, kw/2, kh/2, keyNum+10));

}

keys.addAll(blackKeys);

keys.addAll(whiteKeys);

addMouseMotionListener(new MouseMotionAdapter() {

public void mouseMoved(MouseEvent e) {

if (mouseOverCB.isSelected()) {

Key key = getKey(e.getPoint());

if (prevKey != null && prevKey != key) {

prevKey.off();

}

if (key != null && prevKey != key) {

key.on();

}

prevKey = key;

repaint();

}

}

});

addMouseListener(this);

}

public void mousePressed(MouseEvent e) {

prevKey = getKey(e.getPoint());

if (prevKey != null) {

prevKey.on();

repaint();

}

}

public void mouseReleased(MouseEvent e) {

if (prevKey != null) {

prevKey.off();

repaint();

}

}

public void mouseExited(MouseEvent e) {

if (prevKey != null) {

prevKey.off();

repaint();

prevKey = null;

}

}

public void mouseClicked(MouseEvent e) { }

public void mouseEntered(MouseEvent e) { }

public Key getKey(Point point) {

for (int i = 0; i < keys.size(); i++) {

if (((Key) keys.get(i)).contains(point)) {

return (Key) keys.get(i);

}

}

return null;

}

public void paint(Graphics g) {

Graphics2D g2 = (Graphics2D) g;

Dimension d = getSize();

g2.setBackground(getBackground());

g2.clearRect(0, 0, d.width, d.height);

g2.setColor(Color.white);

g2.fillRect(0, 0, 42*kw, kh);

for (int i = 0; i < whiteKeys.size(); i++) {

Key key = (Key) whiteKeys.get(i);

if (key.isNoteOn()) {

g2.setColor(record ? pink : jfcBlue);

g2.fill(key);

}

g2.setColor(Color.black);

g2.draw(key);

}

for (int i = 0; i < blackKeys.size(); i++) {

Key key = (Key) blackKeys.get(i);

if (key.isNoteOn()) {

g2.setColor(record ? pink : jfcBlue);

g2.fill(key);

g2.setColor(Color.black);

g2.draw(key);

} else {

g2.setColor(Color.black);

g2.fill(key);

}

}

}

} // End class Piano

/**

* Stores MidiChannel information.

*/

class ChannelData {

MidiChannel channel;

boolean solo, mono, mute, sustain;

int velocity, pressure, bend, reverb;

int row, col, num;

public ChannelData(MidiChannel channel, int num) {

this.channel = channel;

this.num = num;

velocity = pressure = bend = reverb = 64;

}

public void setComponentStates() {

table.setRowSelectionInterval(row, row);

table.setColumnSelectionInterval(col, col);

soloCB.setSelected(solo);

monoCB.setSelected(mono);

muteCB.setSelected(mute);

//sustCB.setSelected(sustain);

JSlider slider[] = { veloS, presS, bendS, revbS };

int v[] = { velocity, pressure, bend, reverb };

for (int i = 0; i < slider.length; i++) {

TitledBorder tb = (TitledBorder) slider[i].getBorder();

String s = tb.getTitle();

tb.setTitle(s.substring(0, s.indexOf('=')+1)+s.valueOf(v[i]));

slider[i].repaint();

}

}

} // End class ChannelData

/**

* Table for 128 general MIDI melody instuments.

*/

class InstrumentsTable extends JPanel {

private String names[] = {

"Piano", "Chromatic Perc.", "Organ", "Guitar",

"Bass", "Strings", "Ensemble", "Brass",

"Reed", "Pipe", "Synth Lead", "Synth Pad",

"Synth Effects", "Ethnic", "Percussive", "Sound Effects" };

private int nRows = 8;

private int nCols = names.length; // just show 128 instruments

public InstrumentsTable() {

setLayout(new BorderLayout());

TableModel dataModel = new AbstractTableModel() {

public int getColumnCount() { return nCols; }

public int getRowCount() { return nRows;}

public Object getValueAt(int r, int c) {

if (instruments != null) {

return instruments[c*nRows+r].getName();

} else {

return Integer.toString(c*nRows+r);

}

}

public String getColumnName(int c) {

return names[c];

}

public Class getColumnClass(int c) {

return getValueAt(0, c).getClass();

}

public boolean isCellEditable(int r, int c) {return false;}

public void setValueAt(Object obj, int r, int c) {}

};

table = new JTable(dataModel);

table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

// Listener for row changes

ListSelectionModel lsm = table.getSelectionModel();

lsm.addListSelectionListener(new ListSelectionListener() {

public void valueChanged(ListSelectionEvent e) {

ListSelectionModel sm = (ListSelectionModel) e.getSource();

if (!sm.isSelectionEmpty()) {

cc.row = sm.getMinSelectionIndex();

}

programChange(cc.col*nRows+cc.row);

}

});

// Listener for column changes

lsm = table.getColumnModel().getSelectionModel();

lsm.addListSelectionListener(new ListSelectionListener() {

public void valueChanged(ListSelectionEvent e) {

ListSelectionModel sm = (ListSelectionModel) e.getSource();

if (!sm.isSelectionEmpty()) {

cc.col = sm.getMinSelectionIndex();

}

programChange(cc.col*nRows+cc.row);

}

});

table.setPreferredScrollableViewportSize(new Dimension(nCols*110, 200));

table.setCellSelectionEnabled(true);

table.setColumnSelectionAllowed(true);

for (int i = 0; i < names.length; i++) {

TableColumn column = table.getColumn(names[i]);

column.setPreferredWidth(110);

}

table.setAutoResizeMode(table.AUTO_RESIZE_OFF);

JScrollPane sp = new JScrollPane(table);

sp.setVerticalScrollBarPolicy(sp.VERTICAL_SCROLLBAR_NEVER);

sp.setHorizontalScrollBarPolicy(sp.HORIZONTAL_SCROLLBAR_ALWAYS);

add(sp);

}

public Dimension getPreferredSize() {

return new Dimension(800,170);

}

public Dimension getMaximumSize() {

return new Dimension(800,170);

}

private void programChange(int program) {

if (instruments != null) {

synthesizer.loadInstrument(instruments[program]);

}

cc.channel.programChange(program);

if (record) {

createShortEvent(PROGRAM, program);

}

}

}

/**

* A collection of MIDI controllers.

*/

class Controls extends JPanel implements ActionListener, ChangeListener, ItemListener {

public JButton recordB;

JMenu menu;

int fileNum = 0;

public Controls() {

setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

setBorder(new EmptyBorder(5,10,5,10));

JPanel p = new JPanel();

p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));

veloS = createSlider("Velocity", p);

presS = createSlider("Pressure", p);

revbS = createSlider("Reverb", p);

// create a slider with a 14-bit range of values for pitch-bend

bendS = create14BitSlider("Bend", p);

p.add(Box.createHorizontalStrut(10));

add(p);

p = new JPanel();

p.setBorder(new EmptyBorder(10,0,10,0));

p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));

JComboBox combo = new JComboBox();

combo.setPreferredSize(new Dimension(120,25));

combo.setMaximumSize(new Dimension(120,25));

for (int i = 1; i <= 16; i++) {

combo.addItem("Channel " + String.valueOf(i));

}

combo.addItemListener(this);

p.add(combo);

p.add(Box.createHorizontalStrut(20));

muteCB = createCheckBox("Mute", p);

soloCB = createCheckBox("Solo", p);

monoCB = createCheckBox("Mono", p);

//sustCB = createCheckBox("Sustain", p);

createButton("All Notes Off", p);

p.add(Box.createHorizontalStrut(10));

p.add(mouseOverCB);

p.add(Box.createHorizontalStrut(10));

recordB = createButton("Record...", p);

add(p);

}

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();

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();

} 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);

}

}

程序有点长,不全部贴出来了,最下面附上下载地址,可以打包下载,下面来看看运行结果:

以上是 Java swing实现支持录音等功能的钢琴程序 的全部内容, 来源链接: utcz.com/p/212856.html

回到顶部