private void rebuildListContent() {
   ArrayList<Item> items = new ArrayList<Item>();
   int i = 0;
   List<Data> contents = new ArrayList<Data>(getContents());
   for (Data content : contents) {
     String fullString = getStringRepresentationFor(content);
     if (fullString != null) {
       String shortString;
       fullString = StringUtil.convertLineSeparators(fullString);
       int newLineIdx = fullString.indexOf('\n');
       if (newLineIdx == -1) {
         shortString = fullString.trim();
       } else {
         int lastLooked = 0;
         do {
           int nextLineIdx = fullString.indexOf("\n", lastLooked);
           if (nextLineIdx > lastLooked) {
             shortString = fullString.substring(lastLooked, nextLineIdx).trim() + " ...";
             break;
           } else if (nextLineIdx == -1) {
             shortString = " ...";
             break;
           }
           lastLooked = nextLineIdx + 1;
         } while (true);
       }
       items.add(new Item(i++, shortString, fullString));
     }
   }
   myAllContents = contents;
   FilteringListModel listModel = (FilteringListModel) myList.getModel();
   ((CollectionListModel) listModel.getOriginalModel()).removeAll();
   listModel.addAll(items);
   ListWithFilter listWithFilter = UIUtil.getParentOfType(ListWithFilter.class, myList);
   if (listWithFilter != null) {
     listWithFilter.getSpeedSearch().update();
     if (listModel.getSize() == 0) listWithFilter.resetFilter();
   }
 }
  private void initLeftPanel() {
    myLeftPanel = new JPanel(new GridLayoutManager(2, 1, JBInsets.NONE, -1, -1));

    mySearchField = new SearchTextField(false);
    mySearchField.addDocumentListener(
        new DocumentAdapter() {
          @Override
          protected void textChanged(DocumentEvent e) {
            TemplateItem tmp = myCurrentTemplateItem;
            myFilteringListModel.refilter();
            int idx = myFilteringListModel.getElementIndex(tmp);
            myList.setSelectedIndex(idx < 0 ? 0 : idx);
          }
        });

    new AnAction() {
      @Override
      public void actionPerformed(AnActionEvent e) {
        InputEvent event = e.getInputEvent();
        if (event instanceof KeyEvent) {
          int row = myList.getSelectedIndex();
          int toSelect;
          switch (((KeyEvent) event).getKeyCode()) {
            case KeyEvent.VK_UP:
              toSelect = row == 0 ? myList.getItemsCount() - 1 : row - 1;
              myList.setSelectedIndex(toSelect);
              myList.ensureIndexIsVisible(toSelect);
              break;
            case KeyEvent.VK_DOWN:
              toSelect = row < myList.getItemsCount() - 1 ? row + 1 : 0;
              myList.setSelectedIndex(toSelect);
              myList.ensureIndexIsVisible(toSelect);
              break;
          }
        }
      }
    }.registerCustomShortcutSet(
        new CustomShortcutSet(KeyEvent.VK_UP, KeyEvent.VK_DOWN), mySearchField);

    myLeftPanel.add(
        mySearchField,
        new GridConstraints(
            0,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_SHRINK,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null));

    myList = new JBList();

    List<ProjectTemplatesGroup> templatesGroups =
        new SortedList<ProjectTemplatesGroup>(
            new Comparator<ProjectTemplatesGroup>() {
              @Override
              public int compare(ProjectTemplatesGroup o1, ProjectTemplatesGroup o2) {
                // Put DSL/Development groups on top & Other group to the last place
                if (o1.getName().equals("DSL")) return -1;
                if (o2.getName().equals("DSL")) return 1;
                if (o1.getName().equals("Development")) return -1;
                if (o2.getName().equals("Development")) return 1;
                if (o1.getName().equals("Other")) return 1;
                if (o2.getName().equals("Other")) return -1;
                return o1.getName().compareToIgnoreCase(o2.getName());
              }
            });
    List<TemplateItem> templateItems = new LinkedList<TemplateItem>();

    templatesGroups.addAll(Arrays.asList(ProjectTemplatesGroup.EP_NAME.getExtensions()));

    for (ProjectTemplatesGroup templatesGroup : templatesGroups) {
      for (MPSProjectTemplate template : templatesGroup.getTemplates()) {
        templateItems.add(new TemplateItem(template, templatesGroup));
      }
    }

    CollectionListModel<TemplateItem> model = new CollectionListModel<TemplateItem>(templateItems);
    myFilteringListModel = new FilteringListModel<TemplateItem>(model);
    myFilteringListModel.setFilter(
        new Condition<TemplateItem>() {
          @Override
          public boolean value(TemplateItem templateItem) {
            return templateItem
                .getName()
                .toLowerCase()
                .contains(mySearchField.getText().trim().toLowerCase());
          }
        });
    myList.setModel(myFilteringListModel);

    myList.setCellRenderer(
        new GroupedItemsListRenderer(
            new ListItemDescriptor() {
              @Nullable
              @Override
              public String getTextFor(Object value) {
                return ((TemplateItem) value).getName();
              }

              @Nullable
              @Override
              public String getTooltipFor(Object value) {
                return null;
              }

              @Nullable
              @Override
              public Icon getIconFor(Object value) {
                return ((TemplateItem) value).getIcon();
              }

              @Override
              public boolean hasSeparatorAboveOf(Object value) {
                TemplateItem item = (TemplateItem) value;
                int index = myFilteringListModel.getElementIndex(item);
                return index == 0
                    || !myFilteringListModel
                        .getElementAt(index - 1)
                        .getGroupName()
                        .equals(item.getGroupName());
              }

              @Nullable
              @Override
              public String getCaptionAboveOf(Object value) {
                return ((TemplateItem) value).getGroupName();
              }
            }));

    myList
        .getSelectionModel()
        .addListSelectionListener(
            new ListSelectionListener() {

              @Override
              public void valueChanged(ListSelectionEvent e) {
                myCurrentTemplateItem = (TemplateItem) myList.getSelectedValue();
                updateRightPanel();
              }
            });

    myLeftPanel.add(
        ScrollPaneFactory.createScrollPane(myList),
        new GridConstraints(
            1,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_BOTH,
            GridConstraints.SIZEPOLICY_CAN_SHRINK,
            GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK,
            null,
            null,
            null));
    myLeftPanel.setPreferredSize(new Dimension(200, 400));
  }
 static boolean notFiltered(JList list) {
   ListModel model1 = list.getModel();
   if (!(model1 instanceof FilteringListModel)) return true;
   final FilteringListModel model = (FilteringListModel) model1;
   return model.getOriginalModel().getSize() == model.getSize();
 }
  public ProjectTypesList(
      JBList list,
      SearchTextField searchField,
      MultiMap<TemplatesGroup, ProjectTemplate> map,
      final WizardContext context) {
    myList = list;
    mySearchField = searchField;

    List<TemplateItem> items = buildItems(map);
    final RemoteTemplatesFactory factory = new RemoteTemplatesFactory();
    final String groupName = factory.getGroups()[0];
    final TemplatesGroup samplesGroup = new TemplatesGroup(groupName, "", null);
    myLoadingItem =
        new TemplateItem(new LoadingProjectTemplate(), samplesGroup) {
          @Override
          Icon getIcon() {
            return null;
          }

          @Override
          String getDescription() {
            return "";
          }
        };
    items.add(myLoadingItem);
    final CollectionListModel<TemplateItem> model = new CollectionListModel<TemplateItem>(items);
    myFilteringListModel = new FilteringListModel<TemplateItem>(model);

    ProgressManager.getInstance()
        .run(
            new Task.Backgroundable(context.getProject(), "Loading Samples") {
              @Override
              public void run(@NotNull ProgressIndicator indicator) {
                try {
                  myList.setPaintBusy(true);
                  final ProjectTemplate[] templates = factory.createTemplates(groupName, context);
                  Runnable runnable =
                      new Runnable() {
                        public void run() {
                          int index = myList.getSelectedIndex();
                          model.remove(myLoadingItem);
                          for (ProjectTemplate template : templates) {
                            model.add(new TemplateItem(template, samplesGroup));
                          }
                          myList.setSelectedIndex(index);
                        }
                      };
                  SwingUtilities.invokeLater(runnable);
                } finally {
                  myList.setPaintBusy(false);
                }
              }
            });

    myList.setCellRenderer(
        new GroupedItemsListRenderer(
            new ListItemDescriptor() {
              @Nullable
              @Override
              public String getTextFor(Object value) {
                return ((TemplateItem) value).getName();
              }

              @Nullable
              @Override
              public String getTooltipFor(Object value) {
                return null;
              }

              @Nullable
              @Override
              public Icon getIconFor(Object value) {
                return ((TemplateItem) value).getIcon();
              }

              @Override
              public boolean hasSeparatorAboveOf(Object value) {
                TemplateItem item = (TemplateItem) value;
                int index = myFilteringListModel.getElementIndex(item);
                return index == 0
                    || !myFilteringListModel
                        .getElementAt(index - 1)
                        .getGroupName()
                        .equals(item.getGroupName());
              }

              @Nullable
              @Override
              public String getCaptionAboveOf(Object value) {
                return ((TemplateItem) value).getGroupName();
              }
            }));

    myFilteringListModel.setFilter(
        new Condition<TemplateItem>() {
          @Override
          public boolean value(TemplateItem item) {
            return item.getMatchingDegree() > Integer.MIN_VALUE;
          }
        });

    myList.setModel(myFilteringListModel);
    mySearchField.addDocumentListener(
        new DocumentAdapter() {
          @Override
          protected void textChanged(DocumentEvent e) {
            String text = "*" + mySearchField.getText().trim();
            myMatcher = NameUtil.buildMatcher(text, NameUtil.MatchingCaseSensitivity.NONE);

            TemplateItem value = (TemplateItem) myList.getSelectedValue();
            int degree = value == null ? Integer.MIN_VALUE : value.getMatchingDegree();
            myBestMatch = Pair.create(degree > Integer.MIN_VALUE ? value : null, degree);

            myFilteringListModel.refilter();
            if (myBestMatch.first != null) {
              myList.setSelectedValue(myBestMatch.first, true);
            }
          }
        });

    new AnAction() {
      @Override
      public void actionPerformed(AnActionEvent e) {
        InputEvent event = e.getInputEvent();
        if (event instanceof KeyEvent) {
          int row = myList.getSelectedIndex();
          int toSelect;
          switch (((KeyEvent) event).getKeyCode()) {
            case KeyEvent.VK_UP:
              toSelect = row == 0 ? myList.getItemsCount() - 1 : row - 1;
              myList.setSelectedIndex(toSelect);
              myList.ensureIndexIsVisible(toSelect);
              break;
            case KeyEvent.VK_DOWN:
              toSelect = row < myList.getItemsCount() - 1 ? row + 1 : 0;
              myList.setSelectedIndex(toSelect);
              myList.ensureIndexIsVisible(toSelect);
              break;
          }
        }
      }
    }.registerCustomShortcutSet(
        new CustomShortcutSet(KeyEvent.VK_UP, KeyEvent.VK_DOWN), mySearchField);
  }