OSDN Git Service

・プレイリストで曲選択クリア時にイベント一覧がクリアされない問題の改善
authorAkiyoshi Kamide <kamide@yk.rim.or.jp>
Sat, 22 Apr 2017 17:02:38 +0000 (02:02 +0900)
committerAkiyoshi Kamide <kamide@yk.rim.or.jp>
Sat, 22 Apr 2017 17:02:38 +0000 (02:02 +0900)
・リファクタリング

src/camidion/chordhelper/ChordHelperApplet.java
src/camidion/chordhelper/ChordTextField.java
src/camidion/chordhelper/midieditor/MidiEventTable.java
src/camidion/chordhelper/midieditor/MidiSequenceEditorDialog.java
src/camidion/chordhelper/midieditor/PlaylistTable.java
src/camidion/chordhelper/midieditor/PlaylistTableModel.java
src/camidion/chordhelper/midieditor/SequenceTrackListTable.java
src/camidion/chordhelper/midieditor/SequenceTrackListTableModel.java
src/camidion/chordhelper/midieditor/TrackEventListTableModel.java

index 652fc55..5b65ecf 100644 (file)
@@ -144,7 +144,7 @@ public class ChordHelperApplet extends JApplet {
         * プレイリスト上で現在選択されているMIDIシーケンスをシーケンサへロードして再生します。
         */
        public void play() {
-               play(playlistModel.sequenceListSelectionModel.getMinSelectionIndex());
+               play(playlistModel.getSelectionModel().getMinSelectionIndex());
        }
        /**
         * 指定されたインデックス値が示すプレイリスト上のMIDIシーケンスをシーケンサへロードして再生します。
@@ -266,7 +266,7 @@ public class ChordHelperApplet extends JApplet {
         */
        public static class VersionInfo {
                public static final String NAME = "MIDI Chord Helper";
-               public static final String VERSION = "Ver.20170421.1";
+               public static final String VERSION = "Ver.20170422.1";
                public static final String COPYRIGHT = "Copyright (C) 2004-2017";
                public static final String AUTHER = "@きよし - Akiyoshi Kamide";
                public static final String URL = "http://www.yk.rim.or.jp/~kamide/music/chordhelper/";
index 1e1f88e..2157eb5 100644 (file)
@@ -63,7 +63,7 @@ public class ChordTextField extends JTextField {
                // 追加するデータを適切な文字コードで文字列に変換
                String additionalText;
                if( m != null ) {
-                       additionalText = new String(data,m.charset);
+                       additionalText = new String(data,m.getCharset());
                }
                else try {
                        additionalText = new String(data,"JISAutoDetect");
index 2cc14c3..c39ce09 100644 (file)
@@ -23,10 +23,8 @@ import javax.swing.JOptionPane;
 import javax.swing.JScrollPane;
 import javax.swing.JTable;
 import javax.swing.JToggleButton;
-import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 import javax.swing.table.TableCellEditor;
-import javax.swing.table.TableColumnModel;
 import javax.swing.table.TableModel;
 
 import camidion.chordhelper.ChordHelperApplet;
@@ -39,12 +37,16 @@ public class MidiEventTable extends JTable {
        /**
         * MIDIイベント入力ダイアログ(イベント入力とイベント送出で共用)
         */
-       public MidiEventDialog eventDialog;
+       private MidiEventDialog eventDialog;
        /**
         * 操作音を鳴らすMIDI出力デバイス
         */
        private VirtualMidiDevice outputMidiDevice;
        /**
+        * イベント選択リスナー
+        */
+       private ListSelectionListener selectionListener;
+       /**
         * 新しいイベントリストテーブルを構築します。
         * <p>データモデルとして一つのトラックのイベントリストを指定できます。
         * トラックを切り替えたいときは {@link #setModel(TableModel)}
@@ -59,39 +61,78 @@ public class MidiEventTable extends JTable {
                super(model, null, model.getSelectionModel());
                this.outputMidiDevice = outputMidiDevice;
                this.eventDialog = eventDialog;
+               titleLabel = new TitleLabel();
+               Arrays.stream(TrackEventListTableModel.Column.values()).forEach(c->
+                       getColumnModel().getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
+               );
                pairNoteOnOffModel = new JToggleButton.ToggleButtonModel() {
                        {
                                addItemListener(e->eventDialog.midiMessageForm.durationForm.setEnabled(isSelected()));
                                setSelected(true);
                        }
                };
-               //
-               // 列モデルにセルエディタを設定
                eventCellEditor = new MidiEventCellEditor();
                setAutoCreateColumnsFromModel(false);
-               //
-               eventSelectionListener = new EventSelectionListener();
-               titleLabel = new TitleLabel();
-               //
-               TableColumnModel cm = getColumnModel();
-               Arrays.stream(TrackEventListTableModel.Column.values()).forEach(c->
-                       cm.getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
-               );
+               selectionModel.addListSelectionListener(selectionListener = event->{
+                       if( event.getValueIsAdjusting() ) return;
+                       if( selectionModel.isSelectionEmpty() ) {
+                               queryPasteEventAction.setEnabled(false);
+                               copyEventAction.setEnabled(false);
+                               deleteEventAction.setEnabled(false);
+                               cutEventAction.setEnabled(false);
+                       }
+                       else {
+                               copyEventAction.setEnabled(true);
+                               deleteEventAction.setEnabled(true);
+                               cutEventAction.setEnabled(true);
+                               int minIndex = selectionModel.getMinSelectionIndex();
+                               MidiEvent midiEvent = model.getMidiEvent(minIndex);
+                               if( midiEvent != null ) {
+                                       MidiMessage msg = midiEvent.getMessage();
+                                       if( msg instanceof ShortMessage ) {
+                                               ShortMessage sm = (ShortMessage)msg;
+                                               int cmd = sm.getCommand();
+                                               if( cmd == 0x80 || cmd == 0x90 || cmd == 0xA0 ) {
+                                                       // ノート番号を持つ場合、音を鳴らす。
+                                                       MidiChannel outMidiChannels[] = outputMidiDevice.getChannels();
+                                                       int ch = sm.getChannel();
+                                                       int note = sm.getData1();
+                                                       int vel = sm.getData2();
+                                                       outMidiChannels[ch].noteOn(note, vel);
+                                                       outMidiChannels[ch].noteOff(note, vel);
+                                               }
+                                       }
+                               }
+                               if( pairNoteOnOffModel.isSelected() ) {
+                                       int maxIndex = selectionModel.getMaxSelectionIndex();
+                                       int partnerIndex;
+                                       for( int i=minIndex; i<=maxIndex; i++ ) {
+                                               if( ! selectionModel.isSelectedIndex(i) ) continue;
+                                               partnerIndex = model.getIndexOfPartnerFor(i);
+                                               if( partnerIndex >= 0 && ! selectionModel.isSelectedIndex(partnerIndex) )
+                                                       selectionModel.addSelectionInterval(partnerIndex, partnerIndex);
+                                       }
+                               }
+                       }
+               });
        }
        /**
-        * このテーブルビューが表示するデータを提供する
-        * トラック(イベントリスト)データモデルを返します。
+        * このテーブルビューが表示するデータを提供するトラック(イベントリスト)データモデルを返します。
         * @return トラック(イベントリスト)データモデル
         */
        @Override
        public TrackEventListTableModel getModel() {
                return (TrackEventListTableModel) dataModel;
        }
+       /**
+        * このテーブルビューが表示するデータを提供するトラック(イベントリスト)データモデルを設定します。
+        * @param model トラック(イベントリスト)データモデル
+        */
        public void setModel(TrackEventListTableModel model) {
-               TrackEventListTableModel oldModel = getModel();
-               if( oldModel == model ) return;
+               if( dataModel == model ) return;
                if( model == null ) {
-                       model = getModel().getParent().getParent().emptyEventListTableModel;
+                       PlaylistTableModel playlist = getModel().getParent().getParent();
+                       model = playlist.emptyEventListTableModel;
                        queryJumpEventAction.setEnabled(false);
                        queryAddEventAction.setEnabled(false);
 
@@ -104,10 +145,11 @@ public class MidiEventTable extends JTable {
                        queryJumpEventAction.setEnabled(true);
                        queryAddEventAction.setEnabled(true);
                }
-               oldModel.getSelectionModel().removeListSelectionListener(eventSelectionListener);
+               selectionModel.removeListSelectionListener(selectionListener);
                super.setModel(model);
                setSelectionModel(model.getSelectionModel());
-               model.getSelectionModel().addListSelectionListener(eventSelectionListener);
+               titleLabel.updateTrackNumber(model.getParent().getSelectionModel().getMinSelectionIndex());
+               selectionModel.addListSelectionListener(selectionListener);
        }
        /**
         * タイトルラベル
@@ -126,64 +168,6 @@ public class MidiEventTable extends JTable {
                        setText(text);
                }
        }
-
-       /**
-        * イベント選択リスナー
-        */
-       private EventSelectionListener eventSelectionListener;
-       /**
-        * 選択イベントの変更に反応するリスナー
-        */
-       private class EventSelectionListener implements ListSelectionListener {
-               public EventSelectionListener() {
-                       getModel().getSelectionModel().addListSelectionListener(this);
-               }
-               @Override
-               public void valueChanged(ListSelectionEvent e) {
-                       if( e.getValueIsAdjusting() )
-                               return;
-                       if( getSelectionModel().isSelectionEmpty() ) {
-                               queryPasteEventAction.setEnabled(false);
-                               copyEventAction.setEnabled(false);
-                               deleteEventAction.setEnabled(false);
-                               cutEventAction.setEnabled(false);
-                       }
-                       else {
-                               copyEventAction.setEnabled(true);
-                               deleteEventAction.setEnabled(true);
-                               cutEventAction.setEnabled(true);
-                               TrackEventListTableModel trackModel = getModel();
-                               int minIndex = getSelectionModel().getMinSelectionIndex();
-                               MidiEvent midiEvent = trackModel.getMidiEvent(minIndex);
-                               if( midiEvent != null ) {
-                                       MidiMessage msg = midiEvent.getMessage();
-                                       if( msg instanceof ShortMessage ) {
-                                               ShortMessage sm = (ShortMessage)msg;
-                                               int cmd = sm.getCommand();
-                                               if( cmd == 0x80 || cmd == 0x90 || cmd == 0xA0 ) {
-                                                       // ノート番号を持つ場合、音を鳴らす。
-                                                       MidiChannel outMidiChannels[] = outputMidiDevice.getChannels();
-                                                       int ch = sm.getChannel();
-                                                       int note = sm.getData1();
-                                                       int vel = sm.getData2();
-                                                       outMidiChannels[ch].noteOn(note, vel);
-                                                       outMidiChannels[ch].noteOff(note, vel);
-                                               }
-                                       }
-                               }
-                               if( pairNoteOnOffModel.isSelected() ) {
-                                       int maxIndex = getSelectionModel().getMaxSelectionIndex();
-                                       int partnerIndex;
-                                       for( int i=minIndex; i<=maxIndex; i++ ) {
-                                               if( ! getSelectionModel().isSelectedIndex(i) ) continue;
-                                               partnerIndex = trackModel.getIndexOfPartnerFor(i);
-                                               if( partnerIndex >= 0 && ! getSelectionModel().isSelectedIndex(partnerIndex) )
-                                                       getSelectionModel().addSelectionInterval(partnerIndex, partnerIndex);
-                                       }
-                               }
-                       }
-               }
-       }
        /**
         * Pair noteON/OFF トグルボタンモデル
         */
@@ -233,7 +217,7 @@ public class MidiEventTable extends JTable {
                        MidiEvent partnerEvent = null;
                        eventDialog.midiMessageForm.setMessage(
                                selectedMidiEvent.getMessage(),
-                               trackModel.getParent().charset
+                               trackModel.getParent().getCharset()
                        );
                        if( eventDialog.midiMessageForm.isNote() ) {
                                int partnerIndex = trackModel.getIndexOfPartnerFor(selectedIndex);
@@ -279,7 +263,7 @@ public class MidiEventTable extends JTable {
                        long tick = tickPositionModel.getTickPosition();
                        MidiMessageForm form = eventDialog.midiMessageForm;
                        SequenceTrackListTableModel seqModel = trackModel.getParent();
-                       MidiMessage msg = form.getMessage(seqModel.charset);
+                       MidiMessage msg = form.getMessage(seqModel.getCharset());
                        if( msg == null ) {
                                return false;
                        }
@@ -418,7 +402,9 @@ public class MidiEventTable extends JTable {
                                        ChordHelperApplet.VersionInfo.NAME,
                                        JOptionPane.YES_NO_OPTION,
                                        JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION
-                       ) getModel().removeSelectedMidiEvents();
+                       ) {
+                               getModel().removeMidiEvents(getModel().getSelectedMidiEvents());
+                       }
                }
        };
        /**
index 59ae872..e9e697f 100644 (file)
@@ -79,6 +79,10 @@ public class MidiSequenceEditorDialog extends JDialog {
                }
        };
        /**
+        * プレイリストビュー(シーケンスリスト)
+        */
+       public PlaylistTable playlistTable;
+       /**
         * このエディタダイアログが表示しているプレイリストモデルを返します。
         * @return プレイリストモデル
         */
@@ -115,10 +119,6 @@ public class MidiSequenceEditorDialog extends JDialog {
         */
        public NewSequenceDialog newSequenceDialog;
        /**
-        * プレイリストビュー(シーケンスリスト)
-        */
-       public PlaylistTable playlistTable;
-       /**
         * 新しい {@link MidiSequenceEditorDialog} を構築します。
         * @param playlistTableModel このエディタが参照するプレイリストモデル
         * @param eventDialog MIDIイベント入力ダイアログ
@@ -126,9 +126,9 @@ public class MidiSequenceEditorDialog extends JDialog {
         * @param midiDeviceDialogOpenAction MIDIデバイスダイアログを開くアクション
         */
        public MidiSequenceEditorDialog(PlaylistTableModel playlistTableModel, MidiEventDialog eventDialog, VirtualMidiDevice outputMidiDevice, Action midiDeviceDialogOpenAction) {
-               playlistTable = new PlaylistTable(playlistTableModel, midiDeviceDialogOpenAction);
                MidiEventTable eventListTable = new MidiEventTable(playlistTableModel.emptyEventListTableModel, eventDialog, outputMidiDevice);
                SequenceTrackListTable trackListTable = new SequenceTrackListTable(playlistTableModel.emptyTrackListTableModel, eventListTable);
+               playlistTable = new PlaylistTable(playlistTableModel, midiDeviceDialogOpenAction, trackListTable);
                newSequenceDialog = new NewSequenceDialog(playlistTableModel, outputMidiDevice);
                setTitle("MIDI Editor/Playlist - "+ChordHelperApplet.VersionInfo.NAME);
                setBounds( 150, 200, 900, 500 );
@@ -149,12 +149,10 @@ public class MidiSequenceEditorDialog extends JDialog {
                                                { setMargin(ChordHelperApplet.ZERO_INSETS); }
                                        });
                                }
-                               if(playlistTable.base64EncodeAction != null) {
-                                       add(Box.createRigidArea(new Dimension(5, 0)));
-                                       add(new JButton(playlistTable.base64EncodeAction) {
-                                               { setMargin(ChordHelperApplet.ZERO_INSETS); }
-                                       });
-                               }
+                               add(Box.createRigidArea(new Dimension(5, 0)));
+                               add(new JButton(playlistTable.base64EncodeAction) {
+                                       { setMargin(ChordHelperApplet.ZERO_INSETS); }
+                               });
                                add(Box.createRigidArea(new Dimension(5, 0)));
                                add(new JButton(playlistTableModel.getMoveToTopAction()) {
                                        { setMargin(ChordHelperApplet.ZERO_INSETS); }
index 148ccaf..9866963 100644 (file)
@@ -56,9 +56,10 @@ public class PlaylistTable extends JTable {
         * プレイリストビューを構築します。
         * @param model プレイリストデータモデル
         * @param midiDeviceDialogOpenAction MIDIデバイスダイアログを開くアクション
+        * @param trackListTable トラックリストテーブル(子テーブル)
         */
-       public PlaylistTable(PlaylistTableModel model, Action midiDeviceDialogOpenAction) {
-               super(model, null, model.sequenceListSelectionModel);
+       public PlaylistTable(PlaylistTableModel model, Action midiDeviceDialogOpenAction, SequenceTrackListTable trackListTable) {
+               super(model, null, model.getSelectionModel());
                this.midiDeviceDialogOpenAction = midiDeviceDialogOpenAction;
                try {
                        midiFileChooser = new MidiFileChooser();
@@ -111,6 +112,10 @@ public class PlaylistTable extends JTable {
                        tc.setPreferredWidth(c.preferredWidth);
                        if( c == PlaylistTableModel.Column.LENGTH ) lengthColumn = tc;
                });
+               selectionModel.addListSelectionListener(event->{
+                       if( event.getValueIsAdjusting() ) return;
+                       trackListTable.setModel(getModel().getSelectedSequenceModel());
+               });
        }
        private TableColumn lengthColumn;
        @Override
@@ -301,8 +306,7 @@ public class PlaylistTable extends JTable {
                                ) break;
                        } catch(Exception ex) {
                                JOptionPane.showMessageDialog(
-                                               getRootPane(), ex,
-                                               ChordHelperApplet.VersionInfo.NAME,
+                                               getRootPane(), ex, ChordHelperApplet.VersionInfo.NAME,
                                                JOptionPane.ERROR_MESSAGE);
                                break;
                        }
@@ -332,12 +336,11 @@ public class PlaylistTable extends JTable {
                                                JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION
                                ) return;
                        }
-                       if( ! model.sequenceListSelectionModel.isSelectionEmpty() ) try {
-                               model.remove(model.sequenceListSelectionModel.getMinSelectionIndex());
+                       if( ! model.getSelectionModel().isSelectionEmpty() ) try {
+                               model.remove(model.getSelectionModel().getMinSelectionIndex());
                        } catch (Exception ex) {
                                JOptionPane.showMessageDialog(
-                                               ((JComponent)event.getSource()).getRootPane(),
-                                               ex,
+                                               ((JComponent)event.getSource()).getRootPane(), ex,
                                                ChordHelperApplet.VersionInfo.NAME,
                                                JOptionPane.ERROR_MESSAGE);
                        }
@@ -380,8 +383,7 @@ public class PlaylistTable extends JTable {
                                }
                                catch( Exception ex ) {
                                        JOptionPane.showMessageDialog(
-                                                       rootPane, ex,
-                                                       ChordHelperApplet.VersionInfo.NAME,
+                                                       rootPane, ex, ChordHelperApplet.VersionInfo.NAME,
                                                        JOptionPane.ERROR_MESSAGE);
                                }
                        }
@@ -408,8 +410,7 @@ public class PlaylistTable extends JTable {
                                        if( firstIndex >= 0 ) playlist.play(firstIndex);
                                } catch (Exception ex) {
                                        JOptionPane.showMessageDialog(
-                                                       rootPane, ex,
-                                                       ChordHelperApplet.VersionInfo.NAME,
+                                                       rootPane, ex, ChordHelperApplet.VersionInfo.NAME,
                                                        JOptionPane.ERROR_MESSAGE);
                                }
                        }
index 18244b6..61709e5 100644 (file)
@@ -46,9 +46,10 @@ public class PlaylistTableModel extends AbstractTableModel {
         */
        public final TrackEventListTableModel emptyEventListTableModel = new TrackEventListTableModel(emptyTrackListTableModel, null);
        /**
-        * 選択されているシーケンスのインデックス
+        * このプレイリストの選択モデルを返します。
         */
-       public final ListSelectionModel sequenceListSelectionModel = new DefaultListSelectionModel() {
+       public ListSelectionModel getSelectionModel() { return selectionModel; }
+       private ListSelectionModel selectionModel = new DefaultListSelectionModel() {
                {
                        setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
                }
@@ -152,12 +153,12 @@ public class PlaylistTableModel extends AbstractTableModel {
                        setEnebledBySelection();
                }
                protected void setEnebledBySelection() {
-                       int index = sequenceListSelectionModel.getMinSelectionIndex();
+                       int index = selectionModel.getMinSelectionIndex();
                        setEnabled(index >= 0);
                }
                private void init(String tooltip) {
                        putValue(Action.SHORT_DESCRIPTION, tooltip);
-                       sequenceListSelectionModel.addListSelectionListener(this);
+                       selectionModel.addListSelectionListener(this);
                        setEnebledBySelection();
                }
        }
@@ -274,7 +275,7 @@ public class PlaylistTableModel extends AbstractTableModel {
                        public boolean isCellEditable() { return true; }
                        @Override
                        public Object getValueOf(SequenceTrackListTableModel sequenceModel) {
-                               return sequenceModel.charset;
+                               return sequenceModel.getCharset();
                        }
                },
                /** タイミング解像度 */
@@ -361,7 +362,7 @@ public class PlaylistTableModel extends AbstractTableModel {
                case CHARSET:
                        // 文字コードの変更
                        SequenceTrackListTableModel seq = sequenceModelList.get(row);
-                       seq.charset = Charset.forName(val.toString());
+                       seq.setCharset(Charset.forName(val.toString()));
                        fireTableCellUpdated(row, column);
                        // シーケンス名の表示更新
                        fireTableCellUpdated(row, Column.NAME.ordinal());
@@ -384,8 +385,8 @@ public class PlaylistTableModel extends AbstractTableModel {
         * @return 選択されたMIDIシーケンスのテーブルモデル(非選択時はnull)
         */
        public SequenceTrackListTableModel getSelectedSequenceModel() {
-               if( sequenceListSelectionModel.isSelectionEmpty() ) return null;
-               int selectedIndex = sequenceListSelectionModel.getMinSelectionIndex();
+               if( selectionModel.isSelectionEmpty() ) return null;
+               int selectedIndex = selectionModel.getMinSelectionIndex();
                if( selectedIndex >= sequenceModelList.size() ) return null;
                return sequenceModelList.get(selectedIndex);
        }
@@ -400,7 +401,7 @@ public class PlaylistTableModel extends AbstractTableModel {
                sequenceModelList.add(new SequenceTrackListTableModel(this, sequence, filename));
                int lastIndex = sequenceModelList.size() - 1;
                fireTableRowsInserted(lastIndex, lastIndex);
-               sequenceListSelectionModel.setSelectionInterval(lastIndex, lastIndex);
+               selectionModel.setSelectionInterval(lastIndex, lastIndex);
                return lastIndex;
        }
        /**
index d093840..7a114fc 100644 (file)
@@ -12,11 +12,9 @@ import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JTable;
 import javax.swing.ListSelectionModel;
-import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 import javax.swing.event.TableModelEvent;
 import javax.swing.table.TableCellEditor;
-import javax.swing.table.TableColumnModel;
 
 import camidion.chordhelper.ChordHelperApplet;
 import camidion.chordhelper.music.MIDISpec;
@@ -26,9 +24,42 @@ import camidion.chordhelper.music.MIDISpec;
  */
 public class SequenceTrackListTable extends JTable {
        /**
-        * MIDIイベントリストテーブルビュー(選択中のトラックの中身)
+        * トラック追加アクション
+        */
+       Action addTrackAction = new AbstractAction("New") {
+               {
+                       String tooltip = "Append new track - 新しいトラックの追加";
+                       putValue(Action.SHORT_DESCRIPTION, tooltip);
+                       setEnabled(false);
+               }
+               @Override
+               public void actionPerformed(ActionEvent e) { getModel().createTrack(); }
+       };
+       /**
+        * トラック削除アクション
+        */
+       Action deleteTrackAction = new AbstractAction("Delete", MidiSequenceEditorDialog.deleteIcon) {
+               public static final String CONFIRM_MESSAGE =
+                               "Do you want to delete selected track ?\n選択したトラックを削除しますか?";
+               {
+                       putValue(Action.SHORT_DESCRIPTION, "Delete selected track - 選択したトラックを削除");
+                       setEnabled(false);
+               }
+               @Override
+               public void actionPerformed(ActionEvent event) {
+                       if( JOptionPane.showConfirmDialog(
+                                       ((JComponent)event.getSource()).getRootPane(),
+                                       CONFIRM_MESSAGE,
+                                       ChordHelperApplet.VersionInfo.NAME,
+                                       JOptionPane.YES_NO_OPTION,
+                                       JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION
+                       ) getModel().deleteSelectedTracks();
+               }
+       };
+       /**
+        * トラック選択リスナー
         */
-       public MidiEventTable eventListTable;
+       private ListSelectionListener trackSelectionListener;
        /**
         * トラックリストテーブルビューを構築します。
         * @param model シーケンス(トラックリスト)データモデル
@@ -36,9 +67,6 @@ public class SequenceTrackListTable extends JTable {
         */
        public SequenceTrackListTable(SequenceTrackListTableModel model, MidiEventTable eventListTable) {
                super(model, null, model.getSelectionModel());
-               this.eventListTable = eventListTable;
-               //
-               // 録音対象のMIDIチャンネルをコンボボックスで選択できるようにする
                getColumnModel()
                        .getColumn(SequenceTrackListTableModel.Column.RECORD_CHANNEL.ordinal())
                        .setCellEditor(new DefaultCellEditor(new JComboBox<String>(){{
@@ -47,15 +75,17 @@ public class SequenceTrackListTable extends JTable {
                                addItem("ALL");
                        }}));
                setAutoCreateColumnsFromModel(false);
-               model.getParent().sequenceListSelectionModel.addListSelectionListener(titleLabel);
-               TableColumnModel colModel = getColumnModel();
                Arrays.stream(SequenceTrackListTableModel.Column.values()).forEach(c->
-                       colModel.getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
+                       getColumnModel().getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
                );
+               selectionModel.addListSelectionListener(trackSelectionListener = event->{
+                       if( event.getValueIsAdjusting() ) return;
+                       deleteTrackAction.setEnabled(! selectionModel.isSelectionEmpty());
+                       eventListTable.setModel(getModel().getSelectedTrackModel());
+               });
        }
        /**
-        * このテーブルビューが表示するデータを提供する
-        * シーケンス(トラックリスト)データモデルを返します。
+        * このテーブルビューが表示するデータを提供するシーケンス(トラックリスト)データモデルを返します。
         * @return シーケンス(トラックリスト)データモデル
         */
        @Override
@@ -63,52 +93,50 @@ public class SequenceTrackListTable extends JTable {
                return (SequenceTrackListTableModel)dataModel;
        }
        /**
-        * タイトルラベル
+        * このテーブルビューが表示するデータを提供するシーケンス(トラックリスト)データモデルを設定します。
+        * @param model シーケンス(トラックリスト)データモデル
+        */
+       public void setModel(SequenceTrackListTableModel model) {
+               if( dataModel == model ) return;
+               cancelCellEditing();
+               if( model == null ) {
+                       model = getModel().getParent().emptyTrackListTableModel;
+                       addTrackAction.setEnabled(false);
+               }
+               else {
+                       addTrackAction.setEnabled(true);
+               }
+               selectionModel.clearSelection();
+               selectionModel.removeListSelectionListener(trackSelectionListener);
+               super.setModel(model);
+               setSelectionModel(model.getSelectionModel());
+               titleLabel.setSelection(model.getParent().getSelectionModel());
+               selectionModel.addListSelectionListener(trackSelectionListener);
+       }
+       /**
+        * 曲番号表示付きタイトルラベル
         */
        TitleLabel titleLabel = new TitleLabel();
        /**
-        * 親テーブルの選択シーケンスの変更に反応する
         * 曲番号表示付きタイトルラベル
         */
-       private class TitleLabel extends JLabel implements ListSelectionListener {
+       private class TitleLabel extends JLabel {
                private static final String TITLE = "Tracks";
                public TitleLabel() { setText(TITLE); }
-               @Override
-               public void valueChanged(ListSelectionEvent event) {
-                       if( event.getValueIsAdjusting() ) return;
-                       SequenceTrackListTableModel oldModel = getModel();
-                       SequenceTrackListTableModel newModel = oldModel.getParent().getSelectedSequenceModel();
-                       if( oldModel == newModel ) return;
-                       //
-                       // MIDIチャンネル選択中のときはキャンセルする
-                       cancelCellEditing();
-                       //
+               public void setSelection(ListSelectionModel sequenceSelectionModel) {
                        String text = TITLE;
-                       ListSelectionModel sm = oldModel.getParent().sequenceListSelectionModel;
-                       if( ! sm.isSelectionEmpty() ) {
-                               int index = sm.getMinSelectionIndex();
+                       if( ! sequenceSelectionModel.isSelectionEmpty() ) {
+                               int index = sequenceSelectionModel.getMinSelectionIndex();
                                if( index >= 0 ) text = String.format(text+" - MIDI file #%d", index);
                        }
                        setText(text);
-                       if( newModel == null ) {
-                               newModel = oldModel.getParent().emptyTrackListTableModel;
-                               addTrackAction.setEnabled(false);
-                       }
-                       else {
-                               addTrackAction.setEnabled(true);
-                       }
-                       oldModel.getSelectionModel().removeListSelectionListener(trackSelectionListener);
-                       setModel(newModel);
-                       setSelectionModel(newModel.getSelectionModel());
-                       newModel.getSelectionModel().addListSelectionListener(trackSelectionListener);
                }
        }
        /**
         * {@inheritDoc}
         *
         * <p>このトラックリストテーブルのデータが変わったときに編集を解除します。
-        * 例えば、イベントが編集された場合や、
-        * シーケンサーからこのモデルが外された場合がこれに該当します。
+        * 例えば、イベントが編集された場合や、シーケンサーからこのモデルが外された場合がこれに該当します。
         * </p>
         */
        @Override
@@ -123,47 +151,4 @@ public class SequenceTrackListTable extends JTable {
                TableCellEditor currentCellEditor = getCellEditor();
                if( currentCellEditor != null ) currentCellEditor.cancelCellEditing();
        }
-       /**
-        * トラック追加アクション
-        */
-       Action addTrackAction = new AbstractAction("New") {
-               {
-                       String tooltip = "Append new track - 新しいトラックの追加";
-                       putValue(Action.SHORT_DESCRIPTION, tooltip);
-                       setEnabled(false);
-               }
-               @Override
-               public void actionPerformed(ActionEvent e) { getModel().createTrack(); }
-       };
-       /**
-        * トラック削除アクション
-        */
-       Action deleteTrackAction = new AbstractAction("Delete", MidiSequenceEditorDialog.deleteIcon) {
-               public static final String CONFIRM_MESSAGE =
-                               "Do you want to delete selected track ?\n選択したトラックを削除しますか?";
-               {
-                       putValue(Action.SHORT_DESCRIPTION, "Delete selected track - 選択したトラックを削除");
-                       setEnabled(false);
-               }
-               @Override
-               public void actionPerformed(ActionEvent event) {
-                       if( JOptionPane.showConfirmDialog(
-                                       ((JComponent)event.getSource()).getRootPane(),
-                                       CONFIRM_MESSAGE,
-                                       ChordHelperApplet.VersionInfo.NAME,
-                                       JOptionPane.YES_NO_OPTION,
-                                       JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION
-                       ) getModel().deleteSelectedTracks();
-               }
-       };
-       /**
-        * トラック選択リスナー
-        */
-       private ListSelectionListener trackSelectionListener = event->{
-               if( event.getValueIsAdjusting() ) return;
-               ListSelectionModel selModel = getModel().getSelectionModel();
-               deleteTrackAction.setEnabled(! selModel.isSelectionEmpty());
-               eventListTable.titleLabel.updateTrackNumber(selModel.getMinSelectionIndex());
-               eventListTable.setModel(getModel().getSelectedTrackModel());
-       };
-}
\ No newline at end of file
+}
index 1c9f044..4c120ee 100644 (file)
@@ -47,40 +47,50 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
                        this.preferredWidth = preferredWidth;
                }
        }
-       private PlaylistTableModel sequenceListTableModel;
        /**
         * このモデルを収容している親のプレイリストを返します。
         */
        public PlaylistTableModel getParent() { return sequenceListTableModel; }
-       /**
-        * ラップされたMIDIシーケンス
-        */
-       private Sequence sequence;
+       private PlaylistTableModel sequenceListTableModel;
        /**
         * ラップされたMIDIシーケンスのtickインデックス
         */
        private SequenceTickIndex sequenceTickIndex;
        /**
-        * MIDIファイル名
+        * ファイル名を返します。
+        * @return ファイル名
         */
+       public String getFilename() { return filename; }
        private String filename;
        /**
-        * テキスト部分の文字コード(タイトル、歌詞など)
+        * ファイル名を設定します。
+        * @param filename ファイル名
+        */
+       public void setFilename(String filename) { this.filename = filename; }
+       /**
+        * タイトルや歌詞などで使うテキストの文字コードを返します。
+        * @return テキストの文字コード
+        */
+       public Charset getCharset() { return charset; }
+       private Charset charset = Charset.defaultCharset();
+       /**
+        * タイトルや歌詞などで使うテキストの文字コードを設定します。
+        * @param charset テキストの文字コード
         */
-       public Charset charset = Charset.defaultCharset();
+       public void setCharset(Charset charset) { this.charset = charset; }
        /**
         * トラックリスト
         */
        private List<TrackEventListTableModel> trackModelList = new ArrayList<>();
-       private ListSelectionModel trackListSelectionModel = new DefaultListSelectionModel(){
+       private ListSelectionModel selectionModel = new DefaultListSelectionModel(){
                {
                        setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
                }
        };
        /**
-        * 選択状態を返します。
+        * このトラックリストの選択モデルを返します。
         */
-       public ListSelectionModel getSelectionModel() { return trackListSelectionModel; }
+       public ListSelectionModel getSelectionModel() { return selectionModel; }
        /**
         * MIDIシーケンスとファイル名から {@link SequenceTrackListTableModel} を構築します。
         * @param sequenceListTableModel 親のプレイリスト
@@ -203,6 +213,7 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
         * @return MIDIシーケンス
         */
        public Sequence getSequence() { return sequence; }
+       private Sequence sequence;
        /**
         * MIDIシーケンスのマイクロ秒単位の長さを返します。
         * 曲が長すぎて {@link Sequence#getMicrosecondLength()} が負数を返してしまった場合の補正も行います。
@@ -259,12 +270,12 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
        public void fireTimeSignatureChanged() {
                sequenceTickIndex = new SequenceTickIndex(sequence);
        }
-       private boolean isModified = false;
        /**
         * 変更されたかどうかを返します。
         * @return 変更済みのときtrue
         */
        public boolean isModified() { return isModified; }
+       private boolean isModified = false;
        /**
         * 変更されたかどうかを設定します。
         * @param isModified 変更されたときtrue
@@ -275,16 +286,6 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
                if( index >= 0 ) sequenceListTableModel.fireTableRowsUpdated(index, index);
        }
        /**
-        * ファイル名を設定します。
-        * @param filename ファイル名
-        */
-       public void setFilename(String filename) { this.filename = filename; }
-       /**
-        * ファイル名を返します。
-        * @return ファイル名
-        */
-       public String getFilename() { return filename; }
-       /**
         * このシーケンスを表す文字列としてシーケンス名を返します。シーケンス名がない場合は空文字列を返します。
         */
        @Override
@@ -292,6 +293,7 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
                byte b[] = MIDISpec.getNameBytesOf(sequence);
                return b == null ? "" : new String(b, charset);
        }
+
        /**
         * シーケンス名を設定します。
         * @param name シーケンス名
@@ -336,10 +338,10 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
         * @return トラックモデル(見つからない場合null)
         */
        public TrackEventListTableModel getSelectedTrackModel() {
-               if( trackListSelectionModel.isSelectionEmpty() ) return null;
+               if( selectionModel.isSelectionEmpty() ) return null;
                Track tracks[] = sequence.getTracks();
                if( tracks.length == 0 ) return null;
-               Track t = tracks[trackListSelectionModel.getMinSelectionIndex()];
+               Track t = tracks[selectionModel.getMinSelectionIndex()];
                return trackModelList.stream().filter(tm -> tm.getTrack() == t).findFirst().orElse(null);
        }
        /**
@@ -361,20 +363,20 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
                setModified(true);
                int lastRow = getRowCount() - 1;
                fireTableRowsInserted(lastRow, lastRow);
-               trackListSelectionModel.setSelectionInterval(lastRow, lastRow);
+               selectionModel.setSelectionInterval(lastRow, lastRow);
                return lastRow;
        }
        /**
         * 選択されているトラックを削除します。
         */
        public void deleteSelectedTracks() {
-               if( trackListSelectionModel.isSelectionEmpty() )
+               if( selectionModel.isSelectionEmpty() )
                        return;
-               int minIndex = trackListSelectionModel.getMinSelectionIndex();
-               int maxIndex = trackListSelectionModel.getMaxSelectionIndex();
+               int minIndex = selectionModel.getMinSelectionIndex();
+               int maxIndex = selectionModel.getMaxSelectionIndex();
                Track tracks[] = sequence.getTracks();
                for( int i = maxIndex; i >= minIndex; i-- ) {
-                       if( ! trackListSelectionModel.isSelectedIndex(i) ) continue;
+                       if( ! selectionModel.isSelectedIndex(i) ) continue;
                        sequence.deleteTrack(tracks[i]);
                        trackModelList.remove(i);
                }
index 8f700f5..eb152b3 100644 (file)
@@ -63,7 +63,7 @@ public class TrackEventListTableModel extends AbstractTableModel {
                MESSAGE("MIDI Message", String.class, 300) {
                        @Override
                        public Object getValue(SequenceTrackListTableModel seq, MidiEvent event) {
-                               return MIDISpec.msgToString(event.getMessage(), seq.charset);
+                               return MIDISpec.msgToString(event.getMessage(), seq.getCharset());
                        }
                };
                private String title;
@@ -224,7 +224,8 @@ public class TrackEventListTableModel extends AbstractTableModel {
                byte b[] = MIDISpec.getNameBytesOf(track);
                if( b == null ) return "";
                Charset cs = Charset.defaultCharset();
-               if( sequenceTrackListTableModel != null ) cs = sequenceTrackListTableModel.charset;
+               if( sequenceTrackListTableModel != null )
+                       cs = sequenceTrackListTableModel.getCharset();
                return new String(b, cs);
        }
        /**
@@ -234,7 +235,7 @@ public class TrackEventListTableModel extends AbstractTableModel {
         */
        public boolean setString(String name) {
                if( name.equals(toString()) || ! MIDISpec.setNameBytesOf(
-                       track, name.getBytes(sequenceTrackListTableModel.charset))
+                       track, name.getBytes(sequenceTrackListTableModel.getCharset()))
                ) return false;
                sequenceTrackListTableModel.setModified(true);
                fireTableDataChanged();
@@ -501,11 +502,4 @@ public class TrackEventListTableModel extends AbstractTableModel {
                if(lastIndex < 0) lastIndex = 0;
                fireTableRowsDeleted(oldLastIndex, lastIndex);
        }
-       /**
-        * 引数の選択内容が示すMIDIイベントを除去します。
-        * @param selectionModel 選択内容
-        */
-       public void removeSelectedMidiEvents() {
-               removeMidiEvents(getSelectedMidiEvents());
-       }
 }