这段代码是我使用的乌龟图形版本,它使用JTextField中的命令进行绘制。现在,通过使用图形方法drawLine在乌龟已移动的位置绘制线来绘制图形。问题是每次我单击绘制按钮或输入6进行绘制时,repaint方法都会清除以前绘制的线条,而只会绘制当前线条
//1 - turtle up
//2 - turtle down/draw
//3 - turn right
//4 - turn left
//5 - move forward a number of steps
//6 - display drawing
import java.awt.Graphics;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.Box;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class TurtleGraphics2D extends JPanel implements ActionListener
{
private static final int FLOORSIZE = 200;
private static Box box;
private JTextField textField;
private JButton drawButton;
private int prevX = 0;
private int prevY = 0;
private int currentXPosition = 0;
private int currentYPosition = 0;
private int command, steps = 0;
private int leftCount = 0; //to know how many times the turtle has
//turned left and to reflect left in reference to north
private int rightCount = 0; //to know how many times the turtle has
//turned right and to reflect right in reference to north
private boolean isDown = false; //to know when pen is up or down
private boolean isLeft = false; //to know when turtle has turned left
private boolean isRight = false; //to know when turtle has turned
//right
public TurtleGraphics2D()
{
box = Box.createVerticalBox();
textField = new JTextField("Enter Command...");
drawButton = new JButton("Display Drawing");
box.add(textField);
box.add(drawButton);
textField.addActionListener(this);
drawButton.addActionListener(this);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if (isDown)
g.drawLine(prevY,prevX,currentYPosition,currentXPosition);
prevY = currentYPosition;
prevX = currentXPosition;
}
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == textField)
{
try
{
command = Integer.parseInt(textField.getText());
textField.setText("");
switch(command)
{
case 1:
isDown = false;
break;
case 2:
isDown = true;
break;
case 3:
isRight = true;
isLeft = false;
rightCount++;
if (rightCount > 4)
rightCount = 1;
System.out.println("Right Count: "+rightCount);
break;
case 4:
isLeft = true;
isRight = false;
leftCount++;
if (leftCount > 4)
leftCount = 1;
System.out.println("Left Count: "+leftCount);
break;
case 5:
steps = Integer.parseInt(JOptionPane.showInputDialog("Steps: "));
for(int i = 0; i < steps; ++i)
{
if (isRight == true)
{
if ((rightCount == 3 && leftCount == 0)||(rightCount == 1 && leftCount == 2)||(rightCount == 2 && leftCount == 3)||(rightCount == 3 && leftCount == 4)||(rightCount == 4 && leftCount == 1)) //cursor upward
{
if (currentXPosition > 0) // this condition ensures ArrayIndexOutOfBoundsException is avoided
currentXPosition--;
}
if ((rightCount == 0 && leftCount == 0)||(rightCount == 4 && leftCount == 4)||(rightCount == 1 && leftCount == 1)||(rightCount == 4 && leftCount == 0)||(rightCount == 2 && leftCount == 2)) //cursor right
{
if (currentYPosition < FLOORSIZE) // this condition ensures ArrayIndexOutOfBoundsException is avoided
currentYPosition++;
}
if ((rightCount == 2 && leftCount == 0)||(rightCount == 1 && leftCount == 3)||(rightCount == 4 && leftCount == 2)||(rightCount == 2 && leftCount == 4)||(rightCount == 3 && leftCount == 1)) //cursor left
{
if (currentYPosition > 0)
currentYPosition--;
}
if ((rightCount == 1 && leftCount == 0)||(rightCount == 2 && leftCount == 1)||(rightCount == 1 && leftCount == 4)) //cursor left
{
if (currentXPosition < FLOORSIZE)
currentXPosition++;
}
}
if (isLeft == true)
{
if ((rightCount == 3 && leftCount == 0)||(rightCount == 1 && leftCount == 2)||(rightCount == 2 && leftCount == 3)||(rightCount == 3 && leftCount == 4)||(rightCount == 4 && leftCount == 1)) //cursor upward
{
if (currentXPosition > 0)
currentXPosition--;
}
if ((rightCount == 0 && leftCount == 0)||(rightCount == 4 && leftCount == 4)||(rightCount == 1 && leftCount == 1)||(rightCount == 4 && leftCount == 0)||(rightCount == 2 && leftCount == 2)) //cursor right
{
if (currentYPosition < FLOORSIZE)
currentYPosition++;
}
if ((rightCount == 2 && leftCount == 0)||(rightCount == 1 && leftCount == 3)||(rightCount == 4 && leftCount == 2)||(rightCount == 2 && leftCount == 4)||(rightCount == 3 && leftCount == 1)) //cursor left
{
if (currentYPosition > 0)
currentYPosition--;
}
if ((rightCount == 1 && leftCount == 0)||(rightCount == 2 && leftCount == 1)||(rightCount == 1 && leftCount == 4)) //cursor left
{
if (currentXPosition < FLOORSIZE)
currentXPosition++;
}
}
if (isRight == false && isLeft == false && rightCount == 0 && leftCount == 0)//default/initial direction
{
currentYPosition++;
}
}
break;
case 6:
repaint();
break;
default:
break;
}
}
catch(IllegalArgumentException ex)
{
JOptionPane.showMessageDialog(null,"Invalid Command","Error Message",JOptionPane.ERROR_MESSAGE);
System.err.println("Invalid command");
}
}
else if (event.getSource() == drawButton)
{
repaint();
}
}
public static void main(String args[])
{
JFrame frame = new JFrame();
TurtleGraphics2D panel = new TurtleGraphics2D();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.add(box, BorderLayout.NORTH);
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
}
}
first line drawn
second line drawn clearing the previous line when they should both be displayed
答案 0 :(得分:0)
以下是使用the link that @camickr provided in the comments中讨论的 active 方法对代码进行的简化(虽然功能相同)的重做。此实现维护自定义ArrayList
对象的Line
,可用于在repaint
上重新创建图形:
import java.awt.Graphics;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.Box;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import java.util.ArrayList;
// 1 - turtle up
// 2 - turtle down/draw
// 3 - turn right
// 4 - turn left
// 5 - move forward a number of steps
// 6 - display drawing
class Line {
int startX;
int startY;
int endX;
int endY;
Line(int startX, int startY, int endX, int endY)
{
this.startX = startX;
this.startY = startY;
this.endX = endX;
this.endY = endY;
}
}
public class TurtleGraphics2D extends JPanel implements ActionListener
{
private static final int FLOORSIZE = 400;
private static Box box;
private JTextField textField;
private JButton drawButton;
private int currentXPosition = 0;
private int currentYPosition = 0;
private int heading = 0; // initial heading is South
private boolean isDown = false; // to know when pen is up or down
private ArrayList<Line> lines = new ArrayList<>(); // a collection of lines to (re)draw
public TurtleGraphics2D()
{
box = Box.createVerticalBox();
textField = new JTextField("Enter Command...");
drawButton = new JButton("Display Drawing");
box.add(textField);
box.add(drawButton);
textField.addActionListener(this);
drawButton.addActionListener(this);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for (Line line: lines)
{
g.drawLine(line.startX, line.startY, line.endX, line.endY);
}
}
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == textField)
{
try
{
int command = Integer.parseInt(textField.getText());
textField.setText("");
switch(command)
{
case 1:
isDown = false;
break;
case 2:
isDown = true;
break;
case 3: // right / clockwise
if (++heading > 3)
{
heading -= 4;
}
break;
case 4: // left / counterclockwise
if (--heading < 0)
{
heading += 4;
}
break;
case 5:
int steps = Integer.parseInt(JOptionPane.showInputDialog("Steps: "));
int prevX = currentXPosition;
int prevY = currentYPosition;
for (int i = 0; i < steps; i++)
{
if (heading == 0) // cursor South
{
// this condition ensures ArrayIndexOutOfBoundsException is avoided
if (++currentYPosition > FLOORSIZE)
{
currentYPosition--;
}
}
else if (heading == 1) // cursor West
{
if (--currentXPosition < 0)
{
currentXPosition++;
}
}
else if (heading == 2) // cursor North
{
if (--currentYPosition < 0)
{
currentYPosition++;
}
}
else if (heading == 3) // cursor East
{
if (++currentXPosition > FLOORSIZE)
{
currentXPosition--;
}
}
}
if (isDown)
{
lines.add(new Line(prevX, prevY, currentXPosition, currentYPosition));
}
break;
case 6:
repaint();
break;
default:
break;
}
}
catch(IllegalArgumentException ex)
{
JOptionPane.showMessageDialog(null, "Invalid Command", "Error Message", JOptionPane.ERROR_MESSAGE);
System.err.println("Invalid command");
}
}
else if (event.getSource() == drawButton)
{
repaint();
}
}
public static void main(String args[])
{
JFrame frame = new JFrame();
TurtleGraphics2D panel = new TurtleGraphics2D();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.add(box, BorderLayout.NORTH);
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
}
}
以下结果:4 5 <150> 3 5 <150> 2 5 <50> 4 5 <50> 4 5 <50> 4 5 <50>