OSDN Git Service

パッケージ情報を追加、その他リファクタリング
[midichordhelper/MIDIChordHelper.git] / src / camidion / chordhelper / mididevice / MidiDeviceFrame.java
1 package camidion.chordhelper.mididevice;
2
3 import java.awt.BorderLayout;
4 import java.awt.Rectangle;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.awt.event.WindowAdapter;
8 import java.awt.event.WindowEvent;
9 import java.awt.event.WindowListener;
10
11 import javax.sound.midi.MidiDevice;
12 import javax.sound.midi.Receiver;
13 import javax.sound.midi.Transmitter;
14 import javax.swing.JInternalFrame;
15 import javax.swing.JLabel;
16 import javax.swing.JPanel;
17 import javax.swing.JScrollPane;
18 import javax.swing.Timer;
19
20 /**
21  * MIDIデバイスフレームビュー
22  */
23 public class MidiDeviceFrame extends JInternalFrame {
24         private MidiDeviceModel deviceModel;
25         private TransmitterListView transmitterListView;
26         private ReceiverListView receiverListView;
27         private JScrollPane scrollPane;
28         private JPanel trxPanel, txPanel, rxPanel;
29         private Timer timer;
30         /**
31          * このデバイスフレームに表示内容を提供しているMIDIデバイスモデルを取得します。
32          * @return MIDIデバイスモデル
33          */
34         public MidiDeviceModel getMidiDeviceModel() { return deviceModel; }
35         /**
36          * このデバイスフレームに貼り付けられたMIDIトランスミッタリストビューを取得します。
37          * @return MIDIトランスミッタリストビュー
38          */
39         public TransmitterListView getMidiTransmitterListView() { return transmitterListView; }
40         /**
41          * このデバイスフレームに貼り付けられたMIDIトランシーバリストビューを取得します。
42          * @return MIDIトランシーバリストビュー
43          */
44         public ReceiverListView getMidiReceiverListView() { return receiverListView; }
45         /**
46          * ダイアログウィンドウがアクティブなときだけタイムスタンプ更新を有効にするためのリスナー
47          */
48         public final WindowListener windowListener = new WindowAdapter() {
49                 @Override
50                 public void windowClosing(WindowEvent e) { timer.stop(); }
51                 @Override
52                 public void windowActivated(WindowEvent e) { timer.start(); }
53         };
54         /**
55          * MIDIデバイスモデルからフレームビューを構築します。
56          */
57         public MidiDeviceFrame(MidiDeviceModel deviceModel, MidiCablePane cablePane) {
58                 super( null, true, true, false, false );
59                 this.deviceModel = deviceModel;
60                 setTitle("[" + deviceModel.getMidiDeviceInOutType().getShortName() + "] " + deviceModel);
61                 setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
62                 setLayout(new BorderLayout());
63                 add(new JLabel("--:--") {{
64                         timer = new Timer(50, new ActionListener() {
65                                 private long sec = -2;
66                                 private MidiDevice device = getMidiDeviceModel().getMidiDevice();
67                                 @Override
68                                 public void actionPerformed(ActionEvent event) {
69                                         long usec = device.getMicrosecondPosition();
70                                         long sec = (usec == -1 ? -1 : usec/1000000);
71                                         if( sec == this.sec ) return;
72                                         this.sec = sec;
73                                         setText(sec == -1?"--:--":String.format("%02d:%02d",sec/60,sec%60));
74                                         cablePane.repaint();
75                                 }
76                         });
77                 }}, BorderLayout.SOUTH);
78                 add(scrollPane = new JScrollPane(trxPanel = new JPanel() {{
79                         setLayout(new BorderLayout());
80                         ReceiverListModel rxListModel = getMidiDeviceModel().getReceiverListModel();
81                         if( rxListModel != null ) {
82                                 receiverListView = new ReceiverListView(rxListModel, cablePane);
83                                 add(rxPanel = new JPanel() {{
84                                         setLayout(new BorderLayout());
85                                         add(new JLabel("Rx") {{ setVerticalAlignment(TOP); }}, BorderLayout.WEST);
86                                         add(receiverListView);
87                                 }}, BorderLayout.NORTH);
88                         }
89                         TransmitterListModel txListModel = getMidiDeviceModel().getTransmitterListModel();
90                         if( txListModel != null ) {
91                                 transmitterListView = new TransmitterListView(txListModel, cablePane);
92                                 add(txPanel = new JPanel() {{
93                                         setLayout(new BorderLayout());
94                                         add(new JLabel("Tx") {{ setVerticalAlignment(TOP); }}, BorderLayout.WEST);
95                                         add(transmitterListView);
96                                 }}, rxListModel == null ? BorderLayout.NORTH : BorderLayout.SOUTH);
97                         }
98                 }}));
99         }
100         /**
101          * 引数で指定された{@link Transmitter}のセル範囲を示す、
102          * デスクトップの座標系内の境界の矩形を返します。対応するセルがない場合はnullを返します。
103          * @return セル範囲を示す境界の矩形、またはnull
104          */
105         public Rectangle getBoundsOf(Transmitter tx) {
106                 if( transmitterListView == null ) return null;
107                 Rectangle rect = transmitterListView.getCellBounds(tx);
108                 if( rect == null ) return null;
109                 translate(rect, txPanel, transmitterListView);
110                 return rect;
111         }
112         /**
113          * 引数で指定された{@link Receiver}のセル範囲を示す、
114          * デスクトップの座標系内の境界の矩形を返します。対応するセルがない場合はnullを返します。
115          * @return セル範囲を示す境界の矩形、またはnull
116          */
117         public Rectangle getBoundsOf(Receiver rx) {
118                 if( receiverListView == null ) return null;
119                 Rectangle rect = receiverListView.getCellBounds(rx);
120                 if( rect == null ) return null;
121                 translate(rect, rxPanel, receiverListView);
122                 return rect;
123         }
124         private void translate(Rectangle rect, JPanel panel, AbstractTransceiverListView<?> list) {
125                 int x = getX() + getRootPane().getX() + getContentPane().getX() +
126                                 scrollPane.getX() + trxPanel.getX() +
127                                 panel.getX() + list.getX();
128                 int y = getY() + getRootPane().getY() + getContentPane().getY() +
129                                 scrollPane.getY() + trxPanel.getY() +
130                                 panel.getY() + list.getY();
131                 rect.translate(x,y);
132         }
133 }