0

Basically, I want to make a rectangle that contains a mouse listener for my tic tac toe game. I intend to place them in between the lines to serve as mouse listeners. I have already set up a JFrame, all that is left is for me to add the rectangle. How would I go about doing this? Here is my code so far:

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

}
Leonard Parisi
  • 200
  • 1
  • 3
  • 12
  • You basic idea is slightly off (not to mention your implementation). The `Graphics2D` API has a shapes library, which can be used to perform, among other things, collision detection (ie `contains(Point)`), this is what you would use for your requirements. – MadProgrammer Dec 04 '15 at 00:03
  • Also, have a look at [Performing Custom Painting](http://docs.oracle.com/javase/tutorial/uiswing/painting/) and [Painting in AWT and Swing](http://www.oracle.com/technetwork/java/painting-140037.html) for more details about how painting works in Swing. Also, your line drawing logic is wrong – MadProgrammer Dec 04 '15 at 00:07

1 Answers1

1

You could just use your painting algorithm as a bases for checking if the MouseEvent is within a given area, but this becomes a mess to maintain

Instead, you could take advantage of Graphics2D shape API, which would allow you to define virtual areas and simply use it's contains functionality to test if the MouseEvent falls within one of those areas

Highlight

(ps- You're line drawing code is a little skewed)

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

    }

}

Have a look at 2D Graphics, Performing Custom Painting and Painting in AWT and Swing for more details

You might also want to have a look at Why not to draw directly inside JFrame, How to get the EXACT middle of a screen, even when re-sized, Java AWT drawString() does not display on window and How can I set in the midst? for reasons why you shouldn't override paint of a top level container like JFrame

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366