1

我通过添加一个基本代码来了解它是如何工作的,开始执行第 3 项任务。但我无法摆脱这个问题。我只是添加了一个“if”,这样如果输入文本等于“hr”,那么海龟每次都会向右移动 2 个方格。但是当我运行代码时,就好像它只检查第一个字符。如果前两个字符是“hr”,那么它标记了一个点,但如果不是,它就不再检查输入。例如,如果我写:

re
Fd
hr

即使“hr”在那里,它也永远不会标记点。我该怎么做才能让 TurtleRenderer 在每次插入 \n 时读取该行,而不仅仅是在代码运行时读取?

我的代码:

package turtle;

public class BoardMaker {

    private static int MAX = 100;
    private boolean[][] board = new boolean[MAX][MAX];
    int previousX = 0;
    int previousY = 0;

    public boolean[][] makeBoardFrom(String description) {      
        if(description.contentEquals("hr")){
            previousX+=2;
            board[previousX][previousY]=true;
        }
        return board;
    }

    public boolean[][] initialBoard() {
        for(int i=0;i<MAX;i++)
        {
            for(int j=0;j<MAX;j++)
                board[i][j]=false;
        }
        return board;       
    }
}

TurtleRenderer 类:

package turtle;

public class TurtleRenderer extends Panel implements  DocumentListener {

    private static final long serialVersionUID = 1;

    static final Dimension WINDOW_SIZE = new Dimension(1150, 1150);

    boolean [][] board;
    final BoardMaker boardMaker;

    public TurtleRenderer() {
        boardMaker = new BoardMaker();
        board = boardMaker.initialBoard();
    }

    static public void main(String args[]) throws Exception {
        JFrame frame = new JFrame("Display image");
        JPanel panel = new JPanel();
        TurtleRenderer image = new TurtleRenderer();
        image.setPreferredSize(WINDOW_SIZE);
        JScrollPane textArea = makeTextArea(image);
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
        panel.add(image);
        buildRightPanel(panel, textArea);
        frame.setSize(WINDOW_SIZE);
        frame.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent we){
                System.exit(0);
            }});
        frame.getContentPane().add(panel);
        frame.setVisible(true);
    }

    static void buildRightPanel(JPanel panel,JComponent textArea) {
        JLabel label = new JLabel("Your program:");
        label.setPreferredSize(new Dimension(150, 20));
        JPanel right = new JPanel();
        textArea.setPreferredSize(new Dimension(150,500));
        right.setLayout(new BoxLayout(right, BoxLayout.Y_AXIS));
        right.add(label);
        right.add(textArea);
        panel.add(right);
    }

    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D)g;
        g2d.setColor(Color.white);
        g.fillRect(0, 0, WINDOW_SIZE.width, WINDOW_SIZE.width);
        if(board == null) 
            return;
        g2d.setColor(Color.red);
        for(int i=0;i<board.length;i++) {
            for(int j=0;j<board.length;j++) {
                if(board[i][j])
                    g2d.fillRect(9*i+1, 9*j+1, 6, 6);
            }
        }
    }

    static JScrollPane makeTextArea(TurtleRenderer image) {
        JTextArea textArea = new JTextArea();
        textArea.getDocument().addDocumentListener(image);
        textArea.setVisible(true);
        JScrollPane areaScrollPane = new JScrollPane(textArea);
        areaScrollPane.setVerticalScrollBarPolicy(
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        areaScrollPane.setBorder(BorderFactory.createLineBorder(Color.black));
        return areaScrollPane;
    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        changed(e);
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        changed(e);
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        changed(e);
    }

    void changed(DocumentEvent de) {
        String description;
        Document document = de.getDocument();
        try {
            description = document.getText(0, document.getLength());
        } catch (BadLocationException e) {
            throw new RuntimeException(e);
        }
        try {
            board = boardMaker.makeBoardFrom(description);
        } catch(ParserException pe) {
            board = null;
        }
        this.repaint();
    }
}
4

3 回答 3

1

您的问题是您当前正在测试JTextArea 持有的整个文本是否持有“hr”。如果 hr 是 JTextArea 中的唯一文本,这可能是正确的,但一旦添加了更多文本,这将始终是错误的。您需要检查的是最后一行是否为“hr”。

由于这是家庭作业,我不会发布解决方案,但您的 DocumentListener 的伪代码逻辑解决方案可能是:

try
   get the text String from the document
   get the last char from this String
   if this last Char == carriage return which is (char)10
      split the text into lines using the carriage return as the split's delimiter
      get the last line held by this array and check it
      if it is hr do something
   end if last char == carriage return
end try
catch for BadLocationException 
于 2013-03-09T19:01:30.193 回答
0

首先,和之前的评论一样,该方法makeBoardFrom每次都会接收整个程序。如果由您决定将该程序拆分为单独的命令,然后执行每个命令。您不应尝试将 TurtleRenderer 类更改为不同的行为。

其次,如果要将海龟向左移动两个方格,则必须将两个方格都标记为已访问,而不仅仅是目标方格。现在在您的解决方案中,仅使用previousX+=2;您仅将目标广场标记为已访问。

第三,在该initialBoard方法中,您还必须用 实际标记海龟的初始正方形true。在您的情况下,这将是位置 (0, 0) 处的正方形。

于 2013-03-09T22:49:19.790 回答
0

从 Javadocs,

public boolean contentEquals(CharSequence cs)

Compares this string to the specified CharSequence. 
The result is true if and only if this String represents the same sequence of char values as the specified sequence.

public boolean contains(CharSequence s)

Returns true if and only if this string contains the specified sequence of char values.

从而String.contentEquals将功能更多的一种String.equals方法。虽然有一些差异

与这个问题一样,您需要String.contains方法来检查文本是否包含String "hr"


关于代码效率的另一条建议:

您不必changedUpdate(DocumentEvent e)DocumentListener. 此方法仅在一个属性或一组属性发生更改时调用,即文档的样式已更改,这在 a 中是不可能的,JTextArea因为它不支持样式化文本。

我希望我已经正确理解了您的问题。

于 2013-03-09T19:17:17.207 回答