问题
I'm trying to develop a Tic Tac Toe game in Java using Graphics. My problem is: I don't want to add any other methods inside my Grid.class (which draws the lines 3x3), but i want to draw my X or O from a class called Game. My grid class looks like the following:
import java.awt.Graphics;
import javax.swing.JPanel;
public class Grid extends JPanel{
private final int ITEM_WIDTH = 30;
private final int ITEM_HEIGHT = 30;
private final int OUTER_WIDTH = 90;
private final int OUTER_HEIGHT = 90;
public void paintComponent(Graphics g){
super.paintComponent(g);
drawOuter(g);
drawGrid(g);
}
public void drawOuter(Graphics g){
g.drawRect(0, 0, OUTER_WIDTH, OUTER_HEIGHT);
}
public void drawGrid(Graphics g){
//Vertikális
for(int i = ITEM_WIDTH; i < OUTER_WIDTH; i += ITEM_WIDTH){
g.drawLine(i, 0, i, OUTER_HEIGHT);
}
//Horizontális
for(int i = ITEM_HEIGHT; i < OUTER_HEIGHT; i += ITEM_HEIGHT){
g.drawLine(0, i, OUTER_WIDTH, i);
}
}
Thank you for your helps
回答1:
My suggestion would be try to keep things as simple as possible.
- Create ImageIcons that hold your X and O images
- Have a GridLayout of JLabels placed in your JPanel above.
- Swapping the JLabel's ImageIcon when I wanted to display an X, an O, or a blank.
Proof of concept code. Clicking on the JLabels several times will show the icons. The code has no Tic-Tac-Toe logic though:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class XorOorBlank extends JPanel {
private static final int IMG_WIDTH = 100;
private static final Color BACKGROUND = Color.LIGHT_GRAY;
private static final Color X_COLOR = Color.red;
private static final Color O_COLOR = Color.blue;
private static final Stroke X_STROKE = new BasicStroke(8f);
private static final int GAP = 8;
private static final int SIDE = 3;
private Icon blankIcon = createBlankIcon();
private Icon xIcon = createXIcon();
private Icon oIcon = createOIcon();
public XorOorBlank() {
setBackground(BACKGROUND);
setLayout(new GridLayout(SIDE, SIDE, GAP, GAP));
MouseListener mouseListener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
JLabel label = (JLabel) e.getSource();
Icon icon = label.getIcon();
if (icon == blankIcon) {
icon = xIcon;
} else if (icon == xIcon) {
icon = oIcon;
} else if (icon == oIcon) {
icon = blankIcon;
}
label.setIcon(icon);
}
};
for (int i = 0; i < SIDE; i++) {
for (int j = 0; j < SIDE; j++) {
JLabel label = new JLabel(blankIcon);
label.addMouseListener(mouseListener);
add(label);
}
}
}
private Icon createBlankIcon() {
BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_WIDTH,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setColor(Color.white);
g2.fillRect(0, 0, IMG_WIDTH, IMG_WIDTH);
g2.dispose();
ImageIcon icon = new ImageIcon(img);
return icon;
}
private Icon createXIcon() {
BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_WIDTH,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setColor(Color.white);
g2.fillRect(0, 0, IMG_WIDTH, IMG_WIDTH);
g2.setColor(X_COLOR);
g2.setStroke(X_STROKE);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int x1 = GAP;
int y1 = x1;
int x2 = IMG_WIDTH - GAP;
int y2 = x2;
g2.drawLine(x1, y1, x2, y2);
g2.drawLine(x2, y1, x1, y2);
g2.dispose();
ImageIcon icon = new ImageIcon(img);
return icon;
}
private Icon createOIcon() {
BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_WIDTH,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setColor(Color.white);
g2.fillRect(0, 0, IMG_WIDTH, IMG_WIDTH);
g2.setColor(O_COLOR);
g2.setStroke(X_STROKE);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int x1 = GAP;
int y1 = x1;
int x2 = IMG_WIDTH - 2 * GAP;
int y2 = x2;
g2.drawOval(x1, y1, x2, y2);
g2.dispose();
ImageIcon icon = new ImageIcon(img);
return icon;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("X or O");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new XorOorBlank());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Note: not a paintComponent method to be found.
This displays:
回答2:
You have a few choices...
You Could
Extend from Grid
, overriding it's paintComponent
method and draw the X
/O
s within it (calling super.paintComponent
)
You Could
Create a interface
which provide a simple "draw" method, which when implemented, would paint either X
/O
. You could then simply add an new instance of this to the Grid
class and have it paint the X
/O
via some kind of loop within the paintComponent
method
You Could
Use, something like GridBagLayout
or even OverlayLayout
and place another panel over the top of the Grid
class, or, using BorderLayout
, add the panel directly to the Grid
class, which would then be responsible for painting the X
/O
You Could
Do what Hovercraft Full Of Eels has suggested...
来源:https://stackoverflow.com/questions/20646113/java-drawing-using-graphics-outside-the-class-which-draws-the-main-canvas