JComponent () { myTableModel = new MyTableModel(); myTableModel.addFromAnnotations(myProject); JBTable table = new JBTable(myTableModel); table.setColumnSelectionAllowed(false); table.setShowGrid(false); JTextField stringCellEditor = new JTextField(); stringCellEditor.putClientProperty(DarculaUIUtil.COMPACT_PROPERTY, Boolean.TRUE); table.setDefaultEditor(String.class, new DefaultCellEditor(stringCellEditor)); table.setDefaultRenderer(String.class, new DefaultTableCellRenderer() { @Override public Dimension getPreferredSize() { Dimension size = super.getPreferredSize(); Dimension editorSize = stringCellEditor.getPreferredSize(); size.height = Math.max(size.height, editorSize.height); return size; } }); TableColumnModel columnModel = table.getColumnModel(); TableUtil.setupCheckboxColumn(columnModel.getColumn(MyTableModel.ENABLED_COLUMN)); ToolbarDecorator decorator = ToolbarDecorator.createDecorator(table); decorator.setAddAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { myTableModel.addRow(); } }); decorator.setRemoveAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { TableUtil.removeSelectedItems(table); } }); decorator.setMoveUpAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { TableUtil.moveSelectedItemsUp(table); } }); decorator.setMoveDownAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { TableUtil.moveSelectedItemsDown(table); } }); decorator.addExtraAction(new DumbAwareActionButton(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.duplicate"), JavaDebuggerBundle.messagePointer("action.AnActionButton.description.duplicate"), PlatformIcons.COPY_ICON) { @Override public boolean isEnabled() { return table.getSelectedRowCount() == 1; } @Override public @NotNull ActionUpdateThread getActionUpdateThread() { return ActionUpdateThread.EDT; } @Override public void actionPerformed(@NotNull AnActionEvent e) { selectedCapturePoints(table).forEach(c -> { try { int idx = myTableModel.add(c.clone()); table.getSelectionModel().setSelectionInterval(idx, idx); } catch (CloneNotSupportedException ex) { LOG.error(ex); } }); } }); decorator.addExtraAction(new DumbAwareActionButton(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.enable.selected"), JavaDebuggerBundle.messagePointer("action.AnActionButton.description.enable.selected"), PlatformIcons.SELECT_ALL_ICON) { @Override public boolean isEnabled() { return table.getSelectedRowCount() > 0; } @Override public @NotNull ActionUpdateThread getActionUpdateThread() { return ActionUpdateThread.EDT; } @Override public void actionPerformed(@NotNull AnActionEvent e) { selectedCapturePoints(table).forEach(c -> c.myEnabled = true); table.repaint(); } }); decorator.addExtraAction(new DumbAwareActionButton(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.disable.selected"), JavaDebuggerBundle.messagePointer("action.AnActionButton.description.disable.selected"), PlatformIcons.UNSELECT_ALL_ICON) { @Override public boolean isEnabled() { return table.getSelectedRowCount() > 0; } @Override public @NotNull ActionUpdateThread getActionUpdateThread() { return ActionUpdateThread.EDT; } @Override public void actionPerformed(@NotNull AnActionEvent e) { selectedCapturePoints(table).forEach(c -> c.myEnabled = false); table.repaint(); } }); new DumbAwareAction(CommonBundle.message("action.text.toggle")) { @Override public void update(@NotNull AnActionEvent e) { e.getPresentation().setEnabled(table.getSelectedRowCount() == 1 && !table.isEditing()); } @Override public @NotNull ActionUpdateThread getActionUpdateThread() { return ActionUpdateThread.EDT; } @Override public void actionPerformed(@NotNull final AnActionEvent e) { selectedCapturePoints(table).forEach(c -> c.myEnabled = !c.myEnabled); table.repaint(); } }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0)), table); decorator.addExtraAction(new DumbAwareActionButton(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.import"), JavaDebuggerBundle.messagePointer("action.AnActionButton.description.import"), AllIcons.Actions.Install) { @Override public void actionPerformed(@NotNull final AnActionEvent e) { FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, true, false, true, true) { @Override public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { return super.isFileVisible(file, showHiddenFiles) && (file.isDirectory() || "xml".equals(file.getExtension()) || FileTypeRegistry.getInstance().isFileOfType(file, ArchiveFileType.INSTANCE)); } @Override public boolean isFileSelectable(@Nullable VirtualFile file) { return file != null && FileTypeRegistry.getInstance().isFileOfType(file, StdFileTypes.XML); } }; descriptor.setDescription(JavaDebuggerBundle.message("please.select.a.file.to.import")); descriptor.setTitle(JavaDebuggerBundle.message("import.capture.points")); VirtualFile[] files = FileChooser.chooseFiles(descriptor, e.getProject(), null); if (ArrayUtil.isEmpty(files)) return; table.getSelectionModel().clearSelection(); for (VirtualFile file : files) { try { for (Element element : JDOMUtil.load(file.getInputStream()).getChildren()) { int idx = myTableModel.addIfNeeded(XmlSerializer.deserialize(element, CapturePoint.class)); table.getSelectionModel().addSelectionInterval(idx, idx); } } catch (Exception ex) { final String msg = ex.getLocalizedMessage(); Messages.showErrorDialog(e.getProject(), msg != null && !msg.isEmpty() ? msg : ex.toString(), JavaDebuggerBundle.message("export.failed")); } } } @Override public @NotNull ActionUpdateThread getActionUpdateThread() { return ActionUpdateThread.BGT; } }); decorator.addExtraAction(new DumbAwareActionButton(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.export"), JavaDebuggerBundle.messagePointer("action.AnActionButton.description.export"), AllIcons.ToolbarDecorator.Export) { @Override public void actionPerformed(@NotNull final AnActionEvent e) { VirtualFileWrapper wrapper = FileChooserFactory.getInstance() .createSaveFileDialog(new FileSaverDescriptor(JavaDebuggerBundle.message("export.selected.capture.points.to.file"), "", "xml"), e.getProject()) .save((Path)null, null); if (wrapper == null) return; Element rootElement = new Element("capture-points"); selectedCapturePoints(table).forEach(c -> { try { CapturePoint clone = c.clone(); clone.myEnabled = false; rootElement.addContent(XmlSerializer.serialize(clone)); } catch (CloneNotSupportedException ex) { LOG.error(ex); } }); try { JDOMUtil.write(rootElement, wrapper.getFile().toPath()); } catch (Exception ex) { final String msg = ex.getLocalizedMessage(); Messages.showErrorDialog(e.getProject(), msg != null && !msg.isEmpty() ? msg : ex.toString(), JavaDebuggerBundle.message("export.failed")); } } @Override public boolean isEnabled() { return table.getSelectedRowCount() > 0; } @Override public @NotNull ActionUpdateThread getActionUpdateThread() { return ActionUpdateThread.EDT; } }); myConfigureAnnotationsButton.addActionListener(e -> new AsyncAnnotationsDialog(myProject).show()); myCapturePanel.setBorder( IdeBorderFactory.createTitledBorder(JavaDebuggerBundle.message("settings.breakpoints.based"), false, JBUI.insetsTop(8)) .setShowLine(false)); myCapturePanel.add(decorator.createPanel(), BorderLayout.CENTER); return myPanel; }