0

So I have this code:

package tictactoe;

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TicTacToe extends JFrame {

public static void main(String[] args) {
    JFrame masterFrame = new JFrame("TicTacToe");
    JPanel drawingPanel = new JPanel();
    GameBoard theGame = new GameBoard();

    masterFrame.add(drawingPanel);
    masterFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    masterFrame.setSize(504, 504);
    masterFrame.setResizable(false);
    masterFrame.setLocationRelativeTo(null);
    masterFrame.setVisible(true);
} //End of Main method


@Override
public void paint (Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    //Drawing the GridLines
    g2.drawLine(168, 0, 168, 500);
    g2.drawLine(336, 0, 336, 500);
    g2.drawLine(0, 168, 500, 168);
    g2.drawLine(0, 336, 500, 336);
} //End of Paint Method
} //End of TicTacToe Class    

What I would like it to do is draw 4 lines onto my JFrame in a TicTacToe fashion, but the JFrame remains blank. Why is this? What is wrong with my code and how should I fix it?

Avi Caspe
  • 537
  • 4
  • 12
  • Your `drawingPane` is painting over what ever you've painted using the `paint` method – MadProgrammer Jun 25 '15 at 01:23
  • 1
    Your code never creates an instance of the class TicTacToe, so that class's paint method is never invoked. – VGR Jun 25 '15 at 01:25
  • @MadProgrammer, I tried commenting out the parts where I added the drawing panel and it's still not working. – Avi Caspe Jun 25 '15 at 01:28
  • @VGR, I don't want to make a instance of this class, I feel it would just take up space in the memory. It was my impression that the paint method was called when you did `panel.setVisible(true)` Is that not the case? – Avi Caspe Jun 25 '15 at 01:30
  • @AviCaspe Only a component which is attached to a displayable component (a window which is visible on the screen) can be painted, since you've not created an instance of `TicTacToe` how could ever possibly be painted – MadProgrammer Jun 25 '15 at 01:35

1 Answers1

1

Had you actually created an instance of TicTacToe, instead of JFrame, your DrawingPane would likely be painting over/covering what ever your frame is painting via it's paint method.

// Create an instance of TicTacToe instead of JFrame...
//JFrame masterFrame = new JFrame("TicTacToe");
TicTacToe masterFrame = new TicTacToe();

A child component can be painted without notifying or requiring it's parent container to be painted, meaning that the child components will actually cover up what has previously been painted by the frame, this can produce some very weird results, as different parts get updated

A JFrame contains a number of child components, including the JRootPane and the contentPane, onto which you place your own components.

RootPane

A better solution in your case is probably to use your DrawingPane and customise it's paintComponent to render the grid

See Painting in AWT and Swing and Performing Custom Painting for more details

For example...

TicTacToe

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TicTacToe {

    public static void main(String[] args) {
        new TicTacToe();
    } //End of Main method

    public TicTacToe() {
        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("Tic Tac Toe");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TicTacToePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TicTacToePane extends JPanel {

        public TicTacToePane() {
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            //Drawing the GridLines
            g2d.drawLine(168, 0, 168, 500);
            g2d.drawLine(336, 0, 336, 500);
            g2d.drawLine(0, 168, 500, 168);
            g2d.drawLine(0, 336, 500, 336);
            g2d.dispose();
        }

    }

} //End of TicTacToe Class    

As a general rule, it's recommended not to extend directly from JFrame, apart from the custom painting issues you're having, you're not adding any functionality to the class and you're locking yourself into a single use case (it'd be hard to re-use the class again)

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • What's up with the try catch block? – Avi Caspe Jun 25 '15 at 02:10
  • Also, How would you go about adding second panel next to this one? – Avi Caspe Jun 25 '15 at 02:11
  • @AviCaspe Around `UIManager.setLookAndFeel`? I have a pathological hatred of Meta (the default look and feel), so I prefer to use the system look and feel (Windows in the screen shoot), but the API is suppose to allow you to load look and feels from different sources, so it throws a bunch of exceptions, which, generally speaking, I don't care about (in this case). Have a look at [Modifying the Look and Feel](http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/index.html) for more details – MadProgrammer Jun 25 '15 at 02:13
  • *"How would you go about adding second panel next to this one?"* Since the frame is using `BorderLayout`, you can place components to the `EAST` or `WEST` of the `CENTER` (default) position. See [How to Use BorderLayout](https://docs.oracle.com/javase/tutorial/uiswing/layout/border.html) for more details – MadProgrammer Jun 25 '15 at 02:14
  • Also, are you sure your example is compile-able? I can't seem to get netbeans to like my your code – Avi Caspe Jun 25 '15 at 02:15
  • @AviCaspe Written, compiled and executed in Netbeans (from which I got the screen shot). Just copy and pasted into a new Netbeans project and it compiled and run fine. Which JRE are you using (I'm using 8, but it should work for 7)? – MadProgrammer Jun 25 '15 at 02:15
  • Well I accidentally put the import declarations in two separate spots – Avi Caspe Jun 25 '15 at 02:19
  • Why is the constructor for the TicTacToePane blank? Not only that, but HOW? How does the program know that it is a JPanel? Nowhere do you actually create a new JPanel. – Avi Caspe Jun 25 '15 at 02:27
  • *"Why is the constructor for the TicTacToePane blank?"* - Why not? What other information does it need? *"but HOW? How does the program know that it is a JPanel?" - Because it extends `JPanel`; *"Nowhere do you actually create a new JPanel"* - No, I create an instance of `TicTacToePane` instead, otherwise, it'd be pointless – MadProgrammer Jun 25 '15 at 02:32