1 package camidion.chordhelper.mididevice;
3 import java.awt.Insets;
4 import java.awt.Rectangle;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
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;
22 public class MidiDeviceFrame extends JInternalFrame {
23 private static Insets ZERO_INSETS = new Insets(0,0,0,0);
27 MidiConnecterListView listView;
29 * デバイスのタイムスタンプを更新するタイマー
33 * MIDIデバイスのモデルからフレームビューを構築します。
34 * @param model MIDIデバイスのTransmitter/Receiverリストモデル
36 public MidiDeviceFrame(MidiConnecterListModel model) {
37 super( null, true, true, false, false );
40 String title = model.toString();
41 if( model.txSupported() ) {
42 title = (model.rxSupported()?"[I/O] ":"[IN] ")+title;
45 title = (model.rxSupported()?"[OUT] ":"[No I/O] ")+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() )
56 public void internalFrameClosing(InternalFrameEvent e) {
57 MidiConnecterListModel m = listView.getModel();
59 if( ! m.getMidiDevice().isOpen() )
64 setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
65 add(new JScrollPane(listView));
67 if( listView.getModel().txSupported() ) {
68 add(new JButton("New Tx") {{
69 setMargin(ZERO_INSETS);
70 addActionListener(new ActionListener() {
72 public void actionPerformed(ActionEvent event) {
73 listView.getModel().getUnconnectedTransmitter();
77 add(new JButton("Close Tx") {{
78 setMargin(ZERO_INSETS);
79 addActionListener(new ActionListener() {
81 public void actionPerformed(ActionEvent event) {
82 listView.closeSelectedTransmitter();
88 timer = new Timer(50, new ActionListener() {
89 private long sec = -2;
90 private MidiDevice dev = listView.getModel().getMidiDevice();
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;
97 if( (this.sec = sec) == -1 )
98 text = "No TimeStamp";
100 text = String.format("TimeStamp: %02d:%02d", sec/60, sec%60);
109 * 指定されたインデックスが示す仮想MIDI端子リストの要素のセル範囲を返します。
111 * @param index リスト要素のインデックス
114 public Rectangle getListCellBounds(int index) {
115 Rectangle rect = listView.getCellBounds(index,index);
119 getRootPane().getX() + getContentPane().getX(),
120 getRootPane().getY() + getContentPane().getY()
125 * 仮想MIDI端子リストの指定された要素のセル範囲を返します。
127 * @param transciver 要素となるMIDI端子(Transmitter または Receiver)
130 public Rectangle getListCellBounds(AutoCloseable transciver) {
131 return getListCellBounds(listView.getModel().indexOf(transciver));