OSDN Git Service

ドラッグ&ドロップ処理をTransferHandlerに切り替えてMIDIデバイス接続のケーブル描画を改善
[midichordhelper/MIDIChordHelper.git] / src / camidion / chordhelper / mididevice / MidiDeviceTreeView.java
1 package camidion.chordhelper.mididevice;
2
3 import java.awt.Component;
4 import java.awt.datatransfer.DataFlavor;
5 import java.awt.datatransfer.Transferable;
6
7 import javax.swing.JComponent;
8 import javax.swing.JInternalFrame;
9 import javax.swing.JTree;
10 import javax.swing.ToolTipManager;
11 import javax.swing.TransferHandler;
12 import javax.swing.event.InternalFrameAdapter;
13 import javax.swing.event.InternalFrameEvent;
14 import javax.swing.event.InternalFrameListener;
15 import javax.swing.tree.DefaultTreeCellRenderer;
16
17 /**
18  * MIDIデバイスツリービュー
19  */
20 public class MidiDeviceTreeView extends JTree {
21         public static final DataFlavor deviceModelFlavor  = new DataFlavor(MidiDeviceModel.class,"MidiDeviceModel");
22         private static final DataFlavor flavors[] = {deviceModelFlavor};
23         /**
24          *      {@link MidiDeviceFrame} が閉じられたり、選択されたりしたときに再描画するリスナー
25          */
26         public final InternalFrameListener midiDeviceFrameListener = new InternalFrameAdapter() {
27                 @Override
28                 public void internalFrameActivated(InternalFrameEvent e) {
29                         JInternalFrame frame = e.getInternalFrame();
30                         if( ! (frame instanceof MidiDeviceFrame ) ) return;
31                         setSelectionPath(((MidiDeviceFrame)frame).getMidiDeviceModel().getTreePath());
32                 }
33                 @Override
34                 public void internalFrameClosing(InternalFrameEvent e) { repaint(); }
35         };
36         @Override
37         public MidiDeviceTreeModel getModel() { return (MidiDeviceTreeModel) super.getModel(); }
38         /**
39          * MIDIデバイスツリービューを構築します。
40          * @param model このビューにデータを提供するモデル
41          */
42         public MidiDeviceTreeView(MidiDeviceTreeModel model) {
43                 super(model);
44                 setCellRenderer(new DefaultTreeCellRenderer() {
45                         @Override
46                         public Component getTreeCellRendererComponent(JTree tree, Object value,
47                                         boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus)
48                         {
49                                 super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
50                                 setToolTipText(value.toString());
51                                 if(leaf) {
52                                         MidiDeviceModel deviceModel = (MidiDeviceModel)value;
53                                         if( deviceModel.getMidiDevice().isOpen() ) {
54                                                 setDisabledIcon(MidiDeviceDialog.MIDI_CONNECTER_ICON);
55                                                 setEnabled(false);
56                                                 setToolTipText(getToolTipText()+"はすでに開いています");
57                                         } else {
58                                                 setIcon(MidiDeviceDialog.MIDI_CONNECTER_ICON);
59                                                 setEnabled(true);
60                                                 setToolTipText("ドラッグ&ドロップで"+getToolTipText()+"が開きます");
61                                         }
62                                 }
63                                 return this;
64                         }
65                 });
66                 // ツリーノードを開き、ルートを選択した状態にする
67                 for( int row = 0; row < getRowCount() ; row++ ) expandRow(row);
68                 //
69                 // ツリーノードのToolTipを有効化
70                 ToolTipManager.sharedInstance().registerComponent(this);
71                 //
72                 // ドラッグを有効化
73                 setDragEnabled(true);
74                 setTransferHandler(new TransferHandler() {
75                         @Override
76                         public int getSourceActions(JComponent c) { return COPY_OR_MOVE; }
77                         @Override
78                         protected Transferable createTransferable(JComponent c) {
79                                 JTree tree = (JTree) c;
80                                 Object node = tree.getLastSelectedPathComponent();
81                                 if( node instanceof MidiDeviceModel ) {
82                                         MidiDeviceModel midiDeviceModel = (MidiDeviceModel)node;
83                                         if( ! midiDeviceModel.getMidiDevice().isOpen() ) return new Transferable() {
84                                                 @Override
85                                                 public Object getTransferData(DataFlavor flavor) {
86                                                         return flavor.getRepresentationClass().isInstance(midiDeviceModel) ? midiDeviceModel : null;
87                                                 }
88                                                 @Override
89                                                 public DataFlavor[] getTransferDataFlavors() { return flavors; }
90                                                 @Override
91                                                 public boolean isDataFlavorSupported(DataFlavor flavor) {
92                                                         return flavors[0].equals(flavor);
93                                                 }
94                                         };
95                                 }
96                                 return null;
97                         }
98                         @Override
99                         protected void exportDone(JComponent source, Transferable data, int action) {
100                                 if( action != NONE ) repaint();
101                         }
102                 });
103         }
104 }