1 package camidion.chordhelper.chorddiagram;
3 import java.awt.Dimension;
4 import java.awt.Insets;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.awt.event.AdjustmentEvent;
8 import java.awt.event.AdjustmentListener;
9 import java.awt.event.ItemEvent;
10 import java.awt.event.ItemListener;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.EnumMap;
14 import java.util.List;
16 import java.util.Objects;
18 import javax.swing.Box;
19 import javax.swing.BoxLayout;
20 import javax.swing.ButtonGroup;
21 import javax.swing.JPanel;
22 import javax.swing.JRadioButton;
23 import javax.swing.JScrollBar;
24 import javax.swing.JToggleButton;
25 import javax.swing.SwingConstants;
27 import camidion.chordhelper.ButtonIcon;
28 import camidion.chordhelper.ChordDisplayLabel;
29 import camidion.chordhelper.music.Chord;
30 import camidion.chordhelper.music.Note;
33 * ChordDiagram class for MIDI Chord Helper
36 * Copyright (C) 2004-2017 Akiyoshi Kamide
37 * http://www.yk.rim.or.jp/~kamide/music/chordhelper/
39 public class ChordDiagram extends JPanel {
40 /** コードダイアグラムの対象楽器を示す値 */
41 public static enum Instrument {
43 Guitar("E,B,G,D,A,E");
45 * コードダイアグラムの対象楽器を示す値を構築します。
46 * @param defaultOpenNotes 解放弦の音名(カンマ区切り)
48 private Instrument(String defaultOpenNotes) {
49 List<Integer> notes = new ArrayList<>();
50 for( String note : defaultOpenNotes.split(",") )
51 notes.add(Note.mod12(Note.toggleCo5(Note.co5Of(note))));
52 this.defaultOpenNotes = Collections.unmodifiableList(notes);
55 * デフォルトの開放弦の音階を表す、変更不可能なノート番号リストを返します。
56 * @return 開放弦の音階(固定値)を表すノート番号リスト
58 public List<Integer> getDefaultOpenNotes() { return defaultOpenNotes; }
59 private List<Integer> defaultOpenNotes;
61 * 開放弦の音階を表す、変更(チューニング)可能な ノート番号の配列を生成します。
63 * @return 開放弦の音階(デフォルト値)を表すノート番号の配列
65 public int[] createTunableOpenNotes() {
66 int[] r = new int[defaultOpenNotes.size()];
68 for(int note : defaultOpenNotes) r[i++] = note;
74 * @param capoComboBoxModel カポ値選択コンボボックスのデータモデル
76 public ChordDiagram(CapoComboBoxModel capoComboBoxModel) {
77 capoSelecterView.valueSelecter.setModel(capoComboBoxModel);
78 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
81 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
83 add(Box.createHorizontalStrut(2));
84 add(recordTextButton);
85 add(Box.createHorizontalStrut(2));
86 add(capoSelecterView);
89 add(Box.createHorizontalStrut(5));
92 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
96 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
102 setAlignmentY((float)0);
106 fretRangeScrollbar.setAlignmentY((float)1.0);
107 add(fretRangeScrollbar);
111 for(JRadioButton rb : instButtons.values())
113 setAlignmentY((float)1.0);
118 add(variationScrollbar);
125 public JToggleButton recordTextButton =
126 new JToggleButton("REC", new ButtonIcon(ButtonIcon.REC_ICON)) {
128 setMargin(new Insets(0,0,0,0));
129 setToolTipText("Record to text ON/OFF");
135 public ChordDisplayLabel titleLabel =
136 new ChordDisplayLabel("Chord Diagram",null,null) {
138 setHorizontalAlignment(SwingConstants.CENTER);
139 setVerticalAlignment(SwingConstants.BOTTOM);
145 private ChordDiagramDisplay diagramDisplay =
146 new ChordDiagramDisplay(Instrument.Ukulele) {
149 setPreferredSize(new Dimension(120,120));
155 private Map<Instrument,JRadioButton> instButtons =
156 new EnumMap<Instrument,JRadioButton>(Instrument.class) {
158 ButtonGroup buttonGroup = new ButtonGroup();
159 for( final Instrument instrument : Instrument.values() ) {
160 String label = instrument.toString();
161 JRadioButton radioButton = new JRadioButton(label) {
164 addActionListener(new ActionListener() {
166 public void actionPerformed(ActionEvent e) {
167 diagramDisplay.tune(instrument);
172 buttonGroup.add(radioButton);
173 put(instrument, radioButton);
175 get(Instrument.Ukulele).setSelected(true);
179 private JScrollBar variationScrollbar = new JScrollBar(JScrollBar.VERTICAL) {
181 setModel(diagramDisplay.chordVariations.indexModel);
182 addAdjustmentListener(
183 new AdjustmentListener() {
185 public void adjustmentValueChanged(AdjustmentEvent e) {
186 setToolTipText(diagramDisplay.chordVariations.getIndexDescription());
192 private JScrollBar fretRangeScrollbar = new JScrollBar(JScrollBar.HORIZONTAL) {
194 setModel(diagramDisplay.fretViewIndexModel);
195 setBlockIncrement(diagramDisplay.fretViewIndexModel.getExtent());
201 public CapoSelecterView capoSelecterView = new CapoSelecterView() {
203 checkbox.addItemListener(new ItemListener() {
205 public void itemStateChanged(ItemEvent e) { clear(); }
210 public void setBackground(Color bgColor) {
211 super.setBackground(bgColor);
212 if( diagramDisplay == null ) return;
213 diagramDisplay.setBackground(bgColor);
214 capoSelecterView.setBackground(bgColor);
215 capoSelecterView.valueSelecter.setBackground(bgColor);
216 variationScrollbar.setBackground(bgColor);
217 fretRangeScrollbar.setBackground(bgColor);
222 * <p>{@link #setChord(Chord)} の引数に null を指定して呼び出しているだけです。
225 public void clear() { setChord(null); }
228 * 表示中でない場合、指定のコードに関係なく null が設定されます。
230 * @param chord コード(クリアする場合は null)
232 public void setChord(Chord chord) {
233 if( ! isVisible() ) chord = null;
234 titleLabel.setChord(chord);
235 diagramDisplay.setChord(chord);
239 * @param instrument 対象楽器
240 * @throws NullPointerException 対象楽器がnullの場合
242 public void setTargetInstrument(Instrument instrument) {
243 instButtons.get(Objects.requireNonNull(instrument)).doClick();