【问题标题】:Java: Drawing using Graphics outside the class which draws the main canvasJava:在绘制主画布的类之外使用 Graphics 进行绘制
【发布时间】:2013-12-18 08:26:02
【问题描述】:

我正在尝试使用图形在 Java 中开发井字游戏。 我的问题是:我不想在我的 Grid.class 中添加任何其他方法(绘制线 3x3),但我想从名为 Game 的类中绘制我的 X 或 O。我的网格类如下所示:

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

感谢您的帮助

【问题讨论】:

    标签: java swing graphics tic-tac-toe


    【解决方案1】:

    我的建议是尽量让事情尽可能简单。

    • 创建包含 X 和 O 图像的 ImageIcons
    • 在上面的 JPanel 中放置一个 JLabels 的 GridLayout。
    • 当我想显示 X、O 或空白时交换 JLabel 的 ImageIcon。

    概念验证代码。多次单击 JLabels 将显示图标。该代码虽然没有井字游戏逻辑:

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

    注意:不是paintComponent方法。

    这显示:

    【讨论】:

    • 我期待这样的答案,但如果我能这样做,感觉会很好
    • 只为体验你懂的
    【解决方案2】:

    你有几个选择...

    你可以

    Grid 扩展,覆盖它的paintComponent 方法并在其中绘制X/Os(调用super.paintComponent

    你可以

    创建一个interface,它提供了一个简单的“绘制”方法,当实现该方法时,将绘制X/O。然后,您可以简单地将 this 的新实例添加到 Grid 类,并让它通过 paintComponent 方法中的某种循环绘制 X/O

    你可以

    使用GridBagLayout 甚至OverlayLayout 之类的东西并将另一个面板放在Grid 类的顶部,或者,使用BorderLayout,将面板直接添加到Grid 类,然后负责画X/O

    你可以

    按照 Hovercraft Full Of Eels 的建议去做...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多