001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */ 003/* Open Source Software - may be modified and shared by FRC teams. The code */ 004/* must be accompanied by the FIRST BSD license file in the root directory of */ 005/* the project. */ 006/*----------------------------------------------------------------------------*/ 007 008package edu.wpi.first.wpilibj.smartdashboard; 009 010import java.util.LinkedHashMap; 011 012import edu.wpi.first.networktables.NetworkTableEntry; 013import edu.wpi.first.wpilibj.Sendable; 014import edu.wpi.first.wpilibj.SendableBase; 015import edu.wpi.first.wpilibj.command.Command; 016 017import static java.util.Objects.requireNonNull; 018 019/** 020 * The {@link SendableChooser} class is a useful tool for presenting a selection of options to the 021 * {@link SmartDashboard}. 022 * 023 * <p>For instance, you may wish to be able to select between multiple autonomous modes. You can do 024 * this by putting every possible {@link Command} you want to run as an autonomous into a {@link 025 * SendableChooser} and then put it into the {@link SmartDashboard} to have a list of options appear 026 * on the laptop. Once autonomous starts, simply ask the {@link SendableChooser} what the selected 027 * value is. 028 * 029 * @param <V> The type of the values to be stored 030 */ 031public class SendableChooser<V> extends SendableBase implements Sendable { 032 /** 033 * The key for the default value. 034 */ 035 private static final String DEFAULT = "default"; 036 /** 037 * The key for the selected option. 038 */ 039 private static final String SELECTED = "selected"; 040 /** 041 * The key for the option array. 042 */ 043 private static final String OPTIONS = "options"; 044 /** 045 * A map linking strings to the objects the represent. 046 */ 047 private final LinkedHashMap<String, V> m_map = new LinkedHashMap<>(); 048 private String m_defaultChoice = ""; 049 050 /** 051 * Instantiates a {@link SendableChooser}. 052 */ 053 public SendableChooser() { 054 } 055 056 /** 057 * Adds the given object to the list of options. On the {@link SmartDashboard} on the desktop, the 058 * object will appear as the given name. 059 * 060 * @param name the name of the option 061 * @param object the option 062 */ 063 public void addObject(String name, V object) { 064 m_map.put(name, object); 065 } 066 067 /** 068 * Add the given object to the list of options and marks it as the default. Functionally, this is 069 * very close to {@link #addObject(String, Object)} except that it will use this as the default 070 * option if none other is explicitly selected. 071 * 072 * @param name the name of the option 073 * @param object the option 074 */ 075 public void addDefault(String name, V object) { 076 requireNonNull(name, "Provided name was null"); 077 078 m_defaultChoice = name; 079 addObject(name, object); 080 } 081 082 /** 083 * Returns the selected option. If there is none selected, it will return the default. If there is 084 * none selected and no default, then it will return {@code null}. 085 * 086 * @return the option selected 087 */ 088 public V getSelected() { 089 String selected = m_defaultChoice; 090 if (m_tableSelected != null) { 091 selected = m_tableSelected.getString(m_defaultChoice); 092 } 093 return m_map.get(selected); 094 } 095 096 private NetworkTableEntry m_tableSelected; 097 098 @Override 099 public void initSendable(SendableBuilder builder) { 100 builder.setSmartDashboardType("String Chooser"); 101 builder.addStringProperty(DEFAULT, () -> { 102 return m_defaultChoice; 103 }, null); 104 builder.addStringArrayProperty(OPTIONS, () -> { 105 return m_map.keySet().toArray(new String[0]); 106 }, null); 107 m_tableSelected = builder.getEntry(SELECTED); 108 } 109}