Reading input keys from a shell I was cleaning up some old code and came across this (it's to read input from a terminal):
static public int read_input_key() {

    /*
    F1 ESC O P [27 79 80] 
    F2 ESC O Q [27 79 81] 
    F3 ESC O R [27 79 82] 
    F4 ESC O S [27 79 83]
    Up ESC [ A [27 91 65] 
    Down ESC [ B [27 91 66] 
    Left ESC [ D [27 91 68] 
    Right ESC [ C [27 91 67]
    Home ESC [ 1 ~ [27 91 49 126] 
    F5 ESC [ 1 5 ~ [27 91 49 53 126] 
    F6 ESC [ 1 7 ~ [27 91 49 55 126] 
    F7 ESC [ 1 8 ~ [27 91 49 56 126] 
    F8 ESC [ 1 9 ~ [27 91 49 57 126]
    End ESC [ 4 ~ [27 91 52 126] 
    Page-up ESC [ 5 ~ [27 91 53 126] 
    Page-down ESC [6 ~ [27 91 54 126]
    Insert ESC [ 2 ~ [27 91 50 126]
    F9 ESC [ 2 0 ~ [27 91 50 48 126] 
    F10 ESC [ 2 1 ~ [27 91 50 49 126] 
    F11 ESC [2 2 ~ [27 91 50 50 126] 
    F12 ESC [ 2 3 ~ [27 91 50 51 126]
    */

    // 

    try {

        if (System.in.available() != 0) {

            int c = System.in.read();
            if (c == 27) {

                switch (System.in.read()) {
                case 79:
                    switch (System.in.read()) {
                    case 80:
                        return VK_F1;
                    case 81:
                        return VK_F2;
                    case 82:
                        return VK_F3;
                    case 83:
                        return VK_F4;
                    }
                case 91:
                    switch (System.in.read()) {
                    case 65:
                        return VK_UP;
                    case 66:
                        return VK_DOWN;
                    case 68:
                        return VK_LEFT;
                    case 67:
                        return VK_RIGHT;
                    case 49: {
                        switch (System.in.read()) {
                        case 126:
                            return VK_HOME;
                        case 53:
                            return System.in.read() == 126 ? VK_F5 : 0;
                        case 55:
                            return System.in.read() == 126 ? VK_F6 : 0;
                        case 56:
                            return System.in.read() == 126 ? VK_F7 : 0;
                        case 57:
                            return System.in.read() == 126 ? VK_F8 : 0;
                        }
                    }
                    case 52:
                        return System.in.read() == 126 ? VK_END : 0;
                    case 53:
                        return System.in.read() == 126 ? VK_PAGE_UP : 0;
                    case 54:
                        return System.in.read() == 126 ? VK_PAGE_DOWN : 0;
                    case 50: {
                        switch (System.in.read()) {
                        case 126:
                            return VK_INSERT;
                        case 48:
                            return System.in.read() == 126 ? VK_F9 : 0;
                        case 49:
                            return System.in.read() == 126 ? VK_F10 : 0;
                        case 50:
                            return System.in.read() == 126 ? VK_F11 : 0;
                        case 51:
                            return System.in.read() == 126 ? VK_F12 : 0;
                        }
                    }
                    }
                }
            } else {
                return c;
            }
        }
    } catch (IOException e) {
        // restore terminal?
        e.printStackTrace();
    }

    return 0;
}

It work's fine, but I feel like it can be done really different. To explain the long comment (I should atleast refactor that), this for example:
    F1 ESC O P [27 79 80] 

Means when you press the F1 key you will get the sequence ESC O P, which is represented by the following ascii keys, 27 79 80.
I think you will be able to implement this in a cleaner way by representing the key codes as data instead of control flow. Not only will the resulting code be shorter, but it will be more abstract. If you need to add new sequences or support multiple sets of sequences, you will be able to use the same basic logic.
More specifically, a trie data structure is a good match for your problem. The mapping process is simple: start at the root, input a character, and follow the corresponding branch. If there is no branch, fail. This must be modified slightly to output the original character if it is the sequence does not start with 27.
There is no trie in the Java collections framework, so you will have to build your own. The signature should be something like
class AsciiTrie {
  AsciiTrie[] children;
  int data;
}

Given this data structure, your new algorithm is the following
private static int readInputKey(AsciiTrie t) {
  if (System.in.available() == 0) {
    return 0;
  }

  int c;
  int depth = 0;
  while (t != null) {
    try {
      c = System.in.read();
    } catch {
      // handle error properly
    }

    t = t.children[c];
    depth += 1;

    if (t.data != 0) {
      return t.data;
    }
  }

  if (depth == 1) {
    return c;
  } else {
    return 0;
  }
}

I have not included code to build or populate the trie. But it is quite similar to traversal.