Add constants for built-in Shuffleboard widgets and layouts (#1468)

Prevents users from having to remember (and correctly type) the names of Shuffleboard widgets.
This commit is contained in:
Sam Carlberg
2018-12-29 20:22:47 -05:00
committed by Peter Johnson
parent ceed1d74dc
commit 01d1322066
24 changed files with 1278 additions and 52 deletions

View File

@@ -0,0 +1,62 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.shuffleboard;
/**
* The types of layouts bundled with Shuffleboard.
*
* <pre>{@code
* ShuffleboardLayout myList = Shuffleboard.getTab("My Tab")
* .getLayout(BuiltinLayouts.kList, "My List");
* }</pre>
*/
public enum BuiltInLayouts implements LayoutType {
/**
* Groups components in a vertical list. New widgets added to the layout will be placed at the
* bottom of the list.
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Label position</td><td>String</td><td>"BOTTOM"</td>
* <td>The position of component labels inside the grid. One of
* {@code ["TOP", "LEFT", "BOTTOM", "RIGHT", "HIDDEN"}</td></tr>
* </table>
*/
kList("List Layout"),
/**
* Groups components in an <i>n</i> x <i>m</i> grid. Grid layouts default to 3x3.
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Number of columns</td><td>Number</td><td>3</td><td>Must be in the range [1,15]</td>
* </tr>
* <tr><td>Number of rows</td><td>Number</td><td>3</td><td>Must be in the range [1,15]</td></tr>
* <tr>
* <td>Label position</td>
* <td>String</td>
* <td>"BOTTOM"</td>
* <td>The position of component labels inside the grid.
* One of {@code ["TOP", "LEFT", "BOTTOM", "RIGHT", "HIDDEN"}</td>
* </tr>
* </table>
*/
kGrid("Grid Layout"),
;
private final String m_layoutName;
BuiltInLayouts(String layoutName) {
m_layoutName = layoutName;
}
@Override
public String getLayoutName() {
return m_layoutName;
}
}

View File

@@ -0,0 +1,399 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.shuffleboard;
import edu.wpi.first.wpilibj.interfaces.Accelerometer.Range;
/**
* The types of the widgets bundled with Shuffleboard.
*
* <p>For example, setting a number to be displayed with a slider:
* <pre>{@code
* NetworkTableEntry example = Shuffleboard.getTab("My Tab")
* .add("My Number", 0)
* .withWidget(BuiltInWidgets.kNumberSlider)
* .withProperties(Map.of("min", 0, "max", 1))
* .getEntry();
* }</pre>
*
* <p>Each value in this enum goes into detail on what data types that widget can support, as well
* as the custom properties that widget uses.
*/
public enum BuiltInWidgets implements WidgetType {
/**
* Displays a value with a simple text field.
* <br>Supported types:
* <ul>
* <li>String</li>
* <li>Number</li>
* <li>Boolean</li>
* </ul>
* <br>This widget has no custom properties.
*/
kTextView("Text View"),
/**
* Displays a number with a controllable slider.
* <br>Supported types:
* <ul>
* <li>Number</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Min</td><td>Number</td><td>-1.0</td><td>The minimum value of the slider</td></tr>
* <tr><td>Max</td><td>Number</td><td>1.0</td><td>The maximum value of the slider</td></tr>
* <tr><td>Block increment</td><td>Number</td><td>0.0625</td>
* <td>How much to move the slider by with the arrow keys</td></tr>
* </table>
*/
kNumberSlider("Number Slider"),
/**
* Displays a number with a view-only bar.
* <br>Supported types:
* <ul>
* <li>Number</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Min</td><td>Number</td><td>-1.0</td><td>The minimum value of the bar</td></tr>
* <tr><td>Max</td><td>Number</td><td>1.0</td><td>The maximum value of the bar</td></tr>
* <tr><td>Center</td><td>Number</td><td>0</td><td>The center ("zero") value of the bar</td></tr>
* </table>
*/
kNumberBar("Number Bar"),
/**
* Displays a number with a view-only dial. Displayed values are rounded to the nearest integer.
* <br>Supported types:
* <ul>
* <li>Number</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Min</td><td>Number</td><td>0</td><td>The minimum value of the dial</td></tr>
* <tr><td>Max</td><td>Number</td><td>100</td><td>The maximum value of the dial</td></tr>
* <tr><td>Show value</td><td>Boolean</td><td>true</td>
* <td>Whether or not to show the value as text</td></tr>
* </table>
*/
kDial("Simple Dial"),
/**
* Displays a number with a graph. <strong>NOTE:</strong> graphs can be taxing on the computer
* running the dashboard. Keep the number of visible data points to a minimum. Making the widget
* smaller also helps with performance, but may cause the graph to become difficult to read.
* <br>Supported types:
* <ul>
* <li>Number</li>
* <li>Number array</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Visible time</td><td>Number</td><td>30</td>
* <td>How long, in seconds, should past data be visible for</td></tr>
* </table>
*/
kGraph("Graph"),
/**
* Displays a boolean value as a large colored box.
* <br>Supported types:
* <ul>
* <li>Boolean</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Color when true</td><td>Color</td><td>"green"</td>
* <td>Can be specified as a string ({@code "#00FF00"}) or a rgba integer ({@code 0x00FF0000})
* </td></tr>
* <tr><td>Color when false</td><td>Color</td><td>"red"</td>
* <td>Can be specified as a string or a number</td></tr>
* </table>
*/
kBooleanBox("Boolean Box"),
/**
* Displays a boolean with a large interactive toggle button.
* <br>Supported types:
* <ul>
* <li>Boolean</li>
* </ul>
* <br>This widget has no custom properties.
*/
kToggleButton("Toggle Button"),
/**
* Displays a boolean with a fixed-size toggle switch.
* <br>Supported types:
* <ul>
* <li>Boolean</li>
* </ul>
* <br>This widget has no custom properties.
*/
kToggleSwitch("Toggle Switch"),
/**
* Displays an analog input or a raw number with a number bar.
* <br>Supported types:
* <ul>
* <li>Number</li>
* <li>{@link edu.wpi.first.wpilibj.AnalogInput}</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Min</td><td>Number</td><td>0</td><td>The minimum value of the bar</td></tr>
* <tr><td>Max</td><td>Number</td><td>5</td><td>The maximum value of the bar</td></tr>
* <tr><td>Center</td><td>Number</td><td>0</td><td>The center ("zero") value of the bar</td></tr>
* <tr><td>Orientation</td><td>String</td><td>"HORIZONTAL"</td>
* <td>The orientation of the bar. One of {@code ["HORIZONTAL", "VERTICAL"]}</td></tr>
* <tr><td>Number of tick marks</td><td>Number</td><td>5</td>
* <td>The number of discrete ticks on the bar</td></tr>
* </table>
*/
kVoltageView("Voltage View"),
/**
* Displays a {@link edu.wpi.first.wpilibj.PowerDistributionPanel PowerDistributionPanel}.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.PowerDistributionPanel}</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Show voltage and current values</td><td>Boolean</td><td>true</td>
* <td>Whether or not to display the voltage and current draw</td></tr>
* </table>
*/
kPowerDistributionPanel("PDP"),
/**
* Displays a {@link edu.wpi.first.wpilibj.smartdashboard.SendableChooser SendableChooser} with
* a dropdown combo box with a list of options.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.smartdashboard.SendableChooser}</li>
* </ul>
* <br>This widget has no custom properties.
*/
kComboBoxChooser("ComboBox Chooser"),
/**
* Displays a {@link edu.wpi.first.wpilibj.smartdashboard.SendableChooser SendableChooser} with
* a toggle button for each available option.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.smartdashboard.SendableChooser}</li>
* </ul>
* <br>This widget has no custom properties.
*/
kSplitButtonChooser("Split Button Chooser"),
/**
* Displays an {@link edu.wpi.first.wpilibj.Encoder} displaying its speed, total travelled
* distance, and its distance per tick.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.Encoder}</li>
* </ul>
* <br>This widget has no custom properties.
*/
kEncoder("Encoder"),
/**
* Displays a {@link edu.wpi.first.wpilibj.SpeedController SpeedController}. The speed controller
* will be controllable from the dashboard when test mode is enabled, but will otherwise be
* view-only.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.PWMSpeedController}</li>
* <li>{@link edu.wpi.first.wpilibj.DMC60}</li>
* <li>{@link edu.wpi.first.wpilibj.Jaguar}</li>
* <li>{@link edu.wpi.first.wpilibj.PWMTalonSRX}</li>
* <li>{@link edu.wpi.first.wpilibj.PWMVictorSPX}</li>
* <li>{@link edu.wpi.first.wpilibj.SD540}</li>
* <li>{@link edu.wpi.first.wpilibj.Spark}</li>
* <li>{@link edu.wpi.first.wpilibj.Talon}</li>
* <li>{@link edu.wpi.first.wpilibj.Victor}</li>
* <li>{@link edu.wpi.first.wpilibj.VictorSP}</li>
* <li>{@link edu.wpi.first.wpilibj.SpeedControllerGroup}</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Orientation</td><td>String</td><td>"HORIZONTAL"</td>
* <td>One of {@code ["HORIZONTAL", "VERTICAL"]}</td></tr>
* </table>
*/
kSpeedController("Speed Controller"),
/**
* Displays a command with a toggle button. Pressing the button will start the command, and the
* button will automatically release when the command completes.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.command.Command}</li>
* <li>{@link edu.wpi.first.wpilibj.command.CommandGroup}</li>
* <li>Any custom subclass of {@code Command} or {@code CommandGroup}</li>
* </ul>
* <br>This widget has no custom properties.
*/
kCommand("Command"),
/**
* Displays a PID command with a checkbox and an editor for the PIDF constants. Selecting the
* checkbox will start the command, and the checkbox will automatically deselect when the command
* completes.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.command.PIDCommand}</li>
* <li>Any custom subclass of {@code PIDCommand}</li>
* </ul>
* <br>This widget has no custom properties.
*/
kPIDCommand("PID Command"),
/**
* Displays a PID controller with an editor for the PIDF constants and a toggle switch for
* enabling and disabling the controller.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.PIDController}</li>
* </ul>
* <br>This widget has no custom properties.
*/
kPIDController("PID Controller"),
/**
* Displays an accelerometer with a number bar displaying the magnitude of the acceleration and
* text displaying the exact value.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.AnalogAccelerometer}</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Min</td><td>Number</td><td>-1</td>
* <td>The minimum acceleration value to display</td></tr>
* <tr><td>Max</td><td>Number</td><td>1</td>
* <td>The maximum acceleration value to display</td></tr>
* <tr><td>Show text</td><td>Boolean</td><td>true</td>
* <td>Show or hide the acceleration values</td></tr>
* <tr><td>Precision</td><td>Number</td><td>2</td>
* <td>How many numbers to display after the decimal point</td></tr>
* <tr><td>Show tick marks</td><td>Boolean</td><td>false</td>
* <td>Show or hide the tick marks on the number bars</td></tr>
* </table>
*/
kAccelerometer("Accelerometer"),
/**
* Displays a 3-axis accelerometer with a number bar for each axis' accleration.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.ADXL345_I2C}</li>
* <li>{@link edu.wpi.first.wpilibj.ADXL345_SPI}</li>
* <li>{@link edu.wpi.first.wpilibj.ADXL362}</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Range</td><td>{@link Range}</td><td>k16G</td><td>The accelerometer range</td></tr>
* <tr><td>Show value</td><td>Boolean</td><td>true</td>
* <td>Show or hide the acceleration values</td></tr>
* <tr><td>Precision</td><td>Number</td><td>2</td>
* <td>How many numbers to display after the decimal point</td></tr>
* <tr><td>Show tick marks</td><td>Boolean</td><td>false</td>
* <td>Show or hide the tick marks on the number bars</td></tr>
* </table>
*/
k3AxisAccelerometer("3-Axis Accelerometer"),
/**
* Displays a gyro with a dial from 0 to 360 degrees.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.ADXRS450_Gyro}</li>
* <li>{@link edu.wpi.first.wpilibj.AnalogGyro}</li>
* <li>Any custom subclass of {@code GyroBase} (such as a MXP gyro)</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Major tick spacing</td><td>Number</td><td>45</td><td>Degrees</td></tr>
* <tr><td>Starting angle</td><td>Number</td><td>180</td>
* <td>How far to rotate the entire dial, in degrees</td></tr>
* <tr><td>Show tick mark ring</td><td>Boolean</td><td>true</td></tr>
* </table>
*/
kGyro("Gyro"),
/**
* Displays a relay with toggle buttons for each supported mode (off, on, forward, reverse).
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.Relay}</li>
* </ul>
* <br>This widget has no custom properties.
*/
kRelay("Relay"),
/**
* Displays a differential drive with a widget that displays the speed of each side of the
* drivebase and a vector for the direction and rotation of the drivebase. The widget will be
* controllable if the robot is in test mode.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.drive.DifferentialDrive}</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Number of wheels</td><td>Number</td><td>4</td><td>Must be a positive even integer
* </td></tr>
* <tr><td>Wheel diameter</td><td>Number</td><td>80</td><td>Pixels</td></tr>
* <tr><td>Show velocity vectors</td><td>Boolean</td><td>true</td></tr>
* </table>
*/
kDifferentialDrive("Differential Drivebase"),
/**
* Displays a mecanum drive with a widget that displays the speed of each wheel, and vectors for
* the direction and rotation of the drivebase. The widget will be controllable if the robot is
* in test mode.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.first.wpilibj.drive.MecanumDrive}</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Show velocity vectors</td><td>Boolean</td><td>true</td></tr>
* </table>
*/
kMecanumDrive("Mecanum Drivebase"),
/**
* Displays a camera stream.
* <br>Supported types:
* <ul>
* <li>{@link edu.wpi.cscore.VideoSource} (as long as it is streaming on an MJPEG server)</li>
* </ul>
* <br>Custom properties:
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Show crosshair</td><td>Boolean</td><td>true</td>
* <td>Show or hide a crosshair on the image</td></tr>
* <tr><td>Crosshair color</td><td>Color</td><td>"white"</td>
* <td>Can be a string or a rgba integer</td></tr>
* <tr><td>Show controls</td><td>Boolean</td><td>true</td><td>Show or hide the stream controls
* </td></tr>
* <tr><td>Rotation</td><td>String</td><td>"NONE"</td>
* <td>Rotates the displayed image. One of {@code ["NONE", "QUARTER_CW", "QUARTER_CCW", "HALF"]}
* </td></tr>
* </table>
*/
kCameraStream("Camera Stream"),
;
private final String m_widgetName;
BuiltInWidgets(String widgetName) {
this.m_widgetName = widgetName;
}
@Override
public String getWidgetName() {
return m_widgetName;
}
}

View File

@@ -12,6 +12,7 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
@@ -35,7 +36,7 @@ final class ContainerHelper {
return m_components;
}
ShuffleboardLayout getLayout(String type, String title) {
ShuffleboardLayout getLayout(String title, String type) {
if (!m_layouts.containsKey(title)) {
ShuffleboardLayout layout = new ShuffleboardLayout(m_container, type, title);
m_components.add(layout);
@@ -44,6 +45,14 @@ final class ContainerHelper {
return m_layouts.get(title);
}
ShuffleboardLayout getLayout(String title) {
ShuffleboardLayout layout = m_layouts.get(title);
if (layout == null) {
throw new NoSuchElementException("No layout has been defined with the title '" + title + "'");
}
return layout;
}
ComplexWidget add(String title, Sendable sendable) {
checkTitle(title);
ComplexWidget widget = new ComplexWidget(m_container, title, sendable);

View File

@@ -0,0 +1,21 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.shuffleboard;
/**
* Represents the type of a layout in Shuffleboard. Using this is preferred over specifying raw
* strings, to avoid typos and having to know or look up the exact string name for a desired layout.
*
* @see BuiltInWidgets the built-in widget types
*/
public interface LayoutType {
/**
* Gets the string type of the layout as defined by that layout in Shuffleboard.
*/
String getLayoutName();
}

View File

@@ -8,6 +8,7 @@
package edu.wpi.first.wpilibj.shuffleboard;
import java.util.List;
import java.util.NoSuchElementException;
import edu.wpi.first.wpilibj.Sendable;
@@ -21,15 +22,48 @@ public interface ShuffleboardContainer extends ShuffleboardValue {
*/
List<ShuffleboardComponent<?>> getComponents();
/**
* Gets the layout with the given type and title, creating it if it does not already exist at the
* time this method is called. Note: this method should only be used to use a layout type that
* is not already built into Shuffleboard. To use a layout built into Shuffleboard, use
* {@link #getLayout(String, LayoutType)} and the layouts in {@link BuiltInLayouts}.
*
* @param title the title of the layout
* @param type the type of the layout, eg "List Layout" or "Grid Layout"
* @return the layout
* @see #getLayout(String, LayoutType)
*/
ShuffleboardLayout getLayout(String title, String type);
/**
* Gets the layout with the given type and title, creating it if it does not already exist at the
* time this method is called.
*
* @param type the type of the layout, eg "List" or "Grid"
* @param title the title of the layout
* @param title the title of the layout
* @param layoutType the type of the layout, eg "List" or "Grid"
* @return the layout
*/
ShuffleboardLayout getLayout(String type, String title);
default ShuffleboardLayout getLayout(String title, LayoutType layoutType) {
return getLayout(title, layoutType.getLayoutName());
}
/**
* Gets the already-defined layout in this container with the given title.
*
* <pre>{@code
* Shuffleboard.getTab("Example Tab")
* .getLayout("My Layout", BuiltInLayouts.kList);
*
* // Later...
* Shuffleboard.getTab("Example Tab")
* .getLayout("My Layout");
* }</pre>
*
* @param title the title of the layout to get
* @return the layout with the given title
* @throws NoSuchElementException if no layout has yet been defined with the given title
*/
ShuffleboardLayout getLayout(String title) throws NoSuchElementException;
/**
* Adds a widget to this container to display the given sendable.
@@ -69,7 +103,7 @@ public interface ShuffleboardContainer extends ShuffleboardValue {
* {@link #add(String, Object)}, the value in the widget will be saved on the robot and will be
* used when the robot program next starts rather than {@code defaultValue}.
*
* @param title the title of the widget
* @param title the title of the widget
* @param defaultValue the default value of the widget
* @return a widget to display the sendable data
* @throws IllegalArgumentException if a widget already exists in this container with the given

View File

@@ -8,6 +8,7 @@
package edu.wpi.first.wpilibj.shuffleboard;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import edu.wpi.first.networktables.NetworkTable;
@@ -30,8 +31,13 @@ public class ShuffleboardLayout extends ShuffleboardComponent<ShuffleboardLayout
}
@Override
public ShuffleboardLayout getLayout(String type, String title) {
return m_helper.getLayout(type, title);
public ShuffleboardLayout getLayout(String title, String type) {
return m_helper.getLayout(title, type);
}
@Override
public ShuffleboardLayout getLayout(String title) throws NoSuchElementException {
return m_helper.getLayout(title);
}
@Override

View File

@@ -8,6 +8,7 @@
package edu.wpi.first.wpilibj.shuffleboard;
import java.util.List;
import java.util.NoSuchElementException;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.wpilibj.Sendable;
@@ -43,8 +44,13 @@ public final class ShuffleboardTab implements ShuffleboardContainer {
}
@Override
public ShuffleboardLayout getLayout(String type, String title) {
return m_helper.getLayout(type, title);
public ShuffleboardLayout getLayout(String title, String type) {
return m_helper.getLayout(title, type);
}
@Override
public ShuffleboardLayout getLayout(String title) throws NoSuchElementException {
return m_helper.getLayout(title);
}
@Override

View File

@@ -27,6 +27,20 @@ abstract class ShuffleboardWidget<W extends ShuffleboardWidget<W>>
*
* @param widgetType the type of the widget used to display the data
* @return this widget object
* @see BuiltInWidgets
*/
public final W withWidget(WidgetType widgetType) {
return withWidget(widgetType.getWidgetName());
}
/**
* Sets the type of widget used to display the data. If not set, the default widget type will be
* used. This method should only be used to use a widget that does not come built into
* Shuffleboard (i.e. one that comes with a custom or thrid-party plugin). To use a widget that
* is built into Shuffleboard, use {@link #withWidget(WidgetType)} and {@link BuiltInWidgets}.
*
* @param widgetType the type of the widget used to display the data
* @return this widget object
*/
public final W withWidget(String widgetType) {
setType(widgetType);

View File

@@ -0,0 +1,21 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.shuffleboard;
/**
* Represents the type of a widget in Shuffleboard. Using this is preferred over specifying raw
* strings, to avoid typos and having to know or look up the exact string name for a desired widget.
*
* @see BuiltInWidgets the built-in widget types
*/
public interface WidgetType {
/**
* Gets the string type of the widget as defined by that widget in Shuffleboard.
*/
String getWidgetName();
}