OSDN Git Service

MIDIデバイス周りの修正
authorAkiyoshi Kamide <kamide@yk.rim.or.jp>
Sun, 19 Jun 2016 05:15:08 +0000 (14:15 +0900)
committerAkiyoshi Kamide <kamide@yk.rim.or.jp>
Sun, 19 Jun 2016 05:15:08 +0000 (14:15 +0900)
・新規TxをドラッグしてもすぐにTxを増やさないようにした
・仮想MIDIデバイスの情報としてMIDI Chord Helper自体の情報を表示
・その他リファクタリング

src/camidion/chordhelper/ChordHelperApplet.java
src/camidion/chordhelper/mididevice/MidiCablePane.java
src/camidion/chordhelper/mididevice/MidiDeviceModel.java
src/camidion/chordhelper/mididevice/MidiReceiverListView.java
src/camidion/chordhelper/mididevice/MidiTransmitterListView.java
src/camidion/chordhelper/pianokeyboard/PianoKeyboard.java

index 436862d..d567cbd 100644 (file)
@@ -285,7 +285,7 @@ public class ChordHelperApplet extends JApplet {
         */
        public static class VersionInfo {
                public static final String      NAME = "MIDI Chord Helper";
-               public static final String      VERSION = "Ver.20160618.1";
+               public static final String      VERSION = "Ver.20160619.1";
                public static final String      COPYRIGHT = "Copyright (C) 2004-2016";
                public static final String      AUTHER = "@きよし - Akiyoshi Kamide";
                public static final String      URL = "http://www.yk.rim.or.jp/~kamide/music/chordhelper/";
index 949be78..5788ee9 100644 (file)
@@ -19,7 +19,6 @@ import java.util.Arrays;
 import java.util.Hashtable;
 import java.util.List;
 
-import javax.sound.midi.MidiDevice;
 import javax.sound.midi.Receiver;
 import javax.sound.midi.Transmitter;
 import javax.swing.JComponent;
@@ -142,10 +141,10 @@ public class MidiCablePane extends JComponent implements DragSourceMotionListene
                for( JInternalFrame frame : frames ) {
                        if( ! (frame instanceof MidiDeviceFrame) ) continue;
                        MidiDeviceFrame fromFrame = (MidiDeviceFrame)frame;
-                       MidiDevice fromDevice = fromFrame.getMidiDeviceModel().getMidiDevice();
+                       MidiDeviceModel fromDeviceModel = fromFrame.getMidiDeviceModel();
                        //
                        // Receiverからドラッグされている線を描画
-                       if( draggingPoint != null && fromDevice.getReceivers().indexOf(dragging.getData()) >= 0 ) {
+                       if( draggingPoint != null && fromDeviceModel.getMidiDevice().getReceivers().contains(dragging.getData()) ) {
                                Receiver rx = (Receiver)dragging.getData();
                                Rectangle rxBounds = fromFrame.getBoundsOf(rx);
                                if( rxBounds == null ) continue;
@@ -155,8 +154,10 @@ public class MidiCablePane extends JComponent implements DragSourceMotionListene
                                g2.drawLine(rxBounds.x, rxBounds.y, draggingPoint.x, draggingPoint.y);
                        }
                        // Transmitterを全部スキャン
-                       List<Transmitter> txList = fromDevice.getTransmitters();
-                       for( Transmitter tx : txList ) {
+                       MidiDeviceModel.TransmitterListModel txListModel = fromDeviceModel.getTransmitterListModel();
+                       int ntx = txListModel == null ? 0 : txListModel.getSize();
+                       for( int index=0 ; index < ntx; index++ ) {
+                               Transmitter tx = txListModel.getElementAt(index);
                                //
                                // Transmitterの場所を特定
                                Rectangle txBounds = fromFrame.getBoundsOf(tx);
index 4c257fc..43c39ac 100644 (file)
@@ -30,7 +30,28 @@ public class MidiDeviceModel {
                 * @param element 探したい要素
                 * @return 位置のインデックス(先頭が 0、見つからないとき -1)
                 */
-               public int indexOf(Receiver element) { return device.getReceivers().indexOf(element); }
+               public int indexOf(Object element) { return device.getReceivers().indexOf(element); }
+               /**
+                * {@link MidiDevice#getReceiver()} でレシーバを1個開きます。
+                * すでに1個開いている場合は無視されます。
+                *
+                * @throws MidiUnavailableException リソースの制約のためにレシーバを使用できない場合にスローされる
+                */
+               public void openReceiver() throws MidiUnavailableException {
+                       if( device.getReceivers().isEmpty() ) device.getReceiver();
+               }
+               /**
+                * このリストモデルの{@link Receiver}に接続された他デバイスの{@link Transmitter}を全て閉じます。
+                */
+               public void closePeerTransmitters() {
+                       List<Receiver> rxList = device.getReceivers();
+                       for( Receiver rx : rxList ) {
+                               for( MidiDeviceModel m : deviceModelList ) {
+                                       if( m == MidiDeviceModel.this || m.txListModel == null ) continue;
+                                       m.txListModel.closePeerTransmitterOf(rx);
+                               }
+                       }
+               }
        }
 
        /**
@@ -42,10 +63,11 @@ public class MidiDeviceModel {
         */
        public class TransmitterListModel extends AbstractListModel<Transmitter> {
                private NewTransmitter newTransmitter = new NewTransmitter() {
+                       private Receiver receiver;
                        @Override
-                       public void setReceiver(Receiver receiver) { }
+                       public void setReceiver(Receiver receiver) { this.receiver = receiver; }
                        @Override
-                       public Receiver getReceiver() { return null; }
+                       public Receiver getReceiver() { return receiver; }
                        @Override
                        public void close() { }
                };
@@ -66,7 +88,7 @@ public class MidiDeviceModel {
                 * @param element 探したい要素
                 * @return 位置
                 */
-               public int indexOf(Transmitter element) {
+               public int indexOf(Object element) {
                        List<Transmitter> txList = device.getTransmitters();
                        return element.equals(newTransmitter) ? txList.size() : txList.indexOf(element);
                }
@@ -86,21 +108,20 @@ public class MidiDeviceModel {
                        return tx;
                }
                /**
-                * 指定の位置にある接続可能な{@link Transmitter}を返します。
-                * 新規Transmitterの場合、{@link #getUnconnectedTransmitter()}からの値を返します。
-                * @param index 位置(0が先頭、最後が新規)
-                * @return
+                * このリストモデルの{@link #getUnconnectedTransmitter()}が返した{@link Transmitter}を、
+                * 相手のMIDIデバイスが持つ最初の{@link Receiver}に接続します。
+                *
+                * @param anotherDeviceModel 接続相手のMIDIデバイス
                 * @throws MidiUnavailableException リソースの制約のためにトランスミッタを使用できない場合にスローされる
                 */
-               public Transmitter getConnectableTransmitterAt(int index) throws MidiUnavailableException {
-                       Transmitter tx = getElementAt(index);
-                       if( tx instanceof NewTransmitter ) tx = getUnconnectedTransmitter();
-                       return tx;
+               public void connectToFirstReceiverOfDevice(MidiDeviceModel anotherDeviceModel) throws MidiUnavailableException {
+                       List<Receiver> rxList = anotherDeviceModel.device.getReceivers();
+                       if( ! rxList.isEmpty() ) txListModel.getUnconnectedTransmitter().setReceiver(rxList.get(0));
                }
                /**
-                * このリストモデルで開いている指定の{@link Transmitter}があれば、
-                * それを閉じて表示を更新します。
-                * ない場合は無視されます。
+                * 指定の{@link Transmitter}がリストにあれば、それを閉じます。
+                * 閉じるとリストから自動的に削除されるので、表示の更新も行います。
+                *
                 * @param tx このリストモデルで開いている{@link Transmitter}
                 */
                public void close(Transmitter tx) {
@@ -109,21 +130,9 @@ public class MidiDeviceModel {
                        fireIntervalRemoved(this, 0, getSize());
                }
                /**
-                * このリストモデルの{@link #getUnconnectedTransmitter()}が返した{@link Transmitter}を、
-                * 相手のMIDIデバイスが持つ最初の{@link Receiver}に接続します。
-                *
-                * @param anotherDeviceModel 接続相手のMIDIデバイス
-                * @throws MidiUnavailableException リソースの制約のためにトランスミッタを使用できない場合にスローされる
-                */
-               public void connectToFirstReceiverOfDevice(MidiDeviceModel anotherDeviceModel) throws MidiUnavailableException {
-                       if( ! anotherDeviceModel.rxSupported() ) return;
-                       List<Receiver> rxList = anotherDeviceModel.device.getReceivers();
-                       if( rxList.isEmpty() ) return;
-                       txListModel.getUnconnectedTransmitter().setReceiver(rxList.get(0));
-               }
-               /**
                 * このリストモデルにある{@link Transmitter}のうち、
                 * 引数で指定された{@link Receiver}へデータを送信しているものを全て閉じます。
+                * 閉じるとリストから自動的に削除されるので、表示の更新も行います。
                 */
                private void closePeerTransmitterOf(Receiver rx) {
                        List<Transmitter> originalTxList = device.getTransmitters();
@@ -265,7 +274,7 @@ public class MidiDeviceModel {
         */
        public void open() throws MidiUnavailableException {
                device.open();
-               if( rxListModel != null && device.getReceivers().isEmpty() ) device.getReceiver();
+               if( rxListModel != null ) rxListModel.openReceiver();
        }
        /**
         * このMIDIデバイスを {@link MidiDevice#close()} で閉じます。
@@ -273,14 +282,7 @@ public class MidiDeviceModel {
         * それらも全て閉じます。
         */
        public void close() {
-               if( rxListModel != null ) {
-                       List<Receiver> rxList = device.getReceivers();
-                       for( Receiver rx : rxList ) {
-                               for( MidiDeviceModel m : deviceModelList ) {
-                                       if( m != this && m.txListModel != null ) m.txListModel.closePeerTransmitterOf(rx);
-                               }
-                       }
-               }
+               if( rxListModel != null ) rxListModel.closePeerTransmitters();
                device.close();
        }
 }
index 8883372..6f4403c 100644 (file)
@@ -92,7 +92,7 @@ public class MidiReceiverListView extends JList<Receiver> {
                dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, dgl);
                dragSource.addDragSourceMotionListener(cablePane);
                //
-               // トランスミッタのドロップを受け付け
+               // 外からドラッグされたトランスミッタを、ドロップした場所のレシーバに接続す
                DropTargetListener dtl = new DropTargetAdapter() {
                        @Override
                        public void dragEnter(DropTargetDragEvent event) {
@@ -116,8 +116,7 @@ public class MidiReceiverListView extends JList<Receiver> {
                                try {
                                        Object sourceTx = t.getTransferData(DraggingTransceiver.transmitterFlavor);
                                        if( sourceTx != null ) {
-                                               int targetRxIndex = locationToIndex(event.getLocation());
-                                               ((Transmitter)sourceTx).setReceiver(getModel().getElementAt(targetRxIndex));
+                                               ((Transmitter)sourceTx).setReceiver(getModel().getElementAt(locationToIndex(event.getLocation())));
                                                event.dropComplete(true);
                                                return;
                                        }
index 1c27951..9f6aef8 100644 (file)
@@ -22,6 +22,8 @@ import javax.swing.JList;
 import javax.swing.ListCellRenderer;
 import javax.swing.ListSelectionModel;
 
+import camidion.chordhelper.mididevice.MidiDeviceModel.NewTransmitter;
+
 /**
  * MIDIトランスミッタ({@link Transmitter})のリストビューです。
  * トランスミッタをこのビューからドラッグし、
@@ -89,16 +91,24 @@ public class MidiTransmitterListView extends JList<Transmitter> {
                        public void dragGestureRecognized(DragGestureEvent event) {
                                if( (event.getDragAction() & DnDConstants.ACTION_COPY_OR_MOVE) == 0 ) return;
                                int draggingIndex = locationToIndex(event.getDragOrigin());
-                               try {
-                                       MidiCablePane.dragging.setData(getModel().getConnectableTransmitterAt(draggingIndex));
-                               } catch (Exception exception) {
-                                       exception.printStackTrace();
-                                       return;
-                               }
+                               MidiCablePane.dragging.setData(getModel().getElementAt(draggingIndex));
                                event.startDrag(DragSource.DefaultLinkDrop, MidiCablePane.dragging, new DragSourceAdapter() {
                                        @Override
                                        public void dragDropEnd(DragSourceDropEvent event) {
-                                               if( ! event.getDropSuccess() ) getModel().close((Transmitter)MidiCablePane.dragging.getData());
+                                               Transmitter droppedTx = (Transmitter)MidiCablePane.dragging.getData();
+                                               if( ! event.getDropSuccess() ) {
+                                                       // 所定の場所にドロップされなかったトランスミッタを閉じる
+                                                       getModel().close(droppedTx);
+                                               } else if( droppedTx instanceof MidiDeviceModel.NewTransmitter ) {
+                                                       // ドロップされたダミートランスミッタに接続されたレシーバを
+                                                       // 新しい本物のトランスミッタに付け替える
+                                                       try {
+                                                               getModel().getUnconnectedTransmitter().setReceiver(droppedTx.getReceiver());
+                                                       } catch (Exception exception) {
+                                                               exception.printStackTrace();
+                                                       }
+                                                       droppedTx.setReceiver(null);
+                                               }
                                                cablePane.dragSourceListener.dragDropEnd(event);
                                        }
                                });
@@ -108,7 +118,7 @@ public class MidiTransmitterListView extends JList<Transmitter> {
                dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, dgl);
                dragSource.addDragSourceMotionListener(cablePane);
                //
-               // レシーバのドロップを受け付け
+               // 外からドラッグされたレシーバを、ドロップした場所のトランスミッタに接続す
                DropTargetListener dtl = new DropTargetAdapter() {
                        @Override
                        public void dragEnter(DropTargetDragEvent event) {
@@ -132,8 +142,9 @@ public class MidiTransmitterListView extends JList<Transmitter> {
                                try {
                                        Object sourceRx = t.getTransferData(DraggingTransceiver.receiverFlavor);
                                        if( sourceRx != null ) {
-                                               int targetTxIndex = locationToIndex(event.getLocation());
-                                               getModel().getConnectableTransmitterAt(targetTxIndex).setReceiver((Receiver)sourceRx);
+                                               Transmitter tx = getModel().getElementAt(locationToIndex(event.getLocation()));
+                                               if( tx instanceof NewTransmitter ) tx = getModel().getUnconnectedTransmitter();
+                                               tx.setReceiver((Receiver)sourceRx);
                                                event.dropComplete(true);
                                                return;
                                        }
index e00e5f6..8b70650 100644 (file)
@@ -30,6 +30,7 @@ import javax.swing.event.ListDataEvent;
 import javax.swing.event.ListDataListener;
 
 import camidion.chordhelper.ChordDisplayLabel;
+import camidion.chordhelper.ChordHelperApplet;
 import camidion.chordhelper.anogakki.AnoGakkiPane;
 import camidion.chordhelper.chordmatrix.ChordMatrix;
 import camidion.chordhelper.mididevice.AbstractMidiChannelStatus;
@@ -250,7 +251,10 @@ public class PianoKeyboard extends JComponent {
        public VirtualMidiDevice midiDevice = new AbstractVirtualMidiDevice() {
                class MyInfo extends Info {
                        protected MyInfo() {
-                               super("Virtual MIDI Keyboard","Unknown vendor","Software MIDI keyboard","");
+                               super(ChordHelperApplet.VersionInfo.NAME,
+                                               ChordHelperApplet.VersionInfo.AUTHER,
+                                               "Software MIDI keyboard with indicator",
+                                               ChordHelperApplet.VersionInfo.VERSION);
                        }
                }
                /**