public void reloadShortcuts() {
   for (Map.Entry<FPref, KeyboardShortcutField> e : shortcutFields.entrySet()) {
     e.getValue().reload(e.getKey());
   }
 }
  /** Constructor. */
  VSubmenuPreferences() {

    pnlPrefs.setOpaque(false);
    pnlPrefs.setLayout(new MigLayout("insets 0, gap 0, wrap 2"));

    // Spacing between components is defined here.
    final String sectionConstraints = "w 80%!, h 42px!, gap 10% 0 10px 10px, span 2 1";
    final String regularConstraints = "w 80%!, h 22px!, gap 10% 0 0 10px, span 2 1";

    // Troubleshooting
    pnlPrefs.add(new SectionLabel("Troubleshooting"), sectionConstraints);

    // Reset buttons
    final String twoButtonConstraints1 = "w 38%!, h 30px!, gap 10% 0 0 10px";
    final String twoButtonConstraints2 = "w 38%!, h 30px!, gap 0 0 0 10px";
    pnlPrefs.add(btnReset, twoButtonConstraints1);
    pnlPrefs.add(btnDeleteMatchUI, twoButtonConstraints2);
    pnlPrefs.add(btnDeleteEditorUI, twoButtonConstraints1);
    pnlPrefs.add(btnDeleteWorkshopUI, twoButtonConstraints2);
    pnlPrefs.add(btnUserProfileUI, twoButtonConstraints1);
    pnlPrefs.add(btnContentDirectoryUI, twoButtonConstraints2);

    // General Configuration
    pnlPrefs.add(new SectionLabel("General Configuration"), sectionConstraints + ", gaptop 2%");

    pnlPrefs.add(getPlayerNamePanel(), regularConstraints + ", h 26px!");
    pnlPrefs.add(
        new NoteLabel("Sets the name that you will be referred to by Forge during gameplay."),
        regularConstraints);

    pnlPrefs.add(cbCompactMainMenu, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "Enable for a space efficient sidebar that displays only one menu group at a time (RESTART REQUIRED)."),
        regularConstraints);

    // Gameplay Options
    pnlPrefs.add(new SectionLabel("Gameplay"), sectionConstraints + ", gaptop 2%");

    pnlPrefs.add(cbpAiProfiles, "w 80%!, gap 10% 0 0 10px, span 2 1");
    pnlPrefs.add(new NoteLabel("Choose your AI opponent."), regularConstraints);

    pnlPrefs.add(cbAnte, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Determines whether or not the game is played for ante."),
        regularConstraints);

    pnlPrefs.add(cbAnteMatchRarity, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Attempts to make antes the same rarity for all players."),
        regularConstraints);

    pnlPrefs.add(cbEnableAICheats, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "Allow the AI to cheat to gain advantage (for personalities that have cheat shuffling options set)."),
        regularConstraints);

    pnlPrefs.add(cbManaBurn, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Play with mana burn (from pre-Magic 2010 rules)."), regularConstraints);

    pnlPrefs.add(cbManaLostPrompt, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "When enabled, you get a warning if passing priority would cause you to lose mana in your mana pool."),
        regularConstraints);

    pnlPrefs.add(cbEnforceDeckLegality, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "Enforces deck legality relevant to each environment (minimum deck sizes, max card count etc)."),
        regularConstraints);

    pnlPrefs.add(cbCloneImgSource, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "When enabled clones will use their original art instead of the cloned card's art."),
        regularConstraints);

    pnlPrefs.add(cbPromptFreeBlocks, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "When enabled, if you would have to pay 0 to block, pay automatically without prompt."),
        regularConstraints);

    pnlPrefs.add(cbPauseWhileMinimized, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("When enabled, Forge pauses when minimized (primarily for AI vs AI)."),
        regularConstraints);

    // Deck building options
    pnlPrefs.add(new SectionLabel("Random Deck Generation"), sectionConstraints);

    pnlPrefs.add(cbRemoveSmall, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Disables 1/1 and 0/X creatures in generated decks."), regularConstraints);

    pnlPrefs.add(cbSingletons, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Disables non-land duplicates in generated decks."), regularConstraints);

    pnlPrefs.add(cbRemoveArtifacts, regularConstraints);
    pnlPrefs.add(new NoteLabel("Disables artifact cards in generated decks."), regularConstraints);

    // Deck building options
    pnlPrefs.add(new SectionLabel("Deck Editor Options"), sectionConstraints);

    pnlPrefs.add(cbFilterLandsByColorId, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "When using card color filters, filter lands in a way to make it easier to find relevant mana producing lands."),
        regularConstraints);

    // Advanced
    pnlPrefs.add(new SectionLabel("Advanced Settings"), sectionConstraints);

    pnlPrefs.add(cbDevMode, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Enables menu with functions for testing during development."),
        regularConstraints);

    pnlPrefs.add(cbWorkshopSyntax, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "Enables syntax checking of card scripts in the Workshop. Note: functionality still in testing phase!"),
        regularConstraints);

    pnlPrefs.add(cbpGameLogEntryType, "w 80%!, gap 10% 0 0 10px, span 2 1");
    pnlPrefs.add(
        new NoteLabel(
            "Changes how much information is displayed in the game log. Sorted by least to most verbose."),
        regularConstraints);

    pnlPrefs.add(cbpCloseAction, "w 80%!, gap 10% 0 0 10px, span 2 1");
    pnlPrefs.add(
        new NoteLabel("Changes what happens when clicking the X button in the upper right."),
        regularConstraints);

    // Graphic Options
    pnlPrefs.add(new SectionLabel("Graphic Options"), sectionConstraints + ", gaptop 2%");

    pnlPrefs.add(cbImageFetcher, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Enables live fetching of missing card images from an online resource."),
        regularConstraints);

    pnlPrefs.add(cbDisplayFoil, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Displays foil cards with the visual foil overlay effect."),
        regularConstraints);

    pnlPrefs.add(cbRandomFoil, regularConstraints);
    pnlPrefs.add(new NoteLabel("Adds foil effect to random cards."), regularConstraints);

    pnlPrefs.add(cbScaleLarger, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Allows card pictures to be expanded larger than their original size."),
        regularConstraints);

    pnlPrefs.add(cbLargeCardViewers, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "Makes all card viewers much larger for use with high resolution images. Will not fit on smaller screens."),
        regularConstraints);

    pnlPrefs.add(cbRandomArtInPools, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Generates cards with random art in generated limited mode card pools."),
        regularConstraints);

    pnlPrefs.add(cbUiForTouchScreen, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "Increases some UI elements to provide a better experience on touchscreen devices. (Needs restart)"),
        regularConstraints);

    pnlPrefs.add(cbCompactPrompt, regularConstraints);
    pnlPrefs.add(
        new NoteLabel("Hide header and use smaller font in Prompt pane to make it more compact."),
        regularConstraints);

    /*pnlPrefs.add(cbStackCardView, regularConstraints); TODO: Show this checkbox when setting can support being enabled
    pnlPrefs.add(new NoteLabel("Show cards and abilities on Stack in card view rather than list view."), regularConstraints);*/

    pnlPrefs.add(cbHideReminderText, regularConstraints);
    pnlPrefs.add(new NoteLabel("Hide reminder text in Card Detail pane."), regularConstraints);

    pnlPrefs.add(cbOpenPacksIndiv, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "When opening Fat Packs and Booster Boxes, booster packs will be opened and displayed one at a time."),
        regularConstraints);

    pnlPrefs.add(cbTokensInSeparateRow, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "Displays tokens in a separate row on the battlefield below the non-token creatures."),
        regularConstraints);

    pnlPrefs.add(cbStackCreatures, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "Stacks identical creatures on the battlefield like lands, artifacts, and enchantments."),
        regularConstraints);

    pnlPrefs.add(cbpDisplayCurrentCardColors, "w 80%!, gap 10% 0 0 10px, span 2 1");
    pnlPrefs.add(
        new NoteLabel(
            "Displays the breakdown of the current color of cards in the card detail information panel."),
        regularConstraints);

    // Sound options
    pnlPrefs.add(new SectionLabel("Sound Options"), sectionConstraints + ", gaptop 2%");

    pnlPrefs.add(cbEnableSounds, regularConstraints);
    pnlPrefs.add(new NoteLabel("Enable sound effects during the game."), regularConstraints);

    pnlPrefs.add(cbEnableMusic, regularConstraints);
    pnlPrefs.add(new NoteLabel("Enable background music during the game."), regularConstraints);

    pnlPrefs.add(cbAltSoundSystem, regularConstraints);
    pnlPrefs.add(
        new NoteLabel(
            "Use the alternate sound system (only use if you have issues with sound not playing or disappearing)."),
        regularConstraints);

    // Keyboard shortcuts
    final JLabel lblShortcuts = new SectionLabel("Keyboard Shortcuts");
    pnlPrefs.add(lblShortcuts, sectionConstraints + ", gaptop 2%");

    final List<Shortcut> shortcuts = KeyboardShortcuts.getKeyboardShortcuts();

    for (final Shortcut s : shortcuts) {
      pnlPrefs.add(
          new FLabel.Builder().text(s.getDescription()).fontAlign(SwingConstants.RIGHT).build(),
          "w 50%!, h 22px!, gap 0 2% 0 1%");
      KeyboardShortcutField field = new KeyboardShortcutField(s);
      pnlPrefs.add(field, "w 25%!");
      shortcutFields.put(s.getPrefKey(), field);
    }
  }