0

First, my code (It is far from perfect, I don't really know what I am doing) is this:

   public enum Chord { MAJOR, MINOR, DIMINISHED, BASS, BASS2 }
   public enum Scales { C, D, E, F, G, A }
public class EnumTest
{
Chord chord;
public EnumTest(Chord chord)
{
    this.chord = chord;
}
public void tellItLikeItIs()
{

switch (chord) {

    case MAJOR:
            for(Scales C : Scales.values())
                System.out.println(C + " " + C.ordinal());
                break;

//I've tried in the CHORD enum going MAJOR(0, 2, 4) but I don't think that was correct
    case MINOR: System.out.println("C, Eb, G");
                break;
    default:
        System.out.println("I screwed up");
        break;

}
}


public static void main(String[] args)
{

EnumTest firstDay = new EnumTest(Chord.MAJOR);
firstDay.tellItLikeItIs();
EnumTest thirdDay = new EnumTest(Chord.MINOR);
thirdDay.tellItLikeItIs();
System.out.println("Here are all Scale degrees" +
                   " and their ordinal values: ");
for(Scales C : Scales.values())
  System.out.println(C + " " + C.ordinal());



}

}

I might be missing a few brackets and things, I had trouble posting some of it using the code tool. My question is, for case MAJOR, I can get the compiler to print C 0, D 1, E 2, etc.. except I only want it to print C, E and G (0, 2, 4). Is there a way to select ONLY these 3 ordinal values for a major chord and print those?

Also, in the Scales enum I also need the sharps (C, C#, D, D#..) except the sharps are 'illegal characters' and I get _MusicChord\Scales.java:2: illegal character: \35 I tried to look into escape characters, but I either didn't understand the article I read or I was looking at the wrong thing. Could someone also tell me how to add the #'s into the Scales class without them being illegal characters? Any help is appreciated

1
  • The reason I am trying to use ordinals is because eventually I want to plug this in to a GUI and have the user select a note (A,B,C.. etc..) and then offset the value from the C scale (ex: C(0) = C(0) E(2) G(4), while D is just C offset by 1 whole step (if that makes sense to you all)) The only reasonable way I could think of (and a way suggested to me) was to try to use ordinals Commented Nov 4, 2011 at 13:25

5 Answers 5

2

In the following example you can see how you could address some of the problems you are facing:

public class EnumTest
{
    public enum Chord
    {
        MAJOR,
        MINOR,
        DIMINISHED,
        BASS,
        BASS2
    }

    public enum Scales
    {
        C("C"),
        CSharp("C#"),
        E("E"),
        F("F"),
        G("G"),
        A("A");

        private final String printName;

        Scales(String printName)
        {
            this.printName = printName;
        }

        public String getPrintName()
        {
            return printName;
        }

        public String toString()
        {
            return printName;
        }

        private static final Map<Chord, List<Scales>> scalesForChord;

        static
        {
            scalesForChord = new HashMap<Chord, List<Scales>>();

            scalesForChord.put(Chord.MAJOR, Arrays.asList(Scales.C, Scales.E, Scales.G));
        }

        public static List<Scales> getScalesForChord(Chord chord)
        {
            return scalesForChord.get(chord);
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

@ekaj to help understand Gandalf's answer it is helpful to realize that by using the keyword enum to define your Enum class is approximately equivalent to public class MyEnum extends java.lang.Enum<E>. Enum's in Java are more than just a "list holder" (which was my initial impression). See the documentation at the Java API docs to see what you can all do internal to your enum, etc. download.oracle.com/javase/6/docs/api
1

In addition to the other answers, you should not use .ordinal() because it makes your code harder to extend in the future. Example: What if you have to add an enum and its ordinal is not what you need it it be?

The ordinal is the 'position' of the ENUM in its declaration. In your example this happens to coincide with something that semantically makes sense to your domain.

It is a better idea to draw attention to this semantic importance by having constructors that take these values for the individual ENUMs, like in Gandalf's example. Instead of C("C"), have C("C", 1), and in addition to final String printName; also have a final String whateverThatNumberMeans;

Comments

0

To select only relevant elements of enum use if(c.ordinal() == 1) or better if(Chord.MAJOR.equals(c)) in loop. I hope I understood your question.

The second question is not very clear. If you want to use # as a part of identifier name please not it is impossible. This character is forbidden. But you can use it into toString() implementation if you want.

I hope this helps.

Comments

0

Do { C, Cs, D, ..., A, As, B }. Similarly, you could also do { C, Db, D, ..., A, Bb, B }. As a rule, stick with [[:alpha:]_][[:alnum:]_]* for names.

Comments

0

Try this for your case MAJOR:

case MAJOR:
            for (Scales c : EnumSet.of(Scales.C, Scales.E, Scales.G)) {
                System.out.println(c + " " + c.ordinal());
            }
            break;

and this for your Scales enum:

public enum Scales {
    C, Cs("C#"), D, Ds("D#"), E, F, G, A;
    private final String label;
    private Scales() {
        this.label = name();
    }
    private Scales(String label) {
        this.label = label;
    }
    @Override
    public String toString() { return label; }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.