public FilterPanel init(
      final ReadablePreset.ReadableVoice voice, TableExclusiveSelectionContext tsc)
      throws ParameterException, DeviceException {
    this.setLayout(new FlowLayout());
    final List filterIds =
        voice
            .getPreset()
            .getDeviceParameterContext()
            .getVoiceContext()
            .getIdsForCategory(ParameterCategories.VOICE_FILTER);

    filterModels = new ReadableParameterModel[filterIds.size()];

    try {
      for (int i = 0, j = filterIds.size(); i < j; i++)
        filterModels[i] = voice.getParameterModel((Integer) filterIds.get(i));
    } catch (IllegalParameterIdException e) {
      ZUtilities.zDisposeCollection(Arrays.asList(filterModels));
      throw e;
    }

    Action ra =
        new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
            try {
              voice
                  .getPreset()
                  .refreshVoiceParameters(
                      voice.getVoiceNumber(),
                      (Integer[]) filterIds.toArray(new Integer[filterIds.size()]));
            } catch (PresetException e1) {
              e1.printStackTrace();
            }
          }
        };
    ra.putValue("tip", "Refresh Filter");

    FilterParameterTableModel model = new FilterParameterTableModel(filterModels);

    RowHeaderedAndSectionedTablePanel ampPanel;
    VoiceParameterTable vpt =
        new VoiceParameterTable(voice, ParameterCategories.VOICE_FILTER, model, "Filter");
    tsc.addTableToContext(vpt);
    ampPanel =
        new RowHeaderedAndSectionedTablePanel()
            .init(vpt, "Show Filter", UIColors.getTableBorder(), ra);
    this.add(ampPanel);
    return this;
  }
  protected Component[] getCustomMenuItems() {
    final int[] selRows = this.getSelectedRows();
    Action dc =
        new AbstractAction("Disable channel") {
          public void actionPerformed(ActionEvent e) {
            MultiModeContext mmc = null;
            try {
              mmc = device.getMultiModeContext();
              for (int i = 0, j = selRows.length; i < j; i++) {
                try {
                  mmc.setPreset(IntPool.get(selRows[i] + 1), IntPool.get(-1)).post();
                } catch (ResourceUnavailableException e1) {
                  e1.printStackTrace();
                }
              }
            } catch (DeviceException e1) {
              e1.printStackTrace();
            }
          }
        };
    JMenuItem pmi = null;
    try {
      ArrayList selPresets = new ArrayList();
      PresetContext dpc = device.getDefaultPresetContext();
      MultiModeContext mmc = device.getMultiModeContext();
      for (int i = 0; i < selRows.length; i++) {
        Integer preset =
            mmc.getPreset(IntPool.get(selRows[i] + 1)); // +1 because midi channels indexed from 1
        if (preset.intValue() >= 0) selPresets.add(dpc.getReadablePreset(preset));
      }
      if (selPresets.size() > 0) {

        Object[] sp = ZUtilities.eliminateDuplicates(selPresets.toArray());
        String name =
            (sp.length > 1
                ? "Presets on selected channels"
                : ((ReadablePreset) sp[0]).getDisplayName());
        pmi = ZCommandFactory.getMenu(sp, name);
      }
    } catch (Exception e) {
    }

    Action stm = null;
    if (this.getSelectedRows().length == 1 && this.getSelectedRow() < 16)
      stm =
          new AbstractAction("Set Ch " + (getSelectedRow() + 1) + " as effects channel") {
            public void actionPerformed(ActionEvent e) {
              try {
                device
                    .getMasterContext()
                    .setMasterParam(IntPool.get(245), IntPool.get(getSelectedRow()))
                    .post();
              } catch (Exception e1) {
                e1.printStackTrace();
              }
            }
          };
    ArrayList comps = new ArrayList();
    // comps.add(new PopupCategoryLabel("Multimode"));
    JMenuItem[] mi;
    Component[] mmi;
    if (pmi != null) mi = new JMenuItem[] {pmi, new JMenuItem(dc)};
    else mi = new JMenuItem[] {new JMenuItem(dc)};

    mmi =
        ZCommandFactory.getMenu(new Object[] {mmtm.getMultimodeContext()}, "Multimode")
            .getMenuComponents();
    comps.addAll(Arrays.asList(mmi));
    comps.addAll(Arrays.asList(mi));
    if (stm != null) comps.add(new JMenuItem(stm));
    return (Component[]) comps.toArray(new Component[comps.size()]);
  }
 public void zDispose() {
   ZUtilities.zDisposeCollection(Arrays.asList(filterModels));
   filterModels = null;
 }