Skip to content

Commit

Permalink
Merge pull request #2312 from neilccbrown/terminal-display
Browse files Browse the repository at this point in the history
Add sections to BlueJ terminal to divide up different method calls
  • Loading branch information
neilccbrown authored Jan 24, 2024
2 parents 074506a + 9a03133 commit c4fdeaa
Show file tree
Hide file tree
Showing 10 changed files with 382 additions and 89 deletions.
8 changes: 2 additions & 6 deletions bluej/src/main/java/bluej/BlueJEvent.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
This file is part of the BlueJ program.
Copyright (C) 1999-2009,2010,2014,2016,2019 Michael Kolling and John Rosenberg
Copyright (C) 1999-2009,2010,2014,2016,2019,2024 Michael Kolling and John Rosenberg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -90,11 +90,7 @@ public class BlueJEvent
@OnThread(Tag.FXPlatform)
public static void raiseEvent(int eventId, Object arg)
{
Object[] listenersCopy = listeners.toArray();
for (int i = listenersCopy.length - 1; i >= 0; i--) {
BlueJEventListener listener = (BlueJEventListener) listenersCopy[i];
listener.blueJEvent(eventId, arg, null);
}
raiseEvent(eventId, arg, null);
}

/**
Expand Down
42 changes: 25 additions & 17 deletions bluej/src/main/java/bluej/debugmgr/ExecutionEvent.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
This file is part of the BlueJ program.
Copyright (C) 1999-2009,2010,2014 Michael Kolling and John Rosenberg
Copyright (C) 1999-2009,2010,2014,2024 Michael Kolling and John Rosenberg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -37,26 +37,35 @@ of the License, or (at your option) any later version.
@OnThread(Tag.Any)
public class ExecutionEvent
{
/**
* The execution has finished normally;
*/
public static final String NORMAL_EXIT = "Normal exit";
public static enum Result
{
/**
* The execution has finished normally;
*/
NORMAL_EXIT("Normal exit"),

/**
* The execution has finished due to an exception
*/
public static final String EXCEPTION_EXIT = "An exception occurred";
/**
* The execution has finished due to an exception
*/
EXCEPTION_EXIT("An exception occurred"),

/**
* The execution has finished because the user has forcefully terminated it
*/
public static final String TERMINATED_EXIT = "User terminated";
/**
* The execution has finished because the user has forcefully terminated it
*/
TERMINATED_EXIT("User terminated");

private final String text;
private Result(String text)
{
this.text = text;
}
}

private String className, objectName;
private String methodName;
private JavaType[] signature;
private String[] parameters;
private String result;
private Result result;
private String command;
private Package pkg;
private DebuggerObject resultObject; // If there is a result object it goes here.
Expand Down Expand Up @@ -109,11 +118,10 @@ public void setParameters (JavaType[] signature, String[] parameters)
/**
* Set the result of the execution. This should be one of:
* NORMAL_EXIT - the execution terminated successfully
* FORCED_EXIT - System.exit() was called
* EXCEPTION_EXIT - the execution failed due to an exception
* TERMINATED_EXIT - the user terminated the VM before execution completed
*/
public void setResult (String result)
public void setResult (Result result)
{
this.result = result;
}
Expand Down Expand Up @@ -198,7 +206,7 @@ public String[] getParameters()
* EXCEPTION_EXIT - the execution failed due to an exception
* TERMINATED_EXIT - the user terminated the VM before execution completed
*/
public String getResult()
public Result getResult()
{
return result;
}
Expand Down
6 changes: 3 additions & 3 deletions bluej/src/main/java/bluej/debugmgr/codepad/CodePad.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
This file is part of the BlueJ program.
Copyright (C) 1999-2009,2010,2011,2012,2013,2016,2017,2018,2019,2020,2021,2022,2023 Michael Kolling and John Rosenberg
Copyright (C) 1999-2009,2010,2011,2012,2013,2016,2017,2018,2019,2020,2021,2022,2023,2024 Michael Kolling and John Rosenberg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -857,7 +857,7 @@ public void putResult(final DebuggerObject result, final String name, final Invo

ExecutionEvent executionEvent = new ExecutionEvent(frame.getPackage());
executionEvent.setCommand(command);
executionEvent.setResult(ExecutionEvent.NORMAL_EXIT);
executionEvent.setResult(ExecutionEvent.Result.NORMAL_EXIT);
executionEvent.setResultObject(result);
BlueJEvent.raiseEvent(BlueJEvent.EXECUTION_RESULT, executionEvent);

Expand Down Expand Up @@ -934,7 +934,7 @@ public void putException(ExceptionDescription exception, InvokerRecord ir)
{
ExecutionEvent executionEvent = new ExecutionEvent(frame.getPackage());
executionEvent.setCommand(command);
executionEvent.setResult(ExecutionEvent.EXCEPTION_EXIT);
executionEvent.setResult(ExecutionEvent.Result.EXCEPTION_EXIT);
executionEvent.setException(exception);
BlueJEvent.raiseEvent(BlueJEvent.EXECUTION_RESULT, executionEvent);
updateInspectors();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
This file is part of the BlueJ program.
Copyright (C) 2017,2018,2019 Michael Kolling and John Rosenberg
Copyright (C) 2017,2018,2019,2024 Michael Kolling and John Rosenberg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -96,7 +96,7 @@ public void putResult(DebuggerObject result, String name, InvokerRecord ir)
executionEvent.setMethodName(mv.getName());
}
executionEvent.setParameters(method.getParamTypes(false), ir.getArgumentValues());
executionEvent.setResult(ExecutionEvent.NORMAL_EXIT);
executionEvent.setResult(ExecutionEvent.Result.NORMAL_EXIT);
executionEvent.setResultObject(result);
BlueJEvent.raiseEvent(BlueJEvent.EXECUTION_RESULT, executionEvent);

Expand Down Expand Up @@ -152,7 +152,7 @@ public void putException(ExceptionDescription exception, InvokerRecord ir)
{
ExecutionEvent executionEvent = new ExecutionEvent(pkg, className, objInstanceName);
executionEvent.setParameters(method.getParamTypes(false), ir.getArgumentValues());
executionEvent.setResult(ExecutionEvent.EXCEPTION_EXIT);
executionEvent.setResult(ExecutionEvent.Result.EXCEPTION_EXIT);
executionEvent.setException(exception);
BlueJEvent.raiseEvent(BlueJEvent.EXECUTION_RESULT, executionEvent);

Expand All @@ -165,7 +165,7 @@ public void putVMTerminated(InvokerRecord ir, boolean terminatedByUserCode)
{
ExecutionEvent executionEvent = new ExecutionEvent(pkg, className, objInstanceName);
executionEvent.setParameters(method.getParamTypes(false), ir.getArgumentValues());
executionEvent.setResult(terminatedByUserCode ? ExecutionEvent.NORMAL_EXIT : ExecutionEvent.TERMINATED_EXIT);
executionEvent.setResult(terminatedByUserCode ? ExecutionEvent.Result.NORMAL_EXIT : ExecutionEvent.Result.TERMINATED_EXIT);
BlueJEvent.raiseEvent(BlueJEvent.EXECUTION_RESULT, executionEvent);
}
}
41 changes: 41 additions & 0 deletions bluej/src/main/java/bluej/editor/base/LineDisplay.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ of the License, or (at your option) any later version.
import bluej.editor.base.BaseEditorPane.BaseEditorPaneListener;
import bluej.editor.base.TextLine.StyledSegment;
import bluej.editor.flow.Document;
import bluej.prefmgr.PrefMgr;
import bluej.utility.Debug;
import bluej.utility.javafx.FXFunction;
import com.google.common.cache.Cache;
Expand All @@ -34,7 +35,10 @@ of the License, or (at your option) any later version.
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.shape.Path;
import javafx.scene.shape.PathElement;
import javafx.scene.text.Font;
import javafx.scene.text.HitInfo;
import javafx.scene.text.Text;
import threadchecker.OnThread;
import threadchecker.Tag;

Expand All @@ -45,8 +49,10 @@ of the License, or (at your option) any later version.
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
* A class to handle the display of the set of visible lines in an editor window.
Expand Down Expand Up @@ -90,6 +96,41 @@ public LineDisplay(DoubleExpression horizScrollProperty, StringExpression fontCS
this.showLeftMargin = showLeftMargin;
}

/**
* Gets the X pixel position of the left edge of the given position
* @param lineIndex The line index (0 based in document, using same index as getVisibleLine)
* @param posInLine The column position in the line
* @return The position if we could calculate it, or empty if not (because we need a layout first)
*/
@OnThread(Tag.FXPlatform)
public Optional<Double> calculateLeftEdgeX(int lineIndex, int posInLine)
{
if (isLineVisible(lineIndex))
{
TextLine line = getVisibleLine(lineIndex).textLine;
// If the line needs layout, the positions won't be accurate:
if (line.isNeedsLayout())
return Optional.empty();
// Sometimes, it seems that the line can have the CSS for the font,
// and claim it doesn't need layout, but the font on the Text items
// has not actually been switched to the right font. In this case
// the positions will be inaccurate, so we should not calculate:
Font curFont = line.getChildren().stream().flatMap(n -> n instanceof Text ? Stream.of(((Text)n).getFont()) : Stream.empty()).findFirst().orElse(null);
if (curFont != null && !curFont.getFamily().equals(PrefMgr.getEditorFontFamily()))
return Optional.empty();
PathElement[] elements = line.caretShape(posInLine, true);
Path path = new Path(elements);
Bounds bounds = path.getBoundsInLocal();
// If the bounds are at left edge but char is not, might not have laid out yet:
if (posInLine > 0 && bounds.getMaxX() < 2.0)
{
return Optional.empty();
}
return Optional.of((bounds.getMinX() + bounds.getMaxX()) / 2.0);
}
return Optional.empty();
}

/**
* Gets the visible line object corresponding to the given document line.
* Throws an exception if that line is not visible (you should check first via isLineVisible).
Expand Down
37 changes: 3 additions & 34 deletions bluej/src/main/java/bluej/editor/flow/FlowEditorPane.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
This file is part of the BlueJ program.
Copyright (C) 2019,2020,2021,2022 Michael Kolling and John Rosenberg
Copyright (C) 2019,2020,2021,2022,2024 Michael Kolling and John Rosenberg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -33,28 +33,21 @@ of the License, or (at your option) any later version.
import bluej.editor.base.MarginAndTextLine.MarginDisplay;
import bluej.editor.base.TextLine.HighlightType;
import bluej.editor.base.TextLine.StyledSegment;
import bluej.prefmgr.PrefMgr;
import bluej.utility.javafx.JavaFXUtil;
import javafx.collections.ObservableList;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.geometry.Rectangle2D;
import javafx.scene.AccessibleAttribute;
import javafx.scene.Node;
import javafx.scene.control.IndexRange;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Region;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.PathElement;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import threadchecker.OnThread;
import threadchecker.Tag;

Expand All @@ -70,7 +63,6 @@ of the License, or (at your option) any later version.
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

/**
* A FlowEditorPane is a component with (optional) horizontal and vertical scroll bars.
Expand Down Expand Up @@ -515,31 +507,8 @@ public Optional<Double> getLeftEdgeX(int leftOfCharIndex)
static Optional<Double> getLeftEdgeX(int leftOfCharIndex, Document document, LineDisplay lineDisplay)
{
int lineIndex = document.getLineFromPosition(leftOfCharIndex);
if (lineDisplay.isLineVisible(lineIndex))
{
TextLine line = lineDisplay.getVisibleLine(lineIndex).textLine;
// If the line needs layout, the positions won't be accurate:
if (line.isNeedsLayout())
return Optional.empty();
// Sometimes, it seems that the line can have the CSS for the font,
// and claim it doesn't need layout, but the font on the Text items
// has not actually been switched to the right font. In this case
// the positions will be inaccurate, so we should not calculate:
Font curFont = line.getChildren().stream().flatMap(n -> n instanceof Text ? Stream.of(((Text)n).getFont()) : Stream.empty()).findFirst().orElse(null);
if (curFont != null && !curFont.getFamily().equals(PrefMgr.getEditorFontFamily()))
return Optional.empty();
int posInLine = leftOfCharIndex - document.getLineStart(lineIndex);
PathElement[] elements = line.caretShape(posInLine, true);
Path path = new Path(elements);
Bounds bounds = path.getBoundsInLocal();
// If the bounds are at left edge but char is not, might not have laid out yet:
if (posInLine > 0 && bounds.getMaxX() < 2.0)
{
return Optional.empty();
}
return Optional.of((bounds.getMinX() + bounds.getMaxX()) / 2.0);
}
return Optional.empty();
int posInLine = leftOfCharIndex - document.getLineStart(lineIndex);
return lineDisplay.calculateLeftEdgeX(lineIndex, posInLine);
}

public Optional<Bounds> getCaretBoundsOnScreen(int position)
Expand Down
Loading

0 comments on commit c4fdeaa

Please sign in to comment.