package bluej.stride.framedjava.frames;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import bluej.stride.framedjava.slots.TypeSlot;
import bluej.stride.generic.ExtensionDescription.ExtensionSource;
import bluej.stride.generic.FrameContentItem;
import bluej.stride.generic.FrameCursor;
import bluej.utility.javafx.FXConsumer;
import bluej.utility.javafx.JavaFXUtil;
import bluej.stride.framedjava.ast.ExpressionSlotFragment;
import bluej.stride.framedjava.ast.HighlightedBreakpoint;
import bluej.stride.framedjava.ast.NameDefSlotFragment;
import bluej.stride.framedjava.ast.TypeSlotFragment;
import bluej.stride.framedjava.canvases.JavaCanvas;
import bluej.stride.framedjava.elements.CodeElement;
import bluej.stride.framedjava.elements.ForeachElement;
import bluej.stride.framedjava.frames.BreakFrame.BreakEncloser;
import bluej.stride.framedjava.slots.EachExpressionSlot;
import bluej.stride.generic.ExtensionDescription;
import bluej.stride.generic.Frame;
import bluej.stride.generic.FrameCanvas;
import bluej.stride.generic.FrameFactory;
import bluej.stride.generic.InteractionManager;
import bluej.stride.generic.SingleCanvasFrame;
import bluej.stride.operations.FrameOperation;
import bluej.stride.slots.HeaderItem;
import bluej.stride.slots.SlotLabel;
import bluej.stride.slots.SlotTraversalChars;
import bluej.stride.slots.VariableNameDefTextSlot;
import bluej.stride.operations.PullUpContentsOperation;
import bluej.utility.Utility;
import bluej.utility.javafx.SharedTransition;
import threadchecker.OnThread;
import threadchecker.Tag;
public class ForeachFrame extends SingleCanvasFrame
implements CodeFrame<ForeachElement>, DebuggableParentFrame{
private final TypeSlot type;
private final VariableNameDefTextSlot var;
private final EachExpressionSlot collection;
private ForeachElement element;
private final SlotLabel inLabel;
private final SlotLabel finalLabel;
private ForeachFrame(InteractionManager editor)
{
super(editor, "for each", "foreach-");
type = new TypeSlot(editor, this, this, getHeaderRow(), TypeSlot.Role.DECLARATION, "foreach-type-");
type.setSimplePromptText("item type");
type.addClosingChar(' ');
var = new VariableNameDefTextSlot(editor, this, getHeaderRow(), "foreach-var-");
var.setPromptText("item name");
var.addValueListener(SlotTraversalChars.IDENTIFIER);
collection = new EachExpressionSlot(editor, this, this, getHeaderRow(), type, var, "foreach-collection-");
collection.setSimplePromptText("collection");
inLabel = new SlotLabel(" in ");
finalLabel=new SlotLabel("");
setHeaderRow(new SlotLabel("("),finalLabel, type, var, inLabel, collection, new SlotLabel(")"));
FXConsumer<String> updateTriple = s -> updateSidebarCurried("for each ").accept(type.getText() + " " + var.getText() + " : " + collection.getText());
type.onTextPropertyChange(updateTriple);
JavaFXUtil.addChangeListener(var.textProperty(), updateTriple);
collection.onTextPropertyChange(updateTriple);
}
public ForeachFrame(InteractionManager editor, TypeSlotFragment type, NameDefSlotFragment var, ExpressionSlotFragment collection, boolean enabled)
{
this(editor);
this.type.setText(type);
this.var.setText(var);
this.collection.setText(collection);
frameEnabledProperty.set(enabled);
}
public ForeachFrame(InteractionManager editor, List<Frame> contents)
{
this(editor);
getCanvas().getFirstCursor().insertFramesAfter(contents);
}
@Override
@OnThread(Tag.FXPlatform)
public List getContextOperations()
{
List<FrameOperation> r = super.getContextOperations();
r.add(new PullUpContentsOperation(getEditor()));
return r;
}
public static FrameFactory getFactory()
{
return new FrameFactory<ForeachFrame>() {
@Override
public ForeachFrame createBlock(InteractionManager editor)
{
return new ForeachFrame(editor);
}
@Override
public ForeachFrame createBlock(InteractionManager editor, List<Frame> contents)
{
return new ForeachFrame(editor, contents);
}
@Override
public Class getBlockClass()
{
return ForeachFrame.class;
}
};
}
@Override
public FrameCanvas createCanvas(InteractionManager editor, String stylePrefix)
{
return new JavaCanvas(editor, this, stylePrefix, false);
}
@Override
@OnThread(Tag.FXPlatform)
public HighlightedBreakpoint showDebugAtEnd(DebugInfo debug)
{
return ((JavaCanvas) getCanvas()).showDebugBefore(null, debug);
}
@Override
public void regenerateCode()
{
List<CodeElement> contents = new ArrayList<CodeElement>();
for (CodeFrame<?> f : canvas.getBlocksSubtype(CodeFrame.class)) {
f.regenerateCode();
contents.add(f.getCode());
}
element = new ForeachElement(this, type.getSlotElement(), var.getSlotElement(),
collection.getSlotElement(), contents, frameEnabledProperty.get());
}
@Override
public ForeachElement getCode()
{
return element;
}
@Override
public List getAvailableExtensions(FrameCanvas canvas, FrameCursor cursorInCanvas)
{
return Utility.concat(super.getAvailableExtensions(canvas, cursorInCanvas),
Arrays.asList(new ExtensionDescription('\b', "Remove loop, keep contents", () ->
new PullUpContentsOperation(getEditor()).activate(this), false, ExtensionSource.INSIDE_FIRST)));
}
@Override
public List getDeclaredVariablesWithin(FrameCanvas c)
{
if (c != getCanvas())
throw new IllegalArgumentException("Canvas does not exist in this frame");
String name = var.getText();
if (name.isEmpty())
return Collections.emptyList();
else{ return Arrays.asList(name);
}
}
@Override
public BreakEncloser asBreakEncloser()
{
return BreakEncloser.FOREACH;
}
@Override
@OnThread(Tag.FXPlatform)
public void setView(View oldView, View newView, SharedTransition animateProgress)
{
super.setView(oldView, newView, animateProgress);
String caption = newView == View.JAVA_PREVIEW ? "for" : "for each";
headerCaptionLabel.setText(caption);
String finalkeyword = newView == View.JAVA_PREVIEW ? "final " : "";
finalLabel.setText(finalkeyword);
inLabel.setText(newView == View.JAVA_PREVIEW ? (collection.isConstantRange() ? " = " : " : ") : " in ");
if (isFrameEnabled() && (oldView == View.JAVA_PREVIEW || newView == View.JAVA_PREVIEW))
canvas.previewCurly(newView == View.JAVA_PREVIEW, header.getLeftFirstItem() + tweakCurlyX(), tweakOpeningCurlyY(), animateProgress);
}
@Override
@OnThread(Tag.FXPlatform)
public boolean backspaceAtStart(FrameContentItem srcRow, HeaderItem src)
{
if (src == type && type.isAlmostBlank())
{
new PullUpContentsOperation(getEditor()).activate(getFrame());
return true;
}
return super.backspaceAtStart(srcRow, src);
}
}
. ForeachFrame
. ForeachFrame
. ForeachFrame
. getContextOperations
. getFactory
. createBlock
. createBlock
. getBlockClass
. createCanvas
. showDebugAtEnd
. regenerateCode
. getCode
. getAvailableExtensions
. getDeclaredVariablesWithin
. asBreakEncloser
. setView
. backspaceAtStart
263 neLoCode
+ 0 LoComm