OSDN Git Service

リファクタリング
[midichordhelper/MIDIChordHelper.git] / src / camidion / chordhelper / mididevice / TransmitterListView.java
1 package camidion.chordhelper.mididevice;
2
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;
17
18 import javax.sound.midi.Receiver;
19 import javax.sound.midi.Transmitter;
20 import javax.swing.JList;
21 import javax.swing.ListSelectionModel;
22
23 /**
24  * MIDIトランスミッタ({@link Transmitter})のリストビューです。
25  * トランスミッタをこのビューからドラッグし、
26  * {@link ReceiverListView} のレシーバにドロップして接続できます。
27  */
28 public class TransmitterListView extends JList<Transmitter> {
29         /**
30          * このリストによって表示される{@link Transmitter}のリストを保持するデータモデルを返します。
31          * @return 表示される{@link Transmitter}のリストを提供するデータモデル
32          */
33         @Override
34         public TransmitterListModel getModel() { return (TransmitterListModel) super.getModel(); }
35         /**
36          * 引数で指定された{@link Transmitter}のセル範囲を示す、
37          * リストの座標系内の境界の矩形を返します。対応するセルがない場合はnullを返します。
38          * @return セル範囲を示す境界の矩形、またはnull
39          */
40         public Rectangle getCellBounds(Transmitter tx) {
41                 int index = getModel().indexOf(tx);
42                 return getCellBounds(index,index);
43         }
44         /**
45          * 仮想MIDI端子リストビューを生成します。
46          * @param model このビューから参照されるデータモデル
47          * @param cablePane MIDIケーブル描画面
48          */
49         public TransmitterListView(TransmitterListModel model, MidiCablePane cablePane) {
50                 super(model);
51                 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
52                 setLayoutOrientation(JList.HORIZONTAL_WRAP);
53                 setVisibleRowCount(0);
54                 setCellRenderer(new TransceiverListCellRenderer<Transmitter>() {
55                         @Override
56                         public Component getListCellRendererComponent(JList<? extends Transmitter> list,
57                                         Transmitter value, int index, boolean isSelected, boolean cellHasFocus)
58                         {
59                                 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
60                                 if( value instanceof DummyTransmitter ) {
61                                         setToolTipText("未接続の送信端子(Tx):ドラッグ&ドロップしてRxに接続できます。");
62                                 } else {
63                                         setToolTipText("接続済の送信端子(Tx):ドラッグ&ドロップして接続先Rxを変更、または切断できます。");
64                                 }
65                                 return this;
66                         }
67                 });
68                 DragSource dragSource = new DragSource();
69                 DragGestureListener dgl = new DragGestureListener() {
70                         @Override
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() {
76                                         @Override
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();
83                                                         tx.close();
84                                                         try {
85                                                                 getModel().openTransmitter().setReceiver(rx);
86                                                         } catch (Exception exception) {
87                                                                 exception.printStackTrace();
88                                                         }
89                                                 }
90                                                 cablePane.dragSourceListener.dragDropEnd(event);
91                                         }
92                                 });
93                         }
94                 };
95                 dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, dgl);
96                 dragSource.addDragSourceMotionListener(cablePane.dragSourceMotionListener);
97                 //
98                 // 外からドラッグされたレシーバを、ドロップした場所のトランスミッタに接続する
99                 DropTargetListener dtl = new DropTargetAdapter() {
100                         @Override
101                         public void dragEnter(DropTargetDragEvent event) {
102                                 if( event.isDataFlavorSupported(DraggingTransceiver.receiverFlavor) ) {
103                                         event.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
104                                 }
105                         }
106                         @Override
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);
111                                         return;
112                                 }
113                                 Transferable t = event.getTransferable();
114                                 if( ! t.isDataFlavorSupported(DraggingTransceiver.receiverFlavor) ) {
115                                         event.dropComplete(false);
116                                         return;
117                                 }
118                                 try {
119                                         Object rx = t.getTransferData(DraggingTransceiver.receiverFlavor);
120                                         if( rx != null ) {
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);
125                                                 return;
126                                         }
127                                 }
128                                 catch (Exception ex) {
129                                         ex.printStackTrace();
130                                 }
131                                 event.dropComplete(false);
132                         }
133                 };
134                 new DropTarget( this, DnDConstants.ACTION_COPY_OR_MOVE, dtl, true );
135         }
136 }