/**
  * Create a new predictive string input frame.
  *
  * @param owner owner frame
  * @param force true if the user is forced to select one of the items
  * @param ignoreCase true if case should be ignored
  * @param info information supplier to use for additional information display
  * @param strategies array of matching strategies
  * @param actions actions to be performed when the user closes the frame, e.g. "OK" and "Cancel";
  *     "Cancel" has to be last
  * @param items list of items
  */
 public PredictiveInputFrame(
     SwingFrame owner,
     String title,
     boolean force,
     boolean ignoreCase,
     InfoSupplier<? super T> info,
     java.util.List<PredictiveInputModel.MatchingStrategy<T>> strategies,
     java.util.List<CloseAction<T>> actions,
     int cancelIndex,
     Collection<T> items) {
   super(title);
   _strategies = strategies;
   @SuppressWarnings("unchecked")
   PredictiveInputModel.MatchingStrategy<T>[] strategyArray = // UGLY
       IterUtil.toArray(_strategies, PredictiveInputModel.MatchingStrategy.class);
   _strategyBox = new JComboBox<PredictiveInputModel.MatchingStrategy<T>>(strategyArray);
   _currentStrategy = _strategies.get(0);
   _pim = new PredictiveInputModel<T>(ignoreCase, _currentStrategy, items);
   @SuppressWarnings("unchecked")
   T[] matchingItems =
       (T[])
           IterUtil.toArray(_pim.getMatchingItems(), Comparable.class); // T erases to Comparable!
   _matchList = new JList<T>(matchingItems);
   _force = force;
   _info = info;
   _lastState = null;
   _owner = owner;
   _actions = new ArrayList<CloseAction<T>>(actions);
   _buttons = new JButton[actions.size()];
   _cancelIndex = cancelIndex;
   init(_info != null);
   initDone(); // call mandated by SwingFrame contract
 }
 /** Update the match list based on the model. */
 private void updateList() {
   @SuppressWarnings("unchecked")
   T[] matchingItems =
       (T[])
           IterUtil.toArray(_pim.getMatchingItems(), Comparable.class); // T erases to Comparable!
   _matchList.setListData(matchingItems);
   _matchList.setSelectedValue(_pim.getCurrentItem(), true);
   updateExtensionLabel();
   updateInfo();
   if (_force) {
     for (int i = 0; i < _buttons.length - 1; ++i) {
       _buttons[i].setEnabled(_matchList.getModel().getSize() > 0);
     }
   }
 }
 /**
  * Return the item that was selected or null the user entered a mask not in the list and force ==
  * false.
  *
  * @return item that was selected or null
  */
 public T getItem() {
   if (!_force && _pim.getMatchingItems().size() == 0) return null;
   T item = _matchList.getSelectedValue();
   return item;
 }