OSDN Git Service

リファクタリング(ChordHelperApplet#meta() を無名クラス化、など)
authorAkiyoshi Kamide <kamide@yk.rim.or.jp>
Wed, 13 Nov 2013 16:20:14 +0000 (16:20 +0000)
committerAkiyoshi Kamide <kamide@yk.rim.or.jp>
Wed, 13 Nov 2013 16:20:14 +0000 (16:20 +0000)
git-svn-id: https://svn.sourceforge.jp/svnroot/midichordhelper/MIDIChordHelper@10 302f1594-2db2-43b1-aaa4-6307b5a2a2de

src/ChordHelperApplet.java
src/ChordMatrix.java
src/MIDIDevice.java
src/MIDIMsgForm.java
src/NewSequenceDialog.java

index 851aa7e..34b1e06 100644 (file)
@@ -60,7 +60,7 @@ import javax.swing.event.PopupMenuListener;
  *             Copyright (C) 2004-2013 @きよし - Akiyoshi Kamide\r
  *             http://www.yk.rim.or.jp/~kamide/music/chordhelper/\r
  */\r
-public class ChordHelperApplet extends JApplet implements MetaEventListener {\r
+public class ChordHelperApplet extends JApplet {\r
        /////////////////////////////////////////////////////////////////////\r
        //\r
        // JavaScript などからの呼び出しインターフェース\r
@@ -241,7 +241,7 @@ public class ChordHelperApplet extends JApplet implements MetaEventListener {
         */\r
        public static class VersionInfo {\r
                public static final String      NAME = "MIDI Chord Helper";\r
-               public static final String      VERSION = "Ver.20131113.1";\r
+               public static final String      VERSION = "Ver.20131114.1";\r
                public static final String      COPYRIGHT = "Copyright (C) 2004-2013";\r
                public static final String      AUTHER = "@きよし - Akiyoshi Kamide";\r
                public static final String      URL = "http://www.yk.rim.or.jp/~kamide/music/chordhelper/";\r
@@ -453,33 +453,58 @@ public class ChordHelperApplet extends JApplet implements MetaEventListener {
                //\r
                // MIDI parts\r
                //\r
-               deviceModelList.sequencerModel.getSequencer().addMetaEventListener(this);\r
+               deviceModelList.sequencerModel.getSequencer().addMetaEventListener(\r
+                       new MetaEventListener() {\r
+                               @Override\r
+                               public void meta(MetaMessage msg) {\r
+                                       switch(msg.getType()) {\r
+                                       case 0x01: // Text(任意のテキスト:コメントなど)\r
+                                       case 0x02: // Copyright(著作権表示)\r
+                                       case 0x05: // Lyrics(歌詞)\r
+                                       case 0x06: // Marker\r
+                                       case 0x03: // Sequence Name / Track Name(曲名またはトラック名)\r
+                                               lyricDisplay.addLyric(msg.getData());\r
+                                               break;\r
+                                       case 0x51: // Tempo (3 bytes) - テンポ\r
+                                               tempoSelecter.setTempo(msg.getData());\r
+                                               break;\r
+                                       case 0x58: // Time signature (4 bytes) - 拍子\r
+                                               timesigSelecter.setValue(msg.getData());\r
+                                               break;\r
+                                       case 0x59: // Key signature (2 bytes) : 調号\r
+                                               Music.Key key = new Music.Key(msg.getData());\r
+                                               keysigLabel.setKeySignature(key);\r
+                                               chordMatrix.setKeySignature(key);\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+               );\r
                deviceModelList.sequencerModel.addChangeListener(\r
                        new ChangeListener() {\r
+                               @Override\r
                                public void stateChanged(ChangeEvent e) {\r
                                        MidiSequenceTableModel sequenceTableModel = deviceModelList.sequencerModel.getSequenceTableModel();\r
-                                       int i = editorDialog.sequenceListTableModel.getLoadedIndex();\r
+                                       int loadedSequenceIndex = editorDialog.sequenceListTableModel.getLoadedIndex();\r
                                        songTitleLabel.setText(\r
                                                "<html>"+(\r
-                                                       i < 0 ? "[No MIDI file loaded]" :\r
-                                                       "MIDI file " + i + ": " + (\r
-                                                       sequenceTableModel == null ||\r
-                                                       sequenceTableModel.toString() == null ||\r
-                                                       sequenceTableModel.toString().isEmpty() ?\r
+                                                       loadedSequenceIndex < 0 ? "[No MIDI file loaded]" :\r
+                                                       "MIDI file " + loadedSequenceIndex + ": " + (\r
+                                                               sequenceTableModel == null ||\r
+                                                               sequenceTableModel.toString() == null ||\r
+                                                               sequenceTableModel.toString().isEmpty() ?\r
                                                                "[Untitled]" :\r
                                                                "<font color=maroon>"+sequenceTableModel+"</font>"\r
                                                        )\r
                                                )+"</html>"\r
                                        );\r
                                        chordMatrix.setPlaying(deviceModelList.sequencerModel.isRunning());\r
-                                       long currentTickPosition = deviceModelList.sequencerModel.getSequencer().getTickPosition();\r
+                                       long tickPos = deviceModelList.sequencerModel.getSequencer().getTickPosition();\r
                                        SequenceTickIndex tickIndex = null;\r
                                        if( sequenceTableModel != null ) {\r
                                                tickIndex = sequenceTableModel.getSequenceTickIndex();\r
-                                               tickIndex.tickToMeasure(currentTickPosition);\r
-                                               chordMatrix.setBeat(\r
-                                                       (byte)(tickIndex.lastBeat), tickIndex.timesigUpper\r
-                                               );\r
+                                               tickIndex.tickToMeasure(tickPos);\r
+                                               chordMatrix.setBeat(tickIndex);\r
                                                if(\r
                                                        deviceModelList.sequencerModel.getValueIsAdjusting()\r
                                                        || (\r
@@ -488,18 +513,19 @@ public class ChordHelperApplet extends JApplet implements MetaEventListener {
                                                                ! deviceModelList.sequencerModel.getSequencer().isRecording()\r
                                                        )\r
                                                ) {\r
-                                                       MetaMessage msg = tickIndex.lastMetaMessageAt(\r
-                                                               SequenceTickIndex.TIME_SIGNATURE, currentTickPosition\r
-                                                       );\r
-                                                       if( msg == null ) timesigSelecter.clear(); else meta(msg);\r
-                                                       msg = tickIndex.lastMetaMessageAt(\r
-                                                               SequenceTickIndex.TEMPO, currentTickPosition\r
-                                                       );\r
-                                                       if( msg == null ) tempoSelecter.clear(); else meta(msg);\r
-                                                       msg = tickIndex.lastMetaMessageAt(\r
-                                                               SequenceTickIndex.KEY_SIGNATURE, currentTickPosition\r
-                                                       );\r
-                                                       if( msg == null ) keysigLabel.clear(); else meta(msg);\r
+                                                       MetaMessage msg;\r
+                                                       msg = tickIndex.lastMetaMessageAt(SequenceTickIndex.TIME_SIGNATURE, tickPos);\r
+                                                       timesigSelecter.setValue(msg==null ? null : msg.getData());\r
+                                                       msg = tickIndex.lastMetaMessageAt(SequenceTickIndex.TEMPO, tickPos);\r
+                                                       tempoSelecter.setTempo(msg==null ? null : msg.getData());\r
+                                                       msg = tickIndex.lastMetaMessageAt(SequenceTickIndex.KEY_SIGNATURE, tickPos);\r
+                                                       if( msg == null )\r
+                                                               keysigLabel.clear();\r
+                                                       else {\r
+                                                               Music.Key key = new Music.Key(msg.getData());\r
+                                                               keysigLabel.setKeySignature(key);\r
+                                                               chordMatrix.setKeySignature(key);\r
+                                                       }\r
                                                }\r
                                        }\r
                                }\r
@@ -666,35 +692,6 @@ public class ChordHelperApplet extends JApplet implements MetaEventListener {
                deviceModelList.sequencerModel.stop(); // MIDI再生を強制終了\r
                System.gc();\r
        }\r
-       /////////////////////////////////////////\r
-       //\r
-       // MetaEventListener\r
-       //\r
-       public void meta(MetaMessage msg) {\r
-               int msgtype = msg.getType();\r
-               switch( msgtype ) {\r
-\r
-               case 0x01: // Text(任意のテキスト:コメントなど)\r
-               case 0x02: // Copyright(著作権表示)\r
-               case 0x05: // Lyrics(歌詞)\r
-               case 0x06: // Marker\r
-               case 0x03: // Sequence Name / Track Name(曲名またはトラック名)\r
-                       lyricDisplay.addLyric(msg.getData());\r
-                       break;\r
-\r
-               case 0x51: // Tempo (3 bytes) - テンポ\r
-                       tempoSelecter.setTempo(msg.getData());\r
-                       break;\r
-               case 0x58: // Time signature (4 bytes) - 拍子\r
-                       timesigSelecter.setValue(msg.getData());\r
-                       break;\r
-               case 0x59: // Key signature (2 bytes) : 調号\r
-                       keysigLabel.setKeySignature( new Music.Key(msg.getData()) );\r
-                       chordMatrix.setKeySignature( new Music.Key(msg.getData()) );\r
-                       break;\r
-\r
-               }\r
-       }\r
        private void innerSetDarkMode(boolean is_dark) {\r
                Color col = is_dark ? Color.black : null;\r
                // Color fgcol = is_dark ? Color.pink : null;\r
index 6406cc1..1262c18 100644 (file)
@@ -1089,7 +1089,9 @@ public class ChordMatrix extends JPanel
 \r
        private byte currentBeat = 0;\r
        private byte timesigUpper = 4;\r
-       public void setBeat(byte beat, byte tsu) {\r
+       public void setBeat(SequenceTickIndex sequenceTickIndex) {\r
+               byte beat = (byte)(sequenceTickIndex.lastBeat);\r
+               byte tsu = sequenceTickIndex.timesigUpper;\r
                if( currentBeat == beat && timesigUpper == tsu )\r
                        return;\r
                timesigUpper = tsu;\r
index 72f8821..1baae7b 100644 (file)
@@ -1346,7 +1346,10 @@ class MidiSequencerModel extends MidiConnecterListModel
         * このモデルのMIDIシーケンサが開始されているか調べます。\r
         * @return 開始されていたらtrue\r
         */\r
-       public boolean isRunning() { return timeRangeUpdater.isRunning(); }\r
+       public boolean isRunning() {\r
+               // return timeRangeUpdater.isRunning();\r
+               return getSequencer().isRunning();\r
+       }\r
        /**\r
         * このモデルのMIDIシーケンサを開始します。\r
         */\r
@@ -1443,7 +1446,11 @@ class MidiSequencerModel extends MidiConnecterListModel
                listenerList.remove(ChangeListener.class, listener);\r
        }\r
        /**\r
-        * 状態が変わったことをリスナーに通知します。\r
+        * 状態の変化をリスナーに通知します。\r
+        * <p>登録中のすべての {@link ChangeListener} について\r
+        * {@link ChangeListener#stateChanged(ChangeEvent)}\r
+        * を呼び出すことによって通知します。\r
+        * </p>\r
         */\r
        public void fireStateChanged() {\r
                Object[] listeners = listenerList.getListenerList();\r
index 0c3a6b0..c9582d5 100644 (file)
@@ -381,9 +381,9 @@ class MidiMessageForm extends JPanel implements ActionListener {
                        }\r
                        else if( status == 0xFF ) {\r
                                switch( data1 ) { // Data type -> Selecter\r
-                               case 0x51: dataText.setValue( tempoSelecter.getTempoByteArray() ); break;\r
-                               case 0x58: dataText.setValue( timesigSelecter.getByteArray() ); break;\r
-                               case 0x59: dataText.setValue( keysigSelecter.getKey().getBytes() ); break;\r
+                               case 0x51: dataText.setValue(tempoSelecter.getTempoByteArray()); break;\r
+                               case 0x58: dataText.setValue(timesigSelecter.getByteArray()); break;\r
+                               case 0x59: dataText.setValue(keysigSelecter.getKey().getBytes()); break;\r
                                default: break;\r
                                }\r
                        }\r
@@ -1196,43 +1196,44 @@ class DurationForm extends JPanel implements ActionListener, ChangeListener {
  */\r
 class TempoSelecter extends JPanel implements MouseListener {\r
        static final int DEFAULT_QPM = 120;\r
-       JSpinner                tempo_spinner;\r
+       JSpinner                tempoSpinner;\r
        SpinnerNumberModel      tempoSpinnerModel;\r
-       JLabel          tempo_label, tempo_value_label;\r
+       JLabel          tempoLabel, tempoValueLabel;\r
        private boolean editable;\r
-       private long    prev_beat_us_pos = 0;\r
+       private long    prevBeatMicrosecondPosition = 0;\r
 \r
        public TempoSelecter() {\r
-               String tool_tip = "Tempo in quatrers per minute - テンポ(1分あたりの四分音符の数)";\r
-               tempo_label = new JLabel(\r
+               String tooltip = "Tempo in quatrers per minute - テンポ(1分あたりの四分音符の数)";\r
+               tempoLabel = new JLabel(\r
                        "=",\r
-                       new ButtonIcon( ButtonIcon.QUARTER_NOTE_ICON ),\r
+                       new ButtonIcon(ButtonIcon.QUARTER_NOTE_ICON),\r
                        JLabel.CENTER\r
                );\r
-               tempo_label.setVerticalAlignment( JLabel.CENTER );\r
+               tempoLabel.setVerticalAlignment(JLabel.CENTER);\r
                tempoSpinnerModel = new SpinnerNumberModel(DEFAULT_QPM, 1, 999, 1);\r
-               tempo_spinner = new JSpinner( tempoSpinnerModel );\r
-               tempo_spinner.setToolTipText( tool_tip );\r
-               tempo_value_label = new JLabel( ""+DEFAULT_QPM );\r
-               tempo_value_label.setToolTipText( tool_tip );\r
-               setLayout( new BoxLayout(this,BoxLayout.X_AXIS) );\r
-               add( tempo_label );\r
+               tempoSpinner = new JSpinner(tempoSpinnerModel);\r
+               tempoSpinner.setToolTipText(tooltip);\r
+               tempoValueLabel = new JLabel(""+DEFAULT_QPM);\r
+               tempoValueLabel.setToolTipText(tooltip);\r
+               setLayout(new BoxLayout(this,BoxLayout.X_AXIS));\r
+               add( tempoLabel );\r
                add( Box.createHorizontalStrut(5) );\r
-               add( tempo_spinner );\r
-               add( tempo_value_label );\r
+               add( tempoSpinner );\r
+               add( tempoValueLabel );\r
                setEditable(true);\r
-               tempo_label.addMouseListener(this);\r
+               tempoLabel.addMouseListener(this);\r
        }\r
+       @Override\r
        public void mousePressed(MouseEvent e) {\r
                Component obj = e.getComponent();\r
-               if( obj == tempo_label && isEditable() ) {\r
+               if(obj == tempoLabel && isEditable()) {\r
                        //\r
                        // Adjust tempo by interval time between two clicks\r
                        //\r
-                       long current_us = System.nanoTime()/1000;\r
+                       long currentMicrosecond = System.nanoTime()/1000;\r
                        // midi_ch_selecter.noteOn( 9, 37, 100 );\r
-                       long interval_us = current_us - prev_beat_us_pos;\r
-                       prev_beat_us_pos = current_us;\r
+                       long interval_us = currentMicrosecond - prevBeatMicrosecondPosition;\r
+                       prevBeatMicrosecondPosition = currentMicrosecond;\r
                        if( interval_us < 2000000L /* Shorter than 2 sec only */ ) {\r
                                int tempo_in_bpm = (int)(240000000L / interval_us) >> 2; //  n/4拍子の場合のみを想定\r
                        int old_tempo_in_bpm = getTempoInQpm();\r
@@ -1244,37 +1245,60 @@ class TempoSelecter extends JPanel implements MouseListener {
        public void mouseEntered(MouseEvent e) { }\r
        public void mouseExited(MouseEvent e) { }\r
        public void mouseClicked(MouseEvent e) { }\r
+       /**\r
+        * 編集可能かどうかを返します。\r
+        * @return 編集可能ならtrue\r
+        */\r
        public boolean isEditable() { return editable; }\r
+       /**\r
+        * 編集可能かどうかを設定します。\r
+        * @param editable 編集可能ならtrue\r
+        */\r
        public void setEditable( boolean editable ) {\r
                this.editable = editable;\r
-               tempo_spinner.setVisible( editable );\r
-               tempo_value_label.setVisible( !editable );\r
+               tempoSpinner.setVisible( editable );\r
+               tempoValueLabel.setVisible( !editable );\r
                if( !editable ) {\r
                        // Copy spinner's value to label\r
-                       tempo_value_label.setText(\r
+                       tempoValueLabel.setText(\r
                                ""+tempoSpinnerModel.getNumber().intValue()\r
                        );\r
                }\r
-               tempo_label.setToolTipText(\r
+               tempoLabel.setToolTipText(\r
                        editable ?\r
                        "Click rhythmically to adjust tempo - ここをクリックしてリズムをとるとテンポを合わせられます"\r
                        : null\r
                );\r
        }\r
+       /**\r
+        * テンポを返します。\r
+        * @return テンポ [BPM](QPM)\r
+        */\r
        public int getTempoInQpm() {\r
                return tempoSpinnerModel.getNumber().intValue();\r
        }\r
+       /**\r
+        * テンポをMIDIメタメッセージのバイト列として返します。\r
+        * @return MIDIメタメッセージのバイト列\r
+        */\r
        public byte[] getTempoByteArray() {\r
-               return MIDISpec.qpmTempoToByteArray( getTempoInQpm() );\r
+               return MIDISpec.qpmTempoToByteArray(getTempoInQpm());\r
        }\r
-       public void setTempo( int qpm ) {\r
+       /**\r
+        * テンポを設定します。\r
+        * @param qpm BPM(QPM)の値\r
+        */\r
+       public void setTempo(int qpm) {\r
                tempoSpinnerModel.setValue(new Integer(qpm));\r
-               tempo_value_label.setText(""+qpm);\r
+               tempoValueLabel.setText(""+qpm);\r
        }\r
-       public void setTempo( byte msgdata[] ) {\r
-               setTempo( MIDISpec.byteArrayToQpmTempo( msgdata ) );\r
+       /**\r
+        * MIDIメタメッセージのバイト列からテンポを設定します。\r
+        * @param msgdata MIDIメタメッセージのバイト列(null を指定した場合はデフォルトに戻る)\r
+        */\r
+       public void setTempo(byte msgdata[]) {\r
+               setTempo(msgdata==null ? DEFAULT_QPM: MIDISpec.byteArrayToQpmTempo(msgdata));\r
        }\r
-       public void clear() { setTempo( DEFAULT_QPM ); }\r
 }\r
 \r
 /**\r
@@ -1341,13 +1365,16 @@ class TimeSignatureSelecter extends JPanel {
                data[3] = 8;\r
                return data;\r
        }\r
-       public void setValue( byte upper, byte lower_index ) {\r
+       public void setValue(byte upper, byte lowerIndex) {\r
                upperTimesigSpinnerModel.setValue( upper );\r
-               lowerTimesigCombobox.setSelectedIndex( lower_index );\r
-               timesigValueLabel.setTimeSignature( upper, lower_index );\r
+               lowerTimesigCombobox.setSelectedIndex( lowerIndex );\r
+               timesigValueLabel.setTimeSignature( upper, lowerIndex );\r
        }\r
-       public void setValue( byte[] data ) {\r
-               setValue( data[0], data[1] );\r
+       public void setValue(byte[] data) {\r
+               if(data == null)\r
+                       clear();\r
+               else\r
+                       setValue(data[0], data[1]);\r
        }\r
        public boolean isEditable() { return editable; }\r
        public void setEditable( boolean editable ) {\r
index 14490ee..e9abaad 100644 (file)
@@ -189,22 +189,22 @@ class NewSequenceDialog extends JDialog implements ActionListener {
        }\r
        public Sequence getMidiSequence() {\r
                Music.FirstTrackSpec first_track_spec = new Music.FirstTrackSpec(\r
-                               seq_name_text.getText(),\r
-                               tempo_selecter.getTempoByteArray(),\r
-                               timesig_selecter.getByteArray()\r
-                               );\r
+                       seq_name_text.getText(),\r
+                       tempo_selecter.getTempoByteArray(),\r
+                       timesig_selecter.getByteArray()\r
+               );\r
                return getChordProgression().toMidiSequence(\r
-                               ppq_combo_box.getPPQ(),\r
-                               measure_selecter.getStartMeasurePosition(),\r
-                               measure_selecter.getEndMeasurePosition(),\r
-                               first_track_spec,\r
-                               track_spec_panel.getTrackSpecs()\r
-                               );\r
+                       ppq_combo_box.getPPQ(),\r
+                       measure_selecter.getStartMeasurePosition(),\r
+                       measure_selecter.getEndMeasurePosition(),\r
+                       first_track_spec,\r
+                       track_spec_panel.getTrackSpecs()\r
+               );\r
        }\r
-       public void setChordProgression( Music.ChordProgression cp ) {\r
-               chord_text.setText( cp.toString() );\r
+       public void setChordProgression(Music.ChordProgression cp) {\r
+               chord_text.setText(cp.toString());\r
        }\r
-       public void setRandomChordProgression( int measure_length ) {\r
+       public void setRandomChordProgression(int measureLength) {\r
                //\r
                // テンポ・拍子・コード進行をランダムに設定\r
                //\r
@@ -212,15 +212,10 @@ class NewSequenceDialog extends JDialog implements ActionListener {
                int timesig_upper = 4;\r
                int timesig_lower_index = 2;\r
                switch( (int)(Math.random() * 10) ) {\r
-               case 0: timesig_upper = 3; break; // 3/4\r
+                       case 0: timesig_upper = 3; break; // 3/4\r
                }\r
-               timesig_selecter.setValue(\r
-                               (byte)timesig_upper,\r
-                               (byte)timesig_lower_index\r
-                               );\r
-               setChordProgression(\r
-                               new Music.ChordProgression( measure_length, timesig_upper )\r
-                               );\r
+               timesig_selecter.setValue((byte)timesig_upper, (byte)timesig_lower_index);\r
+               setChordProgression(new Music.ChordProgression(measureLength, timesig_upper));\r
        }\r
        public void transpose(int chromatic_offset) {\r
                Music.ChordProgression cp = getChordProgression();\r
@@ -265,11 +260,11 @@ implements PianoKeyboardListener, ActionListener, ChangeListener
                //\r
                // 音色(プログラム)設定\r
                pg_family_selecter = new MidiProgramFamilySelecter(\r
-                               pg_selecter = new MidiProgramSelecter()\r
-                               );\r
+                       pg_selecter = new MidiProgramSelecter()\r
+               );\r
                pg_selecter.setFamilySelecter(\r
-                               pg_family_selecter\r
-                               );\r
+                       pg_family_selecter\r
+               );\r
                // 音域指定\r
                //\r
                keyboard_panel = new PianoKeyboardPanel();\r
@@ -284,8 +279,8 @@ implements PianoKeyboardListener, ActionListener, ChangeListener
                JPanel track_selecter_panel = new JPanel();\r
                track_selecter_panel.add( new JLabel("Track select:") );\r
                track_selecter_panel.add(\r
-                               trackSelecter = new JComboBox<Music.AbstractNoteTrackSpec>()\r
-                               );\r
+                       trackSelecter = new JComboBox<Music.AbstractNoteTrackSpec>()\r
+               );\r
                add( track_selecter_panel );\r
 \r
                add( track_type_label = new JLabel() );\r