From 72a6b32db34542406ae6974fa3c09cb13ceca9f1 Mon Sep 17 00:00:00 2001 From: Akiyoshi Kamide Date: Wed, 11 May 2016 02:34:09 +0900 Subject: [PATCH] =?utf8?q?MIDI=20Device=20Connection=20=E3=81=8B=E3=82=89?= =?utf8?q?=20MIDI=20Editor=20=E3=81=B8=E6=84=8F=E5=9B=B3=E3=81=97=E3=81=AA?= =?utf8?q?=E3=81=84=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7=E3=82=AF=E3=83=88?= =?utf8?q?=E3=82=92=20=E3=83=89=E3=83=A9=E3=83=83=E3=82=B0=EF=BC=86?= =?utf8?q?=E3=83=89=E3=83=AD=E3=83=83=E3=83=97=E3=81=97=E3=81=A6=E3=82=82?= =?utf8?q?=20NullPointerException=20=E3=81=8C=E5=87=BA=E3=81=AA=E3=81=84?= =?utf8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/camidion/chordhelper/ChordHelperApplet.java | 4 +- .../chordhelper/mididevice/MidiDeviceTreeView.java | 24 ++++----- .../mididevice/MidiOpenedDevicesView.java | 44 ++++++--------- .../mididevice/MidiTransceiverListModelList.java | 4 +- .../chordhelper/midieditor/MidiSequenceEditor.java | 63 +++++++++++----------- 5 files changed, 62 insertions(+), 77 deletions(-) diff --git a/src/camidion/chordhelper/ChordHelperApplet.java b/src/camidion/chordhelper/ChordHelperApplet.java index 04dc825..97f8455 100644 --- a/src/camidion/chordhelper/ChordHelperApplet.java +++ b/src/camidion/chordhelper/ChordHelperApplet.java @@ -284,7 +284,7 @@ public class ChordHelperApplet extends JApplet { */ public static class VersionInfo { public static final String NAME = "MIDI Chord Helper"; - public static final String VERSION = "Ver.20160509.1"; + public static final String VERSION = "Ver.20160510.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/"; @@ -466,7 +466,7 @@ public class ChordHelperApplet extends JApplet { } ); deviceModelList.editorDialog.setIconImage(iconImage); - new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, deviceModelList.editorDialog, true); + new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, deviceModelList.editorDialog.dropTargetListener, true); keyboardPanel.setEventDialog(deviceModelList.editorDialog.eventDialog); midiConnectionDialog = new MidiDeviceDialog(deviceModelList); midiConnectionDialog.setIconImage(iconImage); diff --git a/src/camidion/chordhelper/mididevice/MidiDeviceTreeView.java b/src/camidion/chordhelper/mididevice/MidiDeviceTreeView.java index 4ddaa6c..ff02560 100644 --- a/src/camidion/chordhelper/mididevice/MidiDeviceTreeView.java +++ b/src/camidion/chordhelper/mididevice/MidiDeviceTreeView.java @@ -14,37 +14,36 @@ import java.awt.dnd.DragSourceListener; import javax.swing.JInternalFrame; import javax.swing.JTree; +import javax.swing.ListModel; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; import javax.swing.event.InternalFrameListener; import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.TreeModel; /** * MIDIデバイスツリービュー */ public class MidiDeviceTreeView extends JTree { - public static final DataFlavor TREE_FLAVOR = new DataFlavor(TreeModel.class,"TreeModel"); + public static final DataFlavor LIST_MODEL_FLAVOR = new DataFlavor(ListModel.class,"ListModel"); public class DraggingObject implements Transferable { - private DataFlavor flavors[] = {TREE_FLAVOR}; + private DataFlavor flavors[] = {LIST_MODEL_FLAVOR}; private MidiTransceiverListModel trxListModel; @Override public Object getTransferData(DataFlavor flavor) { - return TREE_FLAVOR.equals(flavor) ? trxListModel : null; + return flavor.getRepresentationClass().isInstance(trxListModel) ? trxListModel : null; } @Override public DataFlavor[] getTransferDataFlavors() { return flavors; } @Override public boolean isDataFlavorSupported(DataFlavor flavor) { - return TREE_FLAVOR.equals(flavor); + return flavors[0].equals(flavor); } }; private DraggingObject draggingObject = new DraggingObject(); /** - * このツリーからドラッグしたMIDIデバイスのドロップが成功し、 - * MIDIデバイスが開かれたときに再描画するためのリスナー + * このツリーからドラッグしたMIDIデバイスのドロップが成功したときに再描画するためのリスナー */ private DragSourceListener dragSourceListener = new DragSourceAdapter() { @Override @@ -65,6 +64,8 @@ public class MidiDeviceTreeView extends JTree { @Override public void internalFrameClosing(InternalFrameEvent e) { repaint(); } }; + @Override + public MidiDeviceTreeModel getModel() { return (MidiDeviceTreeModel) super.getModel(); } /** * MIDIデバイスツリービューを構築します。 * @param model このビューにデータを提供するモデル @@ -78,10 +79,9 @@ public class MidiDeviceTreeView extends JTree { if( (dge.getDragAction() & DnDConstants.ACTION_COPY_OR_MOVE) == 0 ) return; Point origin = dge.getDragOrigin(); Object leaf = getPathForLocation(origin.x, origin.y).getLastPathComponent(); - if( leaf instanceof MidiTransceiverListModel ) { - draggingObject.trxListModel = (MidiTransceiverListModel)leaf; - dge.startDrag(DragSource.DefaultMoveDrop, draggingObject, dragSourceListener); - } + if( ! (leaf instanceof MidiTransceiverListModel) ) return; + draggingObject.trxListModel = (MidiTransceiverListModel)leaf; + dge.startDrag(DragSource.DefaultMoveDrop, draggingObject, dragSourceListener); } } ); @@ -102,6 +102,4 @@ public class MidiDeviceTreeView extends JTree { // 初期状態でツリーノードを開いた状態にする for( int row = 0; row < getRowCount() ; row++ ) expandRow(row); } - @Override - public MidiDeviceTreeModel getModel() { return (MidiDeviceTreeModel) super.getModel(); } } diff --git a/src/camidion/chordhelper/mididevice/MidiOpenedDevicesView.java b/src/camidion/chordhelper/mididevice/MidiOpenedDevicesView.java index da9a7e7..ea79610 100644 --- a/src/camidion/chordhelper/mididevice/MidiOpenedDevicesView.java +++ b/src/camidion/chordhelper/mididevice/MidiOpenedDevicesView.java @@ -10,6 +10,8 @@ import java.awt.dnd.DropTargetListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.beans.PropertyVetoException; +import java.util.HashMap; +import java.util.Map; import javax.sound.midi.MidiUnavailableException; import javax.swing.JDesktopPane; @@ -24,6 +26,9 @@ import javax.swing.tree.TreePath; * 開いている MIDI デバイスを置くためのデスクトップビュー */ public class MidiOpenedDevicesView extends JDesktopPane implements TreeSelectionListener { + + private Map modelToFrame = new HashMap<>(); + /** * ツリー上で選択状態が変わったとき、このデスクトップ上のフレームの選択状態に反映します。 */ @@ -35,10 +40,9 @@ public class MidiOpenedDevicesView extends JDesktopPane implements TreeSelection if( lastSelected instanceof MidiTransceiverListModel ) { MidiTransceiverListModel deviceModel = (MidiTransceiverListModel)lastSelected; if( deviceModel.getMidiDevice().isOpen() ) { - // 開いているMIDIデバイスがツリー上で選択されたら - // このデスクトップでも選択する + // 開いているMIDIデバイスがツリー上で選択されたら、対応するフレームを選択 try { - getMidiDeviceFrameOf(deviceModel).setSelected(true); + modelToFrame.get(deviceModel).setSelected(true); } catch( PropertyVetoException ex ) { ex.printStackTrace(); } @@ -46,8 +50,7 @@ public class MidiOpenedDevicesView extends JDesktopPane implements TreeSelection } } } - // 閉じているMIDIデバイス、またはMIDIデバイス以外のノードがツリー上で選択されたら - // このデスクトップ上のMIDIデバイスフレームをすべて非選択にする + // それ以外が選択されたら、現在選択されているフレームを非選択 JInternalFrame frame = getSelectedFrame(); if( ! (frame instanceof MidiDeviceFrame) ) return; try { @@ -56,31 +59,13 @@ public class MidiOpenedDevicesView extends JDesktopPane implements TreeSelection ex.printStackTrace(); } } - - /** - * 指定されたMIDIデバイスモデルに対するMIDIデバイスフレームを返します。 - * - * @param deviceModel MIDIデバイスモデル - * @return 対応するMIDIデバイスフレーム(ない場合 null) - */ - private MidiDeviceFrame getMidiDeviceFrameOf(MidiTransceiverListModel deviceModel) { - JInternalFrame[] frames = getAllFramesInLayer(JLayeredPane.DEFAULT_LAYER); - for( JInternalFrame frame : frames ) { - if( ! (frame instanceof MidiDeviceFrame) ) continue; - MidiDeviceFrame deviceFrame = (MidiDeviceFrame)frame; - if( deviceFrame.getMidiTransceiverListView().getModel().equals(deviceModel) ) { - return deviceFrame; - } - } - return null; - } /** * ツリー表示からこのデスクトップにドロップされたMIDIデバイスモデルに対応するフレームを表示するためのリスナー */ private DropTargetListener dropTargetListener = new DropTargetAdapter() { @Override public void dragEnter(DropTargetDragEvent dtde) { - if( dtde.getTransferable().isDataFlavorSupported(MidiDeviceTreeView.TREE_FLAVOR) ) { + if( dtde.getTransferable().isDataFlavorSupported(MidiDeviceTreeView.LIST_MODEL_FLAVOR) ) { dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); } } @@ -94,11 +79,11 @@ public class MidiOpenedDevicesView extends JDesktopPane implements TreeSelection return; } Transferable t = dtde.getTransferable(); - if( ! t.isDataFlavorSupported(MidiDeviceTreeView.TREE_FLAVOR) ) { + if( ! t.isDataFlavorSupported(MidiDeviceTreeView.LIST_MODEL_FLAVOR) ) { dtde.dropComplete(false); return; } - Object data = t.getTransferData(MidiDeviceTreeView.TREE_FLAVOR); + Object data = t.getTransferData(MidiDeviceTreeView.LIST_MODEL_FLAVOR); if( ! (data instanceof MidiTransceiverListModel) ) { dtde.dropComplete(false); return; @@ -137,7 +122,7 @@ public class MidiOpenedDevicesView extends JDesktopPane implements TreeSelection // デバイスが正常に開かれたことを確認できたら // ドロップした場所へフレームを配置して可視化する。 // - MidiDeviceFrame deviceFrame = getMidiDeviceFrameOf(deviceModel); + MidiDeviceFrame deviceFrame = modelToFrame.get(deviceModel); deviceFrame.setLocation(dtde.getLocation()); deviceFrame.setVisible(true); } @@ -164,8 +149,11 @@ public class MidiOpenedDevicesView extends JDesktopPane implements TreeSelection int toY = 10; MidiTransceiverListModelList deviceModels = deviceTreeView.getModel().getTransceiverListModelList(); for( MidiTransceiverListModel deviceModel : deviceModels ) { - deviceModel.addListDataListener(cablePane.midiConnecterListDataListener); MidiDeviceFrame frame = new MidiDeviceFrame(new MidiTransceiverListView(deviceModel, cablePane)); + modelToFrame.put(deviceModel, frame); + // + // MIDIデバイスモデルのMIDIコネクタリストが変化したときにMIDIケーブルを再描画 + deviceModel.addListDataListener(cablePane.midiConnecterListDataListener); // // デバイスフレームが開閉したときの動作 frame.addInternalFrameListener(cablePane.midiDeviceFrameListener); diff --git a/src/camidion/chordhelper/mididevice/MidiTransceiverListModelList.java b/src/camidion/chordhelper/mididevice/MidiTransceiverListModelList.java index 7c8a93d..01df8f0 100644 --- a/src/camidion/chordhelper/mididevice/MidiTransceiverListModelList.java +++ b/src/camidion/chordhelper/mididevice/MidiTransceiverListModelList.java @@ -13,8 +13,8 @@ import camidion.chordhelper.ChordHelperApplet; import camidion.chordhelper.midieditor.MidiSequenceEditor; /** - * すべてのMIDIデバイスモデル {@link MidiTransceiverListModel} を収容するリストです。 - * {@link MidiDeviceTreeModel} もこのリストを参照します。 + * 仮想MIDIデバイスを含めた、すべてのMIDIデバイスモデル {@link MidiTransceiverListModel} + * を収容するリストです。{@link MidiDeviceTreeModel} もこのリストを参照します。 */ public class MidiTransceiverListModelList extends Vector { diff --git a/src/camidion/chordhelper/midieditor/MidiSequenceEditor.java b/src/camidion/chordhelper/midieditor/MidiSequenceEditor.java index 8c6b57c..6a21231 100644 --- a/src/camidion/chordhelper/midieditor/MidiSequenceEditor.java +++ b/src/camidion/chordhelper/midieditor/MidiSequenceEditor.java @@ -9,9 +9,9 @@ import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; -import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ComponentAdapter; @@ -79,10 +79,10 @@ import camidion.chordhelper.music.MIDISpec; * MIDIエディタ(MIDI Editor/Playlist for MIDI Chord Helper) * * @author - * Copyright (C) 2006-2014 Akiyoshi Kamide + * Copyright (C) 2006-2016 Akiyoshi Kamide * http://www.yk.rim.or.jp/~kamide/music/chordhelper/ */ -public class MidiSequenceEditor extends JDialog implements DropTargetListener { +public class MidiSequenceEditor extends JDialog { private static VirtualMidiDevice virtualMidiDevice = new AbstractVirtualMidiDevice() { { info = new MyInfo(); @@ -162,38 +162,37 @@ public class MidiSequenceEditor extends JDialog implements DropTargetListener { JOptionPane.WARNING_MESSAGE ) == JOptionPane.YES_OPTION ; } - @Override - public void dragEnter(DropTargetDragEvent event) { - if( event.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ) { - event.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); - } - } - @Override - public void dragExit(DropTargetEvent event) {} - @Override - public void dragOver(DropTargetDragEvent event) {} - @Override - public void dropActionChanged(DropTargetDragEvent event) {} - @Override - @SuppressWarnings("unchecked") - public void drop(DropTargetDropEvent event) { - event.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); - try { - int action = event.getDropAction(); - if ( (action & DnDConstants.ACTION_COPY_OR_MOVE) != 0 ) { - Transferable t = event.getTransferable(); - Object data = t.getTransferData(DataFlavor.javaFileListFlavor); - loadAndPlay((List)data); - event.dropComplete(true); - return; + /** + * ドロップされた複数のMIDIファイルを読み込むリスナー + */ + public final DropTargetListener dropTargetListener = new DropTargetAdapter() { + @Override + public void dragEnter(DropTargetDragEvent event) { + if( event.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ) { + event.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); } - event.dropComplete(false); } - catch (Exception ex) { - ex.printStackTrace(); + @Override + @SuppressWarnings("unchecked") + public void drop(DropTargetDropEvent event) { + event.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); + try { + int action = event.getDropAction(); + if ( (action & DnDConstants.ACTION_COPY_OR_MOVE) != 0 ) { + Transferable t = event.getTransferable(); + if( t.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ) { + loadAndPlay((List)t.getTransferData(DataFlavor.javaFileListFlavor)); + event.dropComplete(true); + return; + } + } + } + catch (Exception ex) { + ex.printStackTrace(); + } event.dropComplete(false); } - } + }; /** * 複数のMIDIファイルを読み込み、再生されていなかったら再生します。 * すでに再生されていた場合、このエディタダイアログを表示します。 @@ -1225,7 +1224,7 @@ public class MidiSequenceEditor extends JDialog implements DropTargetListener { setTitle("MIDI Editor/Playlist - MIDI Chord Helper"); setBounds( 150, 200, 900, 500 ); setLayout(new FlowLayout()); - new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this, true); + new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, dropTargetListener, true); JPanel playlistPanel = new JPanel() {{ JPanel playlistOperationPanel = new JPanel() {{ setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS)); -- 2.11.0