package bluej.stride.framedjava.frames;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import bluej.Config;
import bluej.stride.framedjava.ast.AccessPermission;
import bluej.stride.framedjava.ast.AccessPermissionFragment;
import bluej.stride.framedjava.ast.JavadocUnit;
import bluej.stride.framedjava.ast.NameDefSlotFragment;
import bluej.stride.framedjava.ast.ParamFragment;
import bluej.stride.framedjava.ast.ThrowsTypeFragment;
import bluej.stride.framedjava.ast.TypeSlotFragment;
import bluej.stride.framedjava.elements.MethodProtoElement;
import bluej.stride.framedjava.elements.NormalMethodElement;
import bluej.stride.framedjava.slots.TypeSlot;
import bluej.stride.generic.DocumentedSingleLineFrame;
import bluej.stride.generic.ExtensionDescription;
import bluej.stride.generic.ExtensionDescription.ExtensionSource;
import bluej.stride.generic.FrameCanvas;
import bluej.stride.generic.FrameCursor;
import bluej.stride.generic.FrameFactory;
import bluej.stride.generic.InteractionManager;
import bluej.stride.operations.CustomFrameOperation;
import bluej.stride.operations.FrameOperation;
import bluej.stride.slots.EditableSlot;
import bluej.stride.slots.EditableSlot.MenuItemOrder;
import bluej.stride.slots.FormalParameters;
import bluej.stride.slots.MethodNameDefTextSlot;
import bluej.stride.slots.SlotLabel;
import bluej.stride.slots.SlotTraversalChars;
import bluej.stride.slots.Throws;
import bluej.utility.javafx.JavaFXUtil;
import threadchecker.OnThread;
import threadchecker.Tag;
public class MethodProtoFrame extends DocumentedSingleLineFrame implements CodeFrame<MethodProtoElement>{
private final SlotLabel abstractLabel = new SlotLabel("abstract");
private final BooleanProperty parentIsClass = new SimpleBooleanProperty(false);
private final TypeSlot returnType;
private final MethodNameDefTextSlot methodName;
private final FormalParameters paramsPane;
private final Throws throwsPane;
private MethodProtoElement element;
public MethodProtoFrame(final InteractionManager editor)
{
super(editor, "", "method-");
methodName = new MethodNameDefTextSlot(editor, this, getHeaderRow(), null, "method-name-");
methodName.setPromptText("name");
methodName.addValueListener(SlotTraversalChars.METHOD_NAME);
returnType = new TypeSlot(editor, this, this, getHeaderRow(), TypeSlot.Role.RETURN, "method-return-type-");
returnType.setSimplePromptText("type");
returnType.addClosingChar(' ');
paramsPane = new FormalParameters(editor, this, this, getHeaderRow(), "method-param-");
setDocumentationPromptText("Describe your method here...");
throwsPane = new Throws(this, () -> {
TypeSlot s = new TypeSlot(editor, this, this, getHeaderRow(), TypeSlot.Role.THROWS_CATCH, "method-");
s.setSimplePromptText("thrown type");
return s;
}, () -> getCursorAfter().requestFocus(), editor);
getHeaderRow().getNode().getStyleClass().add("method-header");
bindHeader();
}
public MethodProtoFrame(final InteractionManager editor, TypeSlotFragment returnType,
NameDefSlotFragment methodName, List<ParamFragment> params, List<ThrowsTypeFragment> throwsTypes, String documentation, boolean enabled)
{
this(editor);
this.returnType.setText(returnType);
this.methodName.setText(methodName);
params.forEach(item -> paramsPane.addFormal(item.getParamType(), item.getParamName()));
throwsTypes.forEach(t -> throwsPane.addTypeSlotAtEnd(t.getType(), false));
setDocumentation(documentation);
frameEnabledProperty.set(enabled);
}
private void bindHeader()
{
getHeaderRow().bindContentsConcat(FXCollections.observableArrayList(
JavaFXUtil.listBool(parentIsClass, abstractLabel),
FXCollections.observableArrayList(returnType, methodName),
paramsPane.getSlots(),
throwsPane.getHeaderItems(),
FXCollections.observableArrayList(previewSemi)
));
}
public static FrameFactory getFactory()
{
return new FrameFactory<MethodProtoFrame>() {
@Override
public MethodProtoFrame createBlock(InteractionManager editor)
{
return new MethodProtoFrame(editor);
}
@Override
public Class getBlockClass()
{
return MethodProtoFrame.class;
}
};
}
@Override
@OnThread(Tag.FXPlatform)
public List getContextOperations()
{
List<FrameOperation> r = new ArrayList<>(super.getContextOperations());
if (parentIsClass.get())
{
r.add(new CustomFrameOperation(getEditor(), "abstract->concrete",
Arrays.asList("Change", "to Concrete"), MenuItemOrder.TRANSFORM, this, () -> {
FrameCursor c = getCursorBefore();
NormalMethodElement el = new NormalMethodElement(null, new AccessPermissionFragment(AccessPermission.PUBLIC),
false, false, returnType.getSlotElement(), methodName.getSlotElement(), paramsPane.getSlotElement(), throwsPane.getTypes(),
new ArrayList<>(), new JavadocUnit(getDocumentation()), frameEnabledProperty.get());
c.insertBlockAfter(el.createFrame(getEditor()));
c.getParentCanvas().removeBlock(this);
}));
}
return r;
}
@Override
public void regenerateCode()
{
element = new MethodProtoElement(this, returnType.getSlotElement(), methodName.getSlotElement(),
paramsPane.getSlotElement(), throwsPane.getTypes(), new JavadocUnit(getDocumentation()), frameEnabledProperty.get());
}
@Override
public boolean focusWhenJustAdded()
{
returnType.requestFocus();
return true;
}
@Override
public MethodProtoElement getCode()
{
return element;
}
@Override
public List getAvailableExtensions(FrameCanvas innerCanvas, FrameCursor cursorInCanvas)
{
ArrayList<ExtensionDescription> extensions = new ArrayList<>(super.getAvailableExtensions(innerCanvas, cursorInCanvas));
extensions.add(new ExtensionDescription('t', Config.getString("frame.class.add.throw"),
() -> throwsPane.addTypeSlotAtEnd("", true), true, ExtensionSource.BEFORE, ExtensionSource.AFTER, ExtensionSource.MODIFIER));
return extensions;
}
@Override
public void updateAppearance(FrameCanvas parentCanvas)
{
super.updateAppearance(parentCanvas);
parentIsClass.set(parentCanvas.getParent().getFrame() instanceof ClassFrame);
}
@Override
public EditableSlot getErrorShowRedirect()
{
return methodName;
}
}
. MethodProtoFrame
. MethodProtoFrame
. bindHeader
. getFactory
. createBlock
. getBlockClass
. getContextOperations
. regenerateCode
. focusWhenJustAdded
. getCode
. getAvailableExtensions
. updateAppearance
. getErrorShowRedirect
221 neLoCode
+ 0 LoComm