1 package camidion.chordhelper.mididevice;
3 import java.awt.Component;
4 import java.awt.Rectangle;
5 import java.awt.datatransfer.Transferable;
6 import java.awt.dnd.DnDConstants;
7 import java.awt.dnd.DragGestureEvent;
8 import java.awt.dnd.DragGestureListener;
9 import java.awt.dnd.DragSource;
10 import java.awt.dnd.DragSourceAdapter;
11 import java.awt.dnd.DragSourceDropEvent;
12 import java.awt.dnd.DropTarget;
13 import java.awt.dnd.DropTargetAdapter;
14 import java.awt.dnd.DropTargetDragEvent;
15 import java.awt.dnd.DropTargetDropEvent;
16 import java.awt.dnd.DropTargetListener;
18 import javax.sound.midi.Receiver;
19 import javax.sound.midi.Transmitter;
20 import javax.swing.JList;
21 import javax.swing.ListSelectionModel;
24 * MIDIトランスミッタ({@link Transmitter})のリストビューです。
25 * トランスミッタをこのビューからドラッグし、
26 * {@link ReceiverListView} のレシーバにドロップして接続できます。
28 public class TransmitterListView extends JList<Transmitter> {
30 * このリストによって表示される{@link Transmitter}のリストを保持するデータモデルを返します。
31 * @return 表示される{@link Transmitter}のリストを提供するデータモデル
34 public TransmitterListModel getModel() { return (TransmitterListModel) super.getModel(); }
36 * 引数で指定された{@link Transmitter}のセル範囲を示す、
37 * リストの座標系内の境界の矩形を返します。対応するセルがない場合はnullを返します。
38 * @return セル範囲を示す境界の矩形、またはnull
40 public Rectangle getCellBounds(Transmitter tx) {
41 int index = getModel().indexOf(tx);
42 return getCellBounds(index,index);
45 * 仮想MIDI端子リストビューを生成します。
46 * @param model このビューから参照されるデータモデル
47 * @param cablePane MIDIケーブル描画面
49 public TransmitterListView(TransmitterListModel model, MidiCablePane cablePane) {
51 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
52 setLayoutOrientation(JList.HORIZONTAL_WRAP);
53 setVisibleRowCount(0);
54 setCellRenderer(new TransceiverListCellRenderer<Transmitter>() {
56 public Component getListCellRendererComponent(JList<? extends Transmitter> list,
57 Transmitter value, int index, boolean isSelected, boolean cellHasFocus)
59 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
60 if( value instanceof DummyTransmitter ) {
61 setToolTipText("未接続の送信端子(Tx):ドラッグ&ドロップしてRxに接続できます。");
63 setToolTipText("接続済の送信端子(Tx):ドラッグ&ドロップして接続先Rxを変更、または切断できます。");
68 DragSource dragSource = new DragSource();
69 DragGestureListener dgl = new DragGestureListener() {
71 public void dragGestureRecognized(DragGestureEvent event) {
72 if( (event.getDragAction() & DnDConstants.ACTION_COPY_OR_MOVE) == 0 ) return;
73 Transmitter tx = getModel().getElementAt(locationToIndex(event.getDragOrigin()));
74 MidiCablePane.dragging.setData(tx);
75 event.startDrag(DragSource.DefaultLinkDrop, MidiCablePane.dragging, new DragSourceAdapter() {
77 public void dragDropEnd(DragSourceDropEvent event) {
78 Transmitter tx = (Transmitter)MidiCablePane.dragging.getData();
79 if( ! event.getDropSuccess() ) {
80 getModel().closeTransmitter(tx);
81 } else if( tx instanceof DummyTransmitter ) {
82 Receiver rx = tx.getReceiver();
85 getModel().openTransmitter().setReceiver(rx);
86 } catch (Exception exception) {
87 exception.printStackTrace();
90 cablePane.dragSourceListener.dragDropEnd(event);
95 dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, dgl);
96 dragSource.addDragSourceMotionListener(cablePane.dragSourceMotionListener);
98 // 外からドラッグされたレシーバを、ドロップした場所のトランスミッタに接続する
99 DropTargetListener dtl = new DropTargetAdapter() {
101 public void dragEnter(DropTargetDragEvent event) {
102 if( event.isDataFlavorSupported(DraggingTransceiver.receiverFlavor) ) {
103 event.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
107 public void drop(DropTargetDropEvent event) {
108 event.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
109 if( (event.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) == 0 ) {
110 event.dropComplete(false);
113 Transferable t = event.getTransferable();
114 if( ! t.isDataFlavorSupported(DraggingTransceiver.receiverFlavor) ) {
115 event.dropComplete(false);
119 Object rx = t.getTransferData(DraggingTransceiver.receiverFlavor);
121 Transmitter tx = getModel().getElementAt(locationToIndex(event.getLocation()));
122 if( tx instanceof DummyTransmitter ) tx = getModel().openTransmitter();
123 tx.setReceiver((Receiver)rx);
124 event.dropComplete(true);
128 catch (Exception ex) {
129 ex.printStackTrace();
131 event.dropComplete(false);
134 new DropTarget( this, DnDConstants.ACTION_COPY_OR_MOVE, dtl, true );