OSDN Git Service

MIDIデバイス接続画面の修正
[midichordhelper/MIDIChordHelper.git] / src / camidion / chordhelper / mididevice / MidiDeviceFrame.java
1 package camidion.chordhelper.mididevice;
2
3 import java.awt.Rectangle;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.awt.event.WindowAdapter;
7 import java.awt.event.WindowEvent;
8 import java.awt.event.WindowListener;
9
10 import javax.sound.midi.MidiDevice;
11 import javax.sound.midi.Receiver;
12 import javax.sound.midi.Transmitter;
13 import javax.swing.BoxLayout;
14 import javax.swing.JInternalFrame;
15 import javax.swing.JLabel;
16 import javax.swing.JScrollPane;
17 import javax.swing.Timer;
18
19 /**
20  * MIDIデバイスフレームビュー
21  */
22 public class MidiDeviceFrame extends JInternalFrame {
23         private MidiTransceiverListView transceiverListView;
24         private JScrollPane scrollPane;
25         private Timer timer;
26         /**
27          * このデバイスフレームに貼り付けられた仮想MIDI端子リストビューを取得します。
28          * @return 仮想MIDI端子リストビュー
29          */
30         public MidiTransceiverListView getMidiTransceiverListView() { return transceiverListView; }
31         /**
32          * ダイアログウィンドウがアクティブなときだけタイムスタンプ更新を有効にするためのリスナー
33          */
34         public final WindowListener windowListener = new WindowAdapter() {
35                 @Override
36                 public void windowClosing(WindowEvent e) { timer.stop(); }
37                 @Override
38                 public void windowActivated(WindowEvent e) { timer.start(); }
39         };
40         /**
41          * MIDIデバイスのTransmitter/Receiverリストビューからフレームビューを構築します。
42          */
43         public MidiDeviceFrame(MidiTransceiverListView transceiverListView) {
44                 super( null, true, true, false, false );
45                 this.transceiverListView = transceiverListView;
46                 MidiTransceiverListModel model = transceiverListView.getModel();
47                 setTitle("[" + model.getMidiDeviceInOutType().getShortName() + "] " + model);
48                 setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
49                 add(new JLabel("--:--") {{
50                         timer = new Timer(50, new ActionListener() {
51                                 private long sec = -2;
52                                 private MidiDevice device = getMidiTransceiverListView().getModel().getMidiDevice();
53                                 @Override
54                                 public void actionPerformed(ActionEvent e) {
55                                         long usec = device.getMicrosecondPosition();
56                                         long sec = (usec == -1 ? -1 : usec/1000000);
57                                         if( sec == this.sec ) return;
58                                         this.sec = sec;
59                                         setText(sec == -1?"--:--":String.format("%02d:%02d",sec/60,sec%60));
60                                 }
61                         });
62                 }});
63                 add(scrollPane = new JScrollPane(transceiverListView));
64                 setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
65         }
66         /**
67          * 引数で指定された{@link Transmitter}または{@link Receiver}のセル範囲を示す、
68          * デスクトップの座標系内の境界の矩形を返します。対応するセルがない場合はnullを返します。
69          * @param transceiver {@link Transmitter}または{@link Receiver}
70          * @return セル範囲を示す境界の矩形、またはnull
71          */
72         public Rectangle getBoundsOf(AutoCloseable transceiver) {
73                 Rectangle rect = transceiverListView.getCellBounds(transceiver);
74                 if( rect != null ) rect.translate(
75                         getRootPane().getX() + getContentPane().getX() + scrollPane.getX() + getX(),
76                         getRootPane().getY() + getContentPane().getY() + scrollPane.getY() + getY()
77                 );
78                 return rect;
79         }
80 }