Class SsDbComboBox2<K,D,D2>

Type Parameters:
K - list item key type
D - list item displayValue type
D2 - list item optional extra data field type
All Implemented Interfaces:
RSC, SsComponent, ActionListener, ImageObserver, ItemSelectable, MenuContainer, Serializable, EventListener, Accessible, ListDataListener

public class SsDbComboBox2<K,D,D2> extends SsComboBox2<K,D,D2>
Similar to the SsComboBox2, but used when both <K>, the 'bound' value, and <D>, the 'display' value, are pulled from a database table. <K> is the 'key' and the display value the 'text' which appears in the combo box.

This is sometimes used as a Navigator in conjunction with SyncManager. Generally the key represents a foreign key to another table, and the combobox displays the <D>.

Optional data for combobox's item, <D2>, may be specified, see setD2ColumnName(String). This data may be displayed by the ListItem, see SsComboBox2.setD2DisplayEnabled(boolean) and SsComboBox2.getListItemFormat()

Refer to SsComboBox2 for warnings and caveats.

Builders and generic type parameter capture

The ComboBox hierarchy depends on generic parameter type capture. It is used so that the data read from a database column is converted to the concrete type specified by the parameter type.

When you have a SsDbComboBox2 with param types that you frequently use, it is convenient to incorporate it into a re-usable class. Here's a simple example where you lock in the types, don't add anything else, MyDbComboBox.Builder just works.

static class MyDbComboBox extends SsDbComboBox2<Integer, String, Byte> {
  public static class Builder
      extends SsDbComboBox2.AbstractBuilder<Integer, String, Byte, Builder> {
    @Override
    protected Builder self() {
      return this;
    }
    @Override
    public MyDbComboBox build() {
      return new MyDbComboBox(this);
    }
  }
  private MyDbComboBox(Builder builder) {
    super(builder);
  }
}

MyDbComboBox dbCombo = new MyDbComboBox
                           .Builder() // NOTE: "{ }" not needed
                           .primaryKeyColumnName("keyCol")
                           .displayColumnName("dispCol")
                           .build();
// System.out.println(""+dbCombo.getD2Type()); // output: class java.lang.Byte

This next example, DbComboBox2Extra, does a lot.

  1. lock in <K> and <D> types
  2. leaves <D2> for programmer
  3. adds new generic <D3> for programmer
  4. captures the type of <D3>
  5. has an AbstractBuilder so the class and Builder are extendable
  6. has a concrete Builder to instantiate the class
static class DbComboBox2Extra<D2, D3> extends SsDbComboBox2<Integer, String, D2> {
  private final D3 d3Value; // Note: not part of combo list item.
  private final TypeToken<D3> d3TypeToken;

  public abstract static class AbstractBuilder<D2, D3, T extends AbstractBuilder<D2, D3, T>>
      extends SsDbComboBox2.AbstractBuilder<Integer, String, D2, T> {
    private D3 d3Value;
    // captures D3 for whatever runtime class extends this Abstractbuilder
    private final TypeToken<D3> d3TypeToken = new TypeToken<D3>(getClass()) {};

    public AbstractBuilder() {
      // check if TypeToken is generic; verifyTypeClass throws useful msg
      verifyTypeClass(d3TypeToken, getClass());
    }

    public T d3Data(D3 val) {
      d3Value = val;
      return self();
    }
  }

  // Regular Builder for direct instantiation
  public static class Builder<D2, D3> extends AbstractBuilder<D2, D3, Builder<D2, D3>> {
    // self type idiom
    @Override
    protected Builder<D2, D3> self() {
      return this;
    }

    @Override
    public DbComboBox2Extra<D2, D3> build() {
      return new DbComboBox2Extra<>(this);
    }
  }

  protected DbComboBox2Extra(AbstractBuilder<D2, D3, ?> builder) {
    super(builder);
    d3Value = builder.d3Value;
    d3TypeToken = builder.d3TypeToken;
  }

  public D3 getD3() {
    return d3Value;
  }
  public TypeToken<D3> getD3TypeToken() {
    return d3TypeToken;
  }
}
And a usage example
DbComboBox2Extra<Double, List<Double>> cbExtra = new DbComboBox2Extra
                                                     .Builder<Double, List<Double>>() {}
                                                     // <- "{ }" NEEDED
                                                     .primaryKeyColumnName("aaa")
                                                     .displayColumnName("bbb")
                                                     .d3Data(new ArrayList<>())
                                                     .build();
cbExtra.getD3().addAll(List.of(7D, 6D, 5D));
System.out.println("" + cbExtra.getKeyType());
System.out.println("" + cbExtra.getDisplayValueType());
System.out.println("" + cbExtra.getD2Type());
System.out.println("" + cbExtra.getD3TypeToken());
System.out.println("" + cbExtra.getD3());
With output
    class java.lang.Integer
    class java.lang.String
    class java.lang.Double
    java.util.List<java.lang.Double>
    [7.0, 6.0, 5.0]

Example with two tables

  1. part_data (part_id, part_name, ...)
  2. shipment_data (shipment_id, part_id, quantity, ...)

Assume you would like to develop a screen for the shipment_data table including a combobox where the user can choose a part and a textbox where the user can specify a quantity.

In the combobox you would want to display the part name rather than part_id so that it is easier for the user to choose. At the same time you want to store the id of the part chosen by the user in the shipment table.

/**
 * Create NavigateActions for shipment_data and ComboBox to select part_id.
 * The ComboBox displays part_name and provides part_id.
 * Add the comboBox to this JFrame.
 * @param connection used by SSDBComboBox
 * @param rowSet to connect to shipment_data
 */
void init(Connection connection, JdbcRowSet rowSet) {
  try {
    // Table to examine and traverse.
    rowSet.setCommand("SELECT * FROM shipment_data;");
    rowSet.execute();

    // 2nd arg is DbOps, if null use default.
    rowsModel = RowsModel.create(rowSet, null);

    // Query for the combobox to map part_id to part_name.
    String query = "SELECT * FROM part_data;";

    // Create an instance of the SsDbComboBox2 with the connection object,
    // query, and column names.
    combo = new SsDbComboBox2
                .Builder<Long, String, Long>() {} // <- "{ }" NEEDED
                .connection(connection)
                .query(query)
                .primaryKeyColumnName("part_id")
                .displayColumnName("part_name")
                .build();

    // Execute the query.
    combo.execute();

    // Specifies the column bound to the combo.
    rowsModel.bind(combo, "part_id");

  } catch (Exception ex) {
    // Exception handler here...
  }

  // Add the ssdbcombobox to the JFrame.
  getContentPane().add(combo);
}
See Also:
  • Field Details

  • Constructor Details

  • Method Details

    • execute

      public void execute() throws Exception
      Executes the query specified with setQuery(), populates combobox, and turns on AutoCompleteSupport.
      Throws:
      Exception - may occur querying data or turning on AutoComplete
    • isComboBoxNavigator

      protected boolean isComboBoxNavigator()
      A combobox used as a navigator has some restriction; for example, it can not have nullItem. Override this as needed.
      Overrides:
      isComboBoxNavigator in class SsComboBox2<K,D,D2>
      Returns:
      true if this ComboBox is a navigator
    • getPrimaryKeyColumnName

      Retrieves the database column (normally a primary key) from which to query the keys for the bound column.
      Returns:
      name of the PK value to query for the bound column keys
    • getDateFormat

      Returns the pattern in which dates are displayed.
      Returns:
    • setDateFormat

      public void setDateFormat(String dateFormat)
      When a display column is of type date you can choose the format in which it has to be displayed. For the pattern refer SimpleDateFormat in java.text package.
      Parameters:
      dateFormat - pattern in which dates have to be displayed
    • getDisplayColumnName

      Returns the column name whose values are displayed in the combo box.
      Returns:
      returns the name of the column used to get values for combo box items.
    • getD2ColumnName

      Returns the rowSet column name used to populate the <D2> field of the combobox list item.
      Returns:
      returns the column name <D2> values
    • setD2ColumnName

      public void setD2ColumnName(String d2ColumnName)
      Sets the column name . If there's extra data to store in the combobox list item then use this.
      Parameters:
      d2ColumnName - column name whose values populate <D2>.
    • getSelectedStringValue

      Returns the text displayed in the combobox.
      Returns:
      value corresponding to the selected item in the combo. return null if no item is selected.
    • hasD2

      public final boolean hasD2()
      Description copied from class: SsComboBox2
      This returns whether or not <D2> is populated.
      Overrides:
      hasD2 in class SsComboBox2<K,D,D2>
      Returns:
    • setChosenDisplayValue

      public void setChosenDisplayValue(D displayValue)
      Finds the listItem having displayValue that matches the specified displayValue and make it the selected listItem. If no matching item is found the displayValue is used for setSelectedItem(displayValue).
      Overrides:
      setChosenDisplayValue in class SsComboBox2<K,D,D2>
      Parameters:
      displayValue - element of list item
      Throws:
      IllegalStateException - if d2 enabled
    • getQuery

      public String getQuery()
      Returns the query used to retrieve values from database for the combo box.
      Returns:
      returns the query used.
    • setQuery

      public void setQuery(String query)
      Sets the query used to display items in the combo box.
      Parameters:
      query - query to be used to get values from database (to display combo box items)
    • updateDisplayValue

      public boolean updateDisplayValue(K key, D displayValue)
      Update displayValue of an item in the combobox's item list for given key.

      If more than one item is present in the combo for that key, only the first one is changed.

      Overrides:
      updateDisplayValue in class SsComboBox2<K,D,D2>
      Parameters:
      key - typically a primary key value corresponding to the chosenDisplayValue to be updated
      displayValue - chosenDisplayValue that should be updated in the combobox
      Returns:
      returns true if update is successful otherwise returns false.
    • setDisplayValues

      public void setDisplayValues(List<D> displayValues, List<K> keys)
      Unconditionally throws UnsupportedOperationException.
      Overrides:
      setDisplayValues in class SsComboBox2<K,D,D2>
      Parameters:
      displayValues -
      keys -
    • setDisplayValues

      public void setDisplayValues(List<D> displayValues)
      Unconditionally throws UnsupportedOperationException.
      Overrides:
      setDisplayValues in class SsComboBox2<K,D,D2>
      Parameters:
      displayValues -
    • setDisplayValues

      public <T extends Enum<T>> void setDisplayValues(Class<T> enumDisplayValues)
      Unconditionally throws UnsupportedOperationException.
      Overrides:
      setDisplayValues in class SsComboBox2<K,D,D2>
      Type Parameters:
      T -
      Parameters:
      enumDisplayValues -
    • setBoundColumnName

      @Deprecated public void setBoundColumnName(String boundColumnName)
      Deprecated.
      Use bind()
      After this, make some adjustments. Sets the database column name bound to the Swingset component Deprecated in SSComponentInterface.
      Parameters:
      boundColumnName - the columnName to set