📄 garbagecollectcanvas.java
字号:
myFriend.previousNodeInGCTraversalIsAFish = false;
myFriend.myColor = Color.black;
oh.myFriendLineColor = Color.black;
currentFishBeingMarked = fishObjectHandle;
return;
}
if (oh.fish.getFishColor() == Color.yellow) {
return; // exception condition
}
int myLunchIndex = gcHeap.getObjectPool(oh.objectPos + 1);
if ((myLunchIndex != 0) && (oh.myLunchLineColor == Color.gray)) {
ObjectHandle myLunch = gcHeap.getObjectHandle(myLunchIndex);
myLunch.previousNodeInGCTraversalIsAFish = false;
myLunch.myColor = Color.black;
oh.myLunchLineColor = Color.black;
currentFishBeingMarked = fishObjectHandle;
return;
}
if (oh.fish.getFishColor() == Color.cyan) {
return; // exception condition
}
int mySnackIndex = gcHeap.getObjectPool(oh.objectPos + 2);
if ((mySnackIndex != 0) && (oh.mySnackLineColor == Color.gray)) {
ObjectHandle mySnack = gcHeap.getObjectHandle(mySnackIndex);
mySnack.previousNodeInGCTraversalIsAFish = false;
mySnack.myColor = Color.black;
oh.mySnackLineColor = Color.black;
currentFishBeingMarked = fishObjectHandle;
return;
}
}
public void resetGCState() {
for (int i = 0; i < gcHeap.getHandlePoolSize(); ++i) {
ObjectHandle oh = gcHeap.getObjectHandle(i + 1);
if (!oh.free) {
oh.myColor = Color.white;
oh.previousNodeInGCTraversalIsAFish = false;
oh.previousFishInGCTraversal = 0;
oh.myFriendLineColor = Color.white;
oh.myLunchLineColor = Color.white;
oh.mySnackLineColor = Color.white;
}
}
currentGCState = garbageCollectorHasNotStarted;
fishAreBeingMarked = false;
yellowFishLocalVarIsCurrentGCMarkNode = false;
blueFishLocalVarIsCurrentGCMarkNode = false;
redFishLocalVarIsCurrentGCMarkNode = false;
yellowFishLocalVarLineColor = Color.white;
blueFishLocalVarLineColor = Color.white;
redFishLocalVarLineColor = Color.white;
controlPanelTextArea.setText(HeapOfFishStrings.garbageCollectInstructions);
}
public void paint(Graphics g) {
Font font = g.getFont();
FontMetrics fm = getFontMetrics(font);
int localVarsStringWidth = fm.stringWidth(HeapOfFishStrings.localVariables);
int redFishStringWidth = fm.stringWidth(HeapOfFishStrings.redFishLocalVar);
int blueFishStringWidth = fm.stringWidth(HeapOfFishStrings.blueFishLocalVar);
int yellowFishStringWidth = fm.stringWidth(HeapOfFishStrings.yellowFishLocalVar);
localVarRectWidth = localVarsStringWidth;
if (redFishStringWidth > localVarRectWidth) {
localVarRectWidth = redFishStringWidth;
}
if (blueFishStringWidth > localVarRectWidth) {
localVarRectWidth = blueFishStringWidth;
}
if (yellowFishStringWidth > localVarRectWidth) {
localVarRectWidth = yellowFishStringWidth;
}
localVarRectWidth += 2 * localVarStringMargin;
xFishAreaStart = localVarRectWidth + (2 * localVarStringMargin);
localVarRectHeight = fm.getAscent() + fm.getDescent() + 2 * localVarStringMargin;
Dimension dim = size();
int yLocalVarsAreaStart = (dim.height - (4 * localVarRectHeight)) / 2;
if (yLocalVarsAreaStart < 0) {
yLocalVarsAreaStart = 0;
}
// draw "Local Variables"
int xStart = ((localVarRectWidth - localVarsStringWidth) / 2) + localVarStringMargin;
int yStart = yLocalVarsAreaStart + localVarStringMargin + fm.getAscent();
g.setColor(Color.white);
g.drawString(HeapOfFishStrings.localVariables, xStart, yStart);
// draw "YellowFish yf" on a yellow rectangle
xStart = localVarStringMargin;
yStart = yLocalVarsAreaStart + localVarRectHeight;
if (currentGCState == garbageCollectorHasNotStarted || currentGCState == garbageCollectorIsDone) {
g.setColor(Color.yellow);
}
else if (yellowFishLocalVarIsCurrentGCMarkNode) {
g.setColor(currentGCMarkNodeColor);
}
else {
g.setColor(Color.white);
}
g.fillRect(xStart, yStart, localVarRectWidth, localVarRectHeight);
xLocalVarRectStart = xStart;
yYellowFishLocalVarStart = yStart;
xStart = ((localVarRectWidth - yellowFishStringWidth) / 2) + localVarStringMargin;
yStart += localVarStringMargin + fm.getAscent();
g.setColor(Color.black);
g.drawString(HeapOfFishStrings.yellowFishLocalVar, xStart, yStart);
// draw "BlueFish bf" on a cyan rectangle
xStart = localVarStringMargin;
yStart = yLocalVarsAreaStart + (2 * localVarRectHeight);
if (currentGCState == garbageCollectorHasNotStarted || currentGCState == garbageCollectorIsDone) {
g.setColor(Color.cyan);
}
else if (blueFishLocalVarIsCurrentGCMarkNode) {
g.setColor(currentGCMarkNodeColor);
}
else {
g.setColor(Color.white);
}
g.fillRect(xStart, yStart, localVarRectWidth, localVarRectHeight);
yBlueFishLocalVarStart = yStart;
xStart = ((localVarRectWidth - blueFishStringWidth) / 2) + localVarStringMargin;
yStart += localVarStringMargin + fm.getAscent();
g.setColor(Color.black);
g.drawString(HeapOfFishStrings.blueFishLocalVar, xStart, yStart);
// draw "RedFish rf" on a red rectangle
xStart = localVarStringMargin;
yStart = yLocalVarsAreaStart + (3 * localVarRectHeight);
if (currentGCState == garbageCollectorHasNotStarted || currentGCState == garbageCollectorIsDone) {
g.setColor(Color.red);
}
else if (redFishLocalVarIsCurrentGCMarkNode) {
g.setColor(currentGCMarkNodeColor);
}
else {
g.setColor(Color.white);
}
g.fillRect(xStart, yStart, localVarRectWidth, localVarRectHeight);
yRedFishLocalVarStart = yStart;
xStart = ((localVarRectWidth - redFishStringWidth) / 2) + localVarStringMargin;
yStart += localVarStringMargin + fm.getAscent();
g.setColor(Color.black);
g.drawString(HeapOfFishStrings.redFishLocalVar, xStart, yStart);
if (localVars.yellowFish != 0) {
g.setColor(Color.blue);
if (currentGCState == garbageCollectorHasNotStarted || currentGCState == garbageCollectorIsDone) {
g.setXORMode(Color.yellow);
}
else {
g.setXORMode(yellowFishLocalVarLineColor);
}
ObjectHandle yf = gcHeap.getObjectHandle(localVars.yellowFish);
int xLineStart = xLocalVarRectStart + localVarRectWidth;
int yLineStart = yYellowFishLocalVarStart + (localVarRectHeight / 2);
g.drawLine(xLineStart, yLineStart, yf.fish.getFishPosition().x, yf.fish.getFishPosition().y);
if (localVars.yellowLineStart == null) {
localVars.yellowLineStart = new Point(0, 0);
localVars.yellowLineEnd = new Point(0, 0);
}
localVars.yellowLineStart.x = xLineStart;
localVars.yellowLineStart.y = yLineStart;
localVars.yellowLineEnd.x = yf.fish.getFishPosition().x;
localVars.yellowLineEnd.y = yf.fish.getFishPosition().y;
g.setPaintMode();
}
if (localVars.blueFish != 0) {
g.setColor(Color.blue);
if (currentGCState == garbageCollectorHasNotStarted || currentGCState == garbageCollectorIsDone) {
g.setXORMode(Color.cyan);
}
else {
g.setXORMode(blueFishLocalVarLineColor);
}
ObjectHandle bf = gcHeap.getObjectHandle(localVars.blueFish);
int xLineStart = xLocalVarRectStart + localVarRectWidth;
int yLineStart = yBlueFishLocalVarStart + (localVarRectHeight / 2);
g.drawLine(xLineStart, yLineStart, bf.fish.getFishPosition().x, bf.fish.getFishPosition().y);
if (localVars.blueLineStart == null) {
localVars.blueLineStart = new Point(0, 0);
localVars.blueLineEnd = new Point(0, 0);
}
localVars.blueLineStart.x = xLineStart;
localVars.blueLineStart.y = yLineStart;
localVars.blueLineEnd.x = bf.fish.getFishPosition().x;
localVars.blueLineEnd.y = bf.fish.getFishPosition().y;
g.setPaintMode();
}
if (localVars.redFish != 0) {
g.setColor(Color.blue);
if (currentGCState == garbageCollectorHasNotStarted || currentGCState == garbageCollectorIsDone) {
g.setXORMode(Color.red);
}
else {
g.setXORMode(redFishLocalVarLineColor);
}
ObjectHandle rf = gcHeap.getObjectHandle(localVars.redFish);
int xLineStart = xLocalVarRectStart + localVarRectWidth;
int yLineStart = yRedFishLocalVarStart + (localVarRectHeight / 2);
g.drawLine(xLineStart, yLineStart, rf.fish.getFishPosition().x, rf.fish.getFishPosition().y);
if (localVars.redLineStart == null) {
localVars.redLineStart = new Point(0, 0);
localVars.redLineEnd = new Point(0, 0);
}
localVars.redLineStart.x = xLineStart;
localVars.redLineStart.y = yLineStart;
localVars.redLineEnd.x = rf.fish.getFishPosition().x;
localVars.redLineEnd.y = rf.fish.getFishPosition().y;
g.setPaintMode();
}
// Figure out how many slots will be in each of three columns of slots where
// new fish are put.
int columnCount = 3;
int slotsPerColumn = gcHeap.getHandlePoolSize() / columnCount;
if (gcHeap.getHandlePoolSize() % columnCount > 0) {
++slotsPerColumn;
}
int fishAreaWidth = dim.width - xFishAreaStart;
int slotWidth = fishAreaWidth / columnCount;
int slotHeight = dim.height / slotsPerColumn;
for (int i = 0; i < gcHeap.getHandlePoolSize(); ++i) {
ObjectHandle oh = gcHeap.getObjectHandle(i + 1);
if (!oh.free) {
FishIcon fishIcon = oh.fish;
if (!fishIcon.getFishHasBeenInitiallyPositioned()) {
int column = i / slotsPerColumn;
int row = i % slotsPerColumn;
int xFishPosition = (int) ((double) (slotWidth - fishIcon.getFishWidth()) * Math.random());
if (xFishPosition < 0) {
xFishPosition = 0;
}
xFishPosition += xFishAreaStart + (column * slotWidth);
int yFishPosition = (slotHeight - fishIcon.getFishHeight()) / 2;
if (yFishPosition < 0) {
yFishPosition = 0;
}
yFishPosition += row * slotHeight;
fishIcon.moveFish(xFishPosition, yFishPosition);
}
if (currentGCState == garbageCollectorHasNotStarted || currentGCState == garbageCollectorIsDone) {
fishIcon.paint(g);
}
else {
if (fishAreBeingMarked && currentFishBeingMarked == i + 1) {
fishIcon.paintWithSpecialColors(g, currentGCMarkNodeColor, Color.black);
}
else {
Color eyeColor = Color.black;
if (oh.myColor == Color.black) {
eyeColor = Color.white;
}
fishIcon.paintWithSpecialColors(g, oh.myColor, eyeColor);
}
}
// Draw any lines connecting fish.
g.setColor(Color.blue);
g.setXORMode(fishIcon.getFishColor());
Point fishNose = fishIcon.getFishNosePosition();
oh.gotFriend = false;
oh.myFriendLineStart = null;
oh.myFriendLineEnd = null;
oh.gotLunch = false;
oh.myLunchLineStart = null;
oh.myLunchLineEnd = null;
oh.gotSnack = false;
oh.mySnackLineStart = null;
oh.mySnackLineEnd = null;
int myFriendIndex = gcHeap.getObjectPool(oh.objectPos);
if (myFriendIndex != 0) {
if (currentGCState != garbageCollectorHasNotStarted && currentGCState != garbageCollectorIsDone) {
g.setPaintMode();
g.setColor(Color.blue);
g.setXORMode(oh.myFriendLineColor);
}
ObjectHandle myFriend = gcHeap.getObjectHandle(myFriendIndex);
g.drawLine(fishNose.x, fishNose.y, myFriend.fish.getFishPosition().x, myFriend.fish.getFishPosition().y);
oh.gotFriend = true;
oh.myFriendLineStart = new Point(fishNose.x, fishNose.y);
oh.myFriendLineEnd = new Point(myFriend.fish.getFishPosition().x, myFriend.fish.getFishPosition().y);
}
if (fishIcon.getFishColor() == Color.yellow) {
g.setPaintMode();
continue;
}
int myLunchIndex = gcHeap.getObjectPool(oh.objectPos + 1);
if (myLunchIndex != 0) {
if (currentGCState != garbageCollectorHasNotStarted && currentGCState != garbageCollectorIsDone) {
g.setPaintMode();
g.setColor(Color.blue);
g.setXORMode(oh.myLunchLineColor);
}
ObjectHandle myLunch = gcHeap.getObjectHandle(myLunchIndex);
g.drawLine(fishNose.x, fishNose.y, myLunch.fish.getFishPosition().x, myLunch.fish.getFishPosition().y);
oh.gotLunch = true;
oh.myLunchLineStart = new Point(fishNose.x, fishNose.y);
oh.myLunchLineEnd = new Point(myLunch.fish.getFishPosition().x, myLunch.fish.getFishPosition().y);
}
if (fishIcon.getFishColor() == Color.cyan) {
g.setPaintMode();
continue;
}
int mySnackIndex = gcHeap.getObjectPool(oh.objectPos + 2);
if (mySnackIndex != 0) {
if (currentGCState != garbageCollectorHasNotStarted && currentGCState != garbageCollectorIsDone) {
g.setPaintMode();
g.setColor(Color.blue);
g.setXORMode(oh.mySnackLineColor);
}
ObjectHandle mySnack = gcHeap.getObjectHandle(mySnackIndex);
g.drawLine(fishNose.x, fishNose.y, mySnack.fish.getFishPosition().x, mySnack.fish.getFishPosition().y);
oh.gotSnack = true;
oh.mySnackLineStart = new Point(fishNose.x, fishNose.y);
oh.mySnackLineEnd = new Point(mySnack.fish.getFishPosition().x, mySnack.fish.getFishPosition().y);
}
g.setPaintMode();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -