如何使用鼠标侦听器制作矩形并将其添加到JFrame?

时间:2015-12-04 00:00:47

标签: java jframe jpanel mouselistener

基本上,我想制作一个包含鼠标监听器的矩形,用于我的tic tac toe游戏。我打算将它们放在行之间作为鼠标听众。我已经设置了一个JFrame,剩下的就是我添加矩形。我该怎么做呢?到目前为止,这是我的代码:

public class TicTacToe extends JFrame{
public static void main(String[] args) {
    // TODO Auto-generated method stub
    new TicTacToe();
}

public TicTacToe(){
    //Sets up the frame
    this.setTitle("Tic Tac Toe");
    this.setPreferredSize(new Dimension(500,500));
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.pack();
    this.setVisible(true);

}

public void paint(Graphics g){
    //This just creates the lines for my tic tac toe game. 
    g.clearRect(0, 0, getWidth(), getHeight());
    g.setColor(Color.black);
    Graphics2D g2 = (Graphics2D) g;
    g2.setStroke(new BasicStroke(10));
    //Vertical
    g2.drawLine(this.getWidth()/3, this.getHeight()/10, this.getWidth()/3, this.getHeight()-this.getHeight()/10);
    g2.drawLine(2*(this.getWidth()/3), this.getHeight()/10, 2*(this.getWidth()/3), this.getHeight()-this.getHeight()/10);
    //Horizontal
    g2.drawLine(this.getWidth()/25,this.getWidth()/3,this.getHeight()-this.getHeight()/25,this.getWidth()/3);
    g2.drawLine(this.getWidth()/25,(this.getWidth()/3)*2,this.getHeight()-this.getHeight()/25,(this.getWidth()/3)*2);
    validate();

}

1 个答案:

答案 0 :(得分:0)

你可以使用你的绘画算法作为检查MouseEvent是否在给定区域内的基础,但这会变得很难维护

相反,您可以利用Graphics2D形状API,这样您就可以定义虚拟区域并只使用它的contains功能来测试MouseEvent是否属于其中一个领域

Highlight

(ps-你的线条图代码有点偏斜)

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TicTacToeDemo {

    public static void main(String[] args) {
        new TicTacToeDemo();
    }

    public TicTacToeDemo() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private List<Rectangle> quads;
        private Rectangle selected;

        public TestPane() {
            quads = new ArrayList<>(9);
            MouseAdapter ma = new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent e) {
                    selected = null;
                    for (Rectangle cell : quads) {
                        if (cell.contains(e.getPoint())) {
                            selected = cell;
                            break;
                        }
                    }
                    repaint();
                }
            };
            addMouseMotionListener(ma);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        public void invalidate() {
            // When ever the size of the container changes, we
            // need to revalidate the rectangles based on the new size
            // of the container
            super.invalidate();
            quads.clear();
            int width = getWidth();
            int height = getHeight();
            if (width != 0 && height != 0) {
                int vGap = getHeight() / 10;
                int hGap = getWidth() / 15;

                width -= hGap;
                height -= vGap;

                hGap /= 2;
                vGap /= 2;

                for (int xPos = 0; xPos < 3; xPos++) {
                    for (int yPos = 0; yPos < 3; yPos++) {
                        int x = hGap + (xPos * (width / 3));
                        int y = vGap + (yPos * (height / 3));
                        quads.add(new Rectangle(x, y, width / 3, height / 3));
                    }
                }
            }
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            if (selected != null) {
                g2d.setColor(new Color(0, 0, 255, 128));
                g2d.fill(selected);
            }

            g2d.setColor(Color.black);
            Graphics2D g2 = (Graphics2D) g2d;
            g2.setStroke(new BasicStroke(10));
            //Vertical
            g2.drawLine(this.getWidth() / 3, this.getHeight() / 10, this.getWidth() / 3, this.getHeight() - this.getHeight() / 10);
            g2.drawLine(2 * (this.getWidth() / 3), this.getHeight() / 10, 2 * (this.getWidth() / 3), this.getHeight() - this.getHeight() / 10);
            //Horizontal
            g2.drawLine(this.getWidth() / 25, this.getHeight() / 3, this.getWidth() - this.getWidth() / 25, this.getHeight() / 3);
            g2.drawLine(this.getWidth() / 25, (this.getHeight() / 3) * 2, this.getWidth() - this.getWidth() / 25, (this.getHeight() / 3) * 2);
            g2d.dispose();
        }

    }

}

有关详细信息,请查看2D GraphicsPerforming Custom PaintingPainting in AWT and Swing

您可能还想查看Why not to draw directly inside JFrameHow to get the EXACT middle of a screen, even when re-sizedJava AWT drawString() does not display on windowHow can I set in the midst?,了解为什么不应该覆盖paint的{​​{1}}顶级容器,如JFrame