OSDN Git Service

Merge branch 'master' into HEAD
[midichordhelper/MIDIChordHelper.git] / src / camidion / chordhelper / mididevice / MidiDeviceFrame.java
1 package camidion.chordhelper.mididevice;
2
3 import java.awt.Insets;
4 import java.awt.Rectangle;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7
8 import javax.sound.midi.MidiDevice;
9 import javax.swing.BoxLayout;
10 import javax.swing.JButton;
11 import javax.swing.JInternalFrame;
12 import javax.swing.JLabel;
13 import javax.swing.JPanel;
14 import javax.swing.JScrollPane;
15 import javax.swing.Timer;
16 import javax.swing.event.InternalFrameAdapter;
17 import javax.swing.event.InternalFrameEvent;
18
19 /**
20  * MIDIデバイスフレームビュー
21  */
22 public class MidiDeviceFrame extends JInternalFrame {
23         private static Insets ZERO_INSETS = new Insets(0,0,0,0);
24         /**
25          * デバイスの仮想MIDI端子リストビュー
26          */
27         MidiConnecterListView listView;
28         /**
29          * デバイスのタイムスタンプを更新するタイマー
30          */
31         Timer timer;
32         /**
33          * MIDIデバイスのモデルからフレームビューを構築します。
34          * @param model MIDIデバイスのTransmitter/Receiverリストモデル
35          */
36         public MidiDeviceFrame(MidiConnecterListModel model) {
37                 super( null, true, true, false, false );
38                 //
39                 // タイトルの設定
40                 String title = model.toString();
41                 if( model.txSupported() ) {
42                         title = (model.rxSupported()?"[I/O] ":"[IN] ")+title;
43                 }
44                 else {
45                         title = (model.rxSupported()?"[OUT] ":"[No I/O] ")+title;
46                 }
47                 setTitle(title);
48                 listView = new MidiConnecterListView(model);
49                 setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
50                 addInternalFrameListener(
51                         new InternalFrameAdapter() {
52                                 public void internalFrameOpened(InternalFrameEvent e) {
53                                         if( ! listView.getModel().getMidiDevice().isOpen() )
54                                                 setVisible(false);
55                                 }
56                                 public void internalFrameClosing(InternalFrameEvent e) {
57                                         MidiConnecterListModel m = listView.getModel();
58                                         m.closeDevice();
59                                         if( ! m.getMidiDevice().isOpen() )
60                                                 setVisible(false);
61                                 }
62                         }
63                 );
64                 setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
65                 add(new JScrollPane(listView));
66                 add(new JPanel() {{
67                         if( listView.getModel().txSupported() ) {
68                                 add(new JButton("New Tx") {{
69                                         setMargin(ZERO_INSETS);
70                                         addActionListener(new ActionListener() {
71                                                 @Override
72                                                 public void actionPerformed(ActionEvent event) {
73                                                         listView.getModel().getUnconnectedTransmitter();
74                                                 }
75                                         });
76                                 }});
77                                 add(new JButton("Close Tx") {{
78                                         setMargin(ZERO_INSETS);
79                                         addActionListener(new ActionListener() {
80                                                 @Override
81                                                 public void actionPerformed(ActionEvent event) {
82                                                         listView.closeSelectedTransmitter();
83                                                 }
84                                         });
85                                 }});
86                         }
87                         add(new JLabel() {{
88                                 timer = new Timer(50, new ActionListener() {
89                                         private long sec = -2;
90                                         private MidiDevice dev = listView.getModel().getMidiDevice();
91                                         @Override
92                                         public void actionPerformed(ActionEvent e) {
93                                                 long usec = dev.getMicrosecondPosition();
94                                                 long sec = (usec == -1 ? -1 : usec/1000000);
95                                                 if( sec == this.sec ) return;
96                                                 String text;
97                                                 if( (this.sec = sec) == -1 )
98                                                         text = "No TimeStamp";
99                                                 else
100                                                         text = String.format("TimeStamp: %02d:%02d", sec/60, sec%60);
101                                                 setText(text);
102                                         }
103                                 });
104                         }});
105                 }});
106                 setSize(250,100);
107         }
108         /**
109          * 指定されたインデックスが示す仮想MIDI端子リストの要素のセル範囲を返します。
110          *
111          * @param index リスト要素のインデックス
112          * @return セル範囲の矩形
113          */
114         public Rectangle getListCellBounds(int index) {
115                 Rectangle rect = listView.getCellBounds(index,index);
116                 if( rect == null )
117                         return null;
118                 rect.translate(
119                         getRootPane().getX() + getContentPane().getX(),
120                         getRootPane().getY() + getContentPane().getY()
121                 );
122                 return rect;
123         }
124         /**
125          * 仮想MIDI端子リストの指定された要素のセル範囲を返します。
126          *
127          * @param transciver 要素となるMIDI端子(Transmitter または Receiver)
128          * @return セル範囲の矩形
129          */
130         public Rectangle getListCellBounds(AutoCloseable transciver) {
131                 return getListCellBounds(listView.getModel().indexOf(transciver));
132         }
133 }