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?
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.
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...
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)
来源:https://stackoverflow.com/questions/31039667/java-painting-not-working