Hi Java coders,
I ported this great Processing midi library to B4J using java on Eclipse
TheMidiBus Processing Midi Library
This library open system midi ports and permits to send/receive MIDI (Musical Instrument Didital Interface) to/from a physical or virtual midi device.
The original library register a callback dispose() that is called when the Processing main app closes, so the library automatically closes all midi devices when the user close the app.
See this relevant Processing code, here the original library register a dispose() callback that is called when the user closes the app, eg with X in the Form top-right corner, or by code:
This will call the dispose() function from Processing when app closes.
As you can see on this code the dispose() function just call the close() function that just call the closeAllMidiDevices(), so all devices are closed and resources freed.
Currently on B4J app I have to manually call Close() to close all devices when exit:
My question is ...
... is there a way to omit the Midi.Close() in the MainForm_Closed or MainForm_CloseRequest
and do it call automatically (as Processing do) when the user closes the B4J app ?
Thanks in advance for any help.
I ported this great Processing midi library to B4J using java on Eclipse
TheMidiBus Processing Midi Library
This library open system midi ports and permits to send/receive MIDI (Musical Instrument Didital Interface) to/from a physical or virtual midi device.
The original library register a callback dispose() that is called when the Processing main app closes, so the library automatically closes all midi devices when the user close the app.
See this relevant Processing code, here the original library register a dispose() callback that is called when the user closes the app, eg with X in the Form top-right corner, or by code:
Java:
/**
* Registers an Object as the parent in order to receieve method callbacks as per {@link PApplet}.
* Calling this will replace the previous parent Object if any was set.
*
* @param parent the object to register.
* @return the previous parent object if any was set.
*/
public Object registerParent(Object parent) {
Object old_parent = this.parent;
this.parent = parent;
if (parent != null) {
if (parent instanceof processing.core.PApplet) {
((processing.core.PApplet) parent).registerMethod("dispose", this); // <<< CALLBACK call dispose() function
}
// Other callbacks not relevant here ...
try {
method_note_on = parent.getClass().getMethod("noteOn", new Class[] { Integer.TYPE, Integer.TYPE, Integer.TYPE });
} catch(Exception e) {
// no such method, or an error.. which is fine, just ignore
}
try {
method_note_off = parent.getClass().getMethod("noteOff", new Class[] { Integer.TYPE, Integer.TYPE, Integer.TYPE });
} catch(Exception e) {
// no such method, or an error.. which is fine, just ignore
}
// etc....
// .....................
// .....................
This will call the dispose() function from Processing when app closes.
As you can see on this code the dispose() function just call the close() function that just call the closeAllMidiDevices(), so all devices are closed and resources freed.
Java:
/**
* Closes this MidiBus and all connections it has with other MIDI devices.
* This method exit as per standard Processing library syntax and is called automatically whenever the parent applet shuts down.
* It is functionaly equivalent to close() and stop().
*
* @see #close()
*/
public void dispose() {
close();
}
/**
* Closes this MidiBus and all connections it has with other MIDI devices.
* This method exists as per standard javax.sound.midi syntax.
* It is functionaly equivalent to stop() and dispose(). *
*
* @see #dispose()
*/
public void close() {
closeAllMidiDevices();
}
/**
* Closes all MidiDevices, should only be called when closing the application,
* will interrupt all MIDI I/O. Call publicly from stop(), close() or dispose()
*
* @see #close()
* @see #dispose()
*/
void closeAllMidiDevices() {
if (MidiBus.available_devices == null) findMidiDevices();
if (MidiBus.available_devices == null) return;
MidiDevice device;
for (int i = 0;i < MidiBus.available_devices.length;i++) {
try {
device = MidiSystem.getMidiDevice(MidiBus.available_devices[i]);
if (device == null) continue;
if (device.isOpen()) device.close();
} catch(MidiUnavailableException e) {
//Device wasn't available, which is fine since we wanted to close it anyways
}
}
}
Currently on B4J app I have to manually call Close() to close all devices when exit:
B4X:
Sub MainForm_CloseRequest (EventData As Event)
Log("Clear and Close all Midi devices ...")
Midi.Close
End Sub
My question is ...
... is there a way to omit the Midi.Close() in the MainForm_Closed or MainForm_CloseRequest
and do it call automatically (as Processing do) when the user closes the B4J app ?
Thanks in advance for any help.
Last edited: