【问题标题】:Rectangle not using containg correct bounds when using getHeight(), and getWidth()使用 getHeight() 和 getWidth() 时不使用包含正确边界的矩形
【发布时间】:2011-12-10 13:34:55
【问题描述】:

我一直在兜圈子,试图弄清楚为什么这不起作用。我有一个矩形,它位于 0,0。并且分别是 getHeight 的 1/3 和 getWidth() 的 1/3,分别表示高度和宽度。我有一个“捕获” x 和 y 坐标的鼠标事件。当我使用“矩形”时。包含(鼠标的 x 和 y)

*编辑:当我检查鼠标点击的位置时,它总是返回为 0,0 *

这是我的一些代码:

package com.blackattack.tictactoe;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JPanel;

public class TicTacToePanel extends JPanel implements MouseListener {

    Graphics2D g2d;
    Rectangle[] bounds = new Rectangle[9];
    TicTacToeLogic board = new TicTacToeLogic();
    int STATE = 0;
    final int PLAYING = 0;
    final int LOSS = 1;
    final int WIN = 2;
    Win w = new Win(false, "e");



    public TicTacToePanel() {
        super();
        addMouseListener(this);

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        bounds[0] = new Rectangle(0, 0, getWidth()/3, getHeight()/3);

        bounds[1] = new Rectangle(getWidth()/3, 0, getWidth()/3, getHeight()/3);
        bounds[2] = new Rectangle((getWidth()/3)*2, 0, getWidth()/3, getHeight()/3);

        bounds[3] = new Rectangle(0, getHeight()/3, getWidth()/3, getHeight()/3);
        bounds[4] = new Rectangle(getWidth()/3, getHeight()/3, getWidth()/3, getHeight()/3);
        bounds[5] = new Rectangle((getWidth()/3)*2, getHeight()/3, getWidth()/3, getHeight()/3);

        bounds[6] = new Rectangle(0, getHeight()/3, (getWidth()/3)*2, getHeight()/3);
        bounds[7] = new Rectangle(getWidth()/3, (getHeight()/3)*2, getWidth()/3, getHeight()/3);
        bounds[8] = new Rectangle((getWidth()/3)*2, (getHeight()/3)*2, getWidth()/3, getHeight()/3);
        if(w.didWin && w.who.equals("x")){
            STATE = WIN;
        }
        if(w.didWin && w.who.equals("o")){
            STATE = LOSS;
        }

        g2d = (Graphics2D) g;
        if(STATE == PLAYING) {
        g2d.setColor(Color.black);
        g2d.drawLine(getWidth() / 3, 0, getWidth() / 3, getHeight());
        g2d.drawLine((getWidth() / 3) * 2, 0, (getWidth() / 3) * 2, getHeight());
        g2d.drawLine(0, getHeight() / 3, getWidth(), getHeight() / 3);
        g2d.drawLine(0, (getHeight() / 3) * 2, getWidth(),
                (getHeight() / 3) * 2);

        g2d.setColor(Color.blue);
        if(board.board[0].equals("x")) {
            g2d.drawLine(0, 0, getWidth()/3, getHeight()/3);
            g2d.drawLine(getWidth()/3, 0, 0, getHeight()/3);
        }

        }

    }



    @Override
    public void mouseClicked(MouseEvent e) {
         int x = getX();
          int y = getY();

          // check which "bounds" contains the mouse click?
          for (int i = 0; i < bounds.length; i++) {
             if (bounds[i].contains(e.getPoint())) {
                System.out.println("Point " + x + " " + y + " contains mouse");
             }
          }
          repaint();
    }
    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent e) {

          }






    @Override
    public void mouseReleased(MouseEvent e) {

    }



}

我的一些理论是:

  • 在paintComponent 期间调用getHeight/Width 不起作用,但在我绘制线条时它可以正常工作
  • 我在创建矩形时将值放置在错误的位置,但我仔细检查了这一点。
  • 我尝试过使用代码,但没有成功

谢谢,

安德鲁

PS 这里是sscce:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class mainGUI extends JFrame {

    TicTacToePanel tic = new TicTacToePanel();

    public mainGUI() {
        super("Tic Tac Toe");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(900, 700);
        setResizable(false);
        add(tic);
        setVisible(true);
    }

    public class TicTacToePanel extends JPanel implements MouseListener {

        Graphics2D g2d;
        Rectangle[] bounds = new Rectangle[9];
        TicTacToeLogic board = new TicTacToeLogic();
        int STATE = 0;
        final int PLAYING = 0;
        final int LOSS = 1;
        final int WIN = 2;
        Win w = new Win(false, "e");



        public TicTacToePanel() {
            super();
            addMouseListener(this);

        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            bounds[0] = new Rectangle(0, 0, getWidth()/3, getHeight()/3);

            bounds[1] = new Rectangle(getWidth()/3, 0, getWidth()/3, getHeight()/3);
            bounds[2] = new Rectangle((getWidth()/3)*2, 0, getWidth()/3, getHeight()/3);

            bounds[3] = new Rectangle(0, getHeight()/3, getWidth()/3, getHeight()/3);
            bounds[4] = new Rectangle(getWidth()/3, getHeight()/3, getWidth()/3, getHeight()/3);
            bounds[5] = new Rectangle((getWidth()/3)*2, getHeight()/3, getWidth()/3, getHeight()/3);

            bounds[6] = new Rectangle(0, getHeight()/3, (getWidth()/3)*2, getHeight()/3);
            bounds[7] = new Rectangle(getWidth()/3, (getHeight()/3)*2, getWidth()/3, getHeight()/3);
            bounds[8] = new Rectangle((getWidth()/3)*2, (getHeight()/3)*2, getWidth()/3, getHeight()/3);
            if(w.didWin && w.who.equals("x")){
                STATE = WIN;
            }
            if(w.didWin && w.who.equals("o")){
                STATE = LOSS;
            }

            g2d = (Graphics2D) g;
            if(STATE == PLAYING) {
            g2d.setColor(Color.black);
            g2d.drawLine(getWidth() / 3, 0, getWidth() / 3, getHeight());
            g2d.drawLine((getWidth() / 3) * 2, 0, (getWidth() / 3) * 2, getHeight());
            g2d.drawLine(0, getHeight() / 3, getWidth(), getHeight() / 3);
            g2d.drawLine(0, (getHeight() / 3) * 2, getWidth(),
                    (getHeight() / 3) * 2);

            g2d.setColor(Color.blue);
            if(board.board[0].equals("x")) {
                g2d.drawLine(0, 0, getWidth()/3, getHeight()/3);
                g2d.drawLine(getWidth()/3, 0, 0, getHeight()/3);
            }

            }

        }



        @Override
        public void mouseClicked(MouseEvent e) {
             int x = getX();
              int y = getY();

              // check which "bounds" contains the mouse click?
              for (int i = 0; i < bounds.length; i++) {
                 if (bounds[i].contains(e.getPoint())) {
                     board.changeState(i, "x");
                    System.out.println("Point " + x + " " + y + " contains mouse");
                 }
              }
              repaint();
        }
        @Override
        public void mouseEntered(MouseEvent e) {

        }

        @Override
        public void mouseExited(MouseEvent e) {

        }

        @Override
        public void mousePressed(MouseEvent e) {

              }






        @Override
        public void mouseReleased(MouseEvent e) {

        }




}


    public class TicTacToeLogic {

        String[] board = { "e", "e", "e", "e", "e", "e", "e", "e", "e" };

        public TicTacToeLogic() {

        }

        public void changeState(int pos, String val) {
            board[pos] = val;
        }

        public void aiPlayerChoose() {
            boolean ready = true;
            if(isWin().who.equals("x") && isWin().didWin){
                ready=false;
            }
            while (ready) {
                Random r = new Random(System.currentTimeMillis());
                int which = r.nextInt(8);
                if (board[which].equals("e")) {
                    board[which] = "o";
                    ready = false;
                }
            }
        }

        public Win isWin() {
            // o
            if (board[0].equals("x") && board[1].equals("x")
                    && board[2].equals("x")) {
                return new Win(true, "x");
            }
            if (board[3].equals("x") && board[4].equals("x")
                    && board[5].equals("x")) {
                return new Win(true, "x");
            }
            if (board[6].equals("x") && board[7].equals("x")
                    && board[8].equals("x")) {
                return new Win(true, "x");
            }
            // o
            if (board[0].equals("o") && board[1].equals("o")
                    && board[2].equals("o")) {
                return new Win(true, "o");
            }
            if (board[3].equals("o") && board[4].equals("o")
                    && board[5].equals("o")) {
                return new Win(true, "o");
            }
            if (board[6].equals("o") && board[7].equals("o")
                    && board[8].equals("o")) {
                return new Win(true, "o");
            }
            // x
            if (board[0].equals("x") && board[4].equals("x")
                    && board[8].equals("x")) {
                return new Win(true, "x");
            }
            if (board[2].equals("x") && board[4].equals("x")
                    && board[6].equals("x")) {
                return new Win(true, "x");
            }
            // o
            if (board[0].equals("o") && board[4].equals("o")
                    && board[8].equals("o")) {
                return new Win(true, "o");
            }
            if (board[2].equals("o") && board[4].equals("o")
                    && board[6].equals("o")) {
                return new Win(true, "o");
            }
            // x
            if (board[0].equals("x") && board[3].equals("x")
                    && board[6].equals("x")) {
                return new Win(true, "x");
            }
            if (board[1].equals("x") && board[4].equals("x")
                    && board[7].equals("x")) {
                return new Win(true, "x");
            }
            if (board[2].equals("x") && board[5].equals("x")
                    && board[8].equals("x")) {
                return new Win(true, "x");
            }
            // x
            if (board[0].equals("o") && board[3].equals("o")
                    && board[6].equals("o")) {
                return new Win(true, "o");
            }
            if (board[1].equals("o") && board[4].equals("o")
                    && board[7].equals("o")) {
                return new Win(true, "o");
            }
            if (board[2].equals("o") && board[5].equals("o")
                    && board[8].equals("o")) {
                return new Win(true, "o");
            }

            return new Win(false, "e");
        }



    }

    public class Win {

        boolean didWin = false;
        String who = "";

        public Win(boolean i, String s) {
            didWin = i;
            who = s;

        }
    }


    public static void main(String[] args) {
        mainGUI app = new mainGUI();
    }

}

【问题讨论】:

  • 建议:1) 在你的代码中加入 println 语句,以查看程序中不同位置的变量状态。 2) 不要在paint 或paintComponent 方法中执行程序逻辑。例如,这种方法绝不是您应该决定游戏是否获胜的方法。它仅用于绘画和绘画。 3)使用您的阵列来帮助您。如果您充分利用您的数组,您将能够消除 1/2 以上的代码。
  • @HovercraftFullOfEels 是时候清理一些代码了!
  • 如果您还没有这样做,我建议您获得一个可以轻松实现带断点调试的良好 IDE。在paintComponent 的第一行添加一个断点,并在代码遍历程序时检查每个值实际上是什么。可能发生的情况是您所期望的值在当时根本不是这样。如果您可以遍历代码,则可以在遍历代码时检查每个值。
  • @Asaf 我正在使用 eclipse 并使用了断点我认为 eclipse 应该可以正常工作
  • @AndrewDelgadillo 是的,这是我个人使用的。如果您能够看到这些值但仍然无法找出问题所在,我建议您将额外信息添加到问题中。也可以试试下面答案中的建议。

标签: java height width jpanel


【解决方案1】:

例如,只需将其添加到您的鼠标侦听器中(同样,鼠标侦听器中的大部分代码都可以通过更智能地使用数组进行压缩),这样您就可以看到单击正方形时会发生什么:

@Override
public void mouseClicked(MouseEvent e) {
  int x = getX();
  int y = getY();

  // check which "bounds" contains the mouse click?
  for (int i = 0; i < bounds.length; i++) {
     if (bounds[i].contains(e.getPoint())) {
        System.out.println("Point " + i + " contains mouse");
     }
  }

顺便说一句:我会捕获 mousePressed 事件而不是 mouseClicked 事件,因为后者可能会错过按下。

【讨论】:

  • @Andrew:这段代码告诉我,您在定义边界[6] 的边界时遇到了问题。我建议您使用 for 循环设置边界,这样代码只需要编写一次并且对所有矩形都是正确的。
  • 谢谢。当我打印出点击的 x 和 y 时,它总是显示 0,0,这很奇怪。我认为鼠标监听器搞砸了一些事情
  • 它不会为我打印 0,0,但会显示单击了哪个边界对象。我知道你做了什么,它不仅仅是 6,也许还有 8。再次,使用数组,使用 for 循环,修复代码。
  • 我已经用 for 循环替换了 mouseClicked。我明白它是如何工作的,但你所说的“不仅仅是 6 个,也许还有 8 个”是什么意思?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-08
  • 2011-09-02
  • 1970-01-01
  • 2013-03-30
  • 1970-01-01
相关资源
最近更新 更多