如何在每行之后进行DocumentListener比较,而不仅仅是在程序运行后进行比较?

时间:2013-03-09 18:40:15

标签: java

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

re
Fd
hr

即使“hr”存在,它也从未标志着这一点。我可以做什么,以便每次插入\ n时TurtleRenderer都会读取行,而不是只在代码运行后读取行?

我的代码:

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();
    }
}

3 个答案:

答案 0 :(得分:1)

您的问题是,您目前正在测试JTextArea持有的整个文本是否包含“hr”。如果hr是JTextArea中的唯一文本,则可能会出现这种情况,但是再次添加文本时,这将始终为false。您需要检查的是最后一行是否为“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 

答案 1 :(得分: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方法。 There are some differences though

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


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

您无需在changedUpdate(DocumentEvent e)内的DocumentListener方法中执行任何操作。仅当属性或一组属性发生更改时才会调用此方法,即文档样式已更改,这在JTextArea中是不可能的,因为它不支持样式文本。

我希望我能正确理解你的问题。

答案 2 :(得分:0)

首先,与previous comment一样,方法makeBoardFrom每次都会收到 整个计划。如果由您决定将该程序拆分为单个命令,然后执行每个命令。您不应尝试更改TurtleRenderer类以使其行为不同。

其次,如果你想将乌龟向左移动两个方格,你必须标记两个方格 参观的广场,而不仅仅是目的地广场。现在,在您的解决方案中,仅使用previousX+=2;,您只需将目标广场标记为已访问。

第三,在initialBoard方法中,你还必须用true实际标记乌龟的初始方格。在你的情况下,将是位置(0,0)的方格。