1 package camidion.chordhelper.mididevice;
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;
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;
22 public class MidiDeviceFrame extends JInternalFrame {
23 private MidiTransceiverListView transceiverListView;
24 private JScrollPane scrollPane;
27 * このデバイスフレームに貼り付けられた仮想MIDI端子リストビューを取得します。
28 * @return 仮想MIDI端子リストビュー
30 public MidiTransceiverListView getMidiTransceiverListView() { return transceiverListView; }
32 * ダイアログウィンドウがアクティブなときだけタイムスタンプ更新を有効にするためのリスナー
34 public final WindowListener windowListener = new WindowAdapter() {
36 public void windowClosing(WindowEvent e) { timer.stop(); }
38 public void windowActivated(WindowEvent e) { timer.start(); }
41 * MIDIデバイスのTransmitter/Receiverリストビューからフレームビューを構築します。
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();
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;
59 setText(sec == -1?"--:--":String.format("%02d:%02d",sec/60,sec%60));
63 add(scrollPane = new JScrollPane(transceiverListView));
64 setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
67 * 引数で指定された{@link Transmitter}または{@link Receiver}のセル範囲を示す、
68 * デスクトップの座標系内の境界の矩形を返します。対応するセルがない場合はnullを返します。
69 * @param transceiver {@link Transmitter}または{@link Receiver}
70 * @return セル範囲を示す境界の矩形、またはnull
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()