@Override public void execute() { if (context.getSelection().size() != 1) return; SNode n = context.getSelection().items().iterator().next(); if (!(n instanceof SGroup)) return; final SGroup group = (SGroup) n; SketchDocument doc = context.getDocument(); final List<SNode> model = doc.getCurrentPage().getModel(); model.remove(group); model.addAll(group.getNodes()); context.getSelection().clear(); for (SNode node : group.getNodes()) { node.setTranslateX(node.getTranslateX() + group.getTranslateX()); node.setTranslateY(node.getTranslateY() + group.getTranslateY()); context.getSelection().addSelectedNode(node); } context.redraw(); UndoManager.UndoableAction action = new UndoManager.UndoableAction() { public void executeUndo() { model.removeAll(group.getNodes()); for (SNode node : group.getNodes()) { node.setTranslateX(node.getTranslateX() - group.getTranslateX()); node.setTranslateY(node.getTranslateY() - group.getTranslateY()); } model.add(group); context.getSelection().setSelectedNode(group); context.redraw(); } public void executeRedo() { model.remove(group); for (SNode node : group.getNodes()) { model.add(node); node.setTranslateX(node.getTranslateX() + group.getTranslateX()); node.setTranslateY(node.getTranslateY() + group.getTranslateY()); } context.getSelection().setSelectedNodes(group.getNodes()); context.redraw(); } public CharSequence getName() { return "ungroup shapes"; } }; context.getUndoManager().pushAction(action); }