Java JPanel中的图形问题,但它在框架中工作

Ada*_*man 1 java swing jpanel tic-tac-toe

我是新手,我正在使用Cay Hortsmann的Big Java来学习.对于其中一个早期项目,我正在制作一个带有GUI的井字游戏,但是我无法让棋盘出现在JPanel上.它只在框架中显示正常,但由于我想添加按钮,我尝试将板放在JPanel中,然后将JPanel添加到框架中.不幸的是,这不起作用.我很感激你能给出的任何反馈:

import javax.swing.JFrame;
import javax.swing.JPanel;



public class TicTacToePlayer {

    private static final int FRAME_WIDTH = 400;
    private static final int FRAME_HEIGHT = 400;

    private int count = 0;

    public static void main(String[] args) {

        final JFrame frame = new JFrame();

        // create board
        final LinesComponent boardLines = new LinesComponent();     
        JPanel panel = new JPanel();
        panel.add(boardLines);
        frame.add(panel);
        frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }

}
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JComponent;


public class LinesComponent extends JComponent {
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;

        Lines boardLines = new Lines();
        boardLines.draw(g2);
    }

}
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;

import javax.swing.JComponent;


public class Lines extends JComponent {
    public Lines() {
        setPreferredSize(new Dimension(400, 400));

    }

    public void draw(Graphics2D g2) {
        Line2D.Double leftVertLine = new Line2D.Double(150, 50, 150, 350);
        Line2D.Double rightVertLine = new Line2D.Double(250, 50, 250, 350);
        Line2D.Double topHorizLine = new Line2D.Double(50, 150, 350, 150);
        Line2D.Double bottomHorizLine = new Line2D.Double(50, 250, 350, 250);
        g2.draw(leftVertLine);
        g2.draw(rightVertLine);
        g2.draw(topHorizLine);
        g2.draw(bottomHorizLine);
    }
}
Run Code Online (Sandbox Code Playgroud)

Mad*_*mer 5

让我们从明显的......开始

  • JPanel使用a FlowLayoutpreferredSize表示添加到其中的组件. JComponent具有默认大小0x0,这意味着当您添加boardLines到它时,它有效地变得不可见并且从不绘制.您可以通过使用创建该BorderLayoutpanel,例如JPanel panel = new JPanel(new BorderLayout());
  • 虽然从技术上讲不是必需的,但super.paintComponent在执行自定义绘画时调用它总是很好的
  • 您不应该在其中创建短期对象paintComponent,尤其是当状态不以任何方式更改时(也就是说,创建新实例的结果与您创建的上一个实例的结果相同). paintComponent可以在短时间内重复调用,这可能会给您的系统带来不必要的压力
  • Lines不需要延伸JComponent,严重来说,它只是没有做任何事......
  • 使用pack,而不是setSizeJFrame,就会使生活变得更加简单...
  • 应该在Event Dispatching Thread的上下文中创建和操作Swing UI

举个例子:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TicTacToePlayer {

    private static final int FRAME_WIDTH = 400;
    private static final int FRAME_HEIGHT = 400;

    private int count = 0;

    public static void main(String[] args) {
        new TicTacToePlayer();
    }

    public TicTacToePlayer() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                final JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                // create board
                final LinesComponent boardLines = new LinesComponent();
                JPanel panel = new JPanel(new BorderLayout());
                panel.add(boardLines);
                frame.add(panel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class LinesComponent extends JComponent {

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            draw(g2);
        }

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

        public void draw(Graphics2D g2) {
            Line2D.Double leftVertLine = new Line2D.Double(150, 50, 150, 350);
            Line2D.Double rightVertLine = new Line2D.Double(250, 50, 250, 350);
            Line2D.Double topHorizLine = new Line2D.Double(50, 150, 350, 150);
            Line2D.Double bottomHorizLine = new Line2D.Double(50, 250, 350, 250);
            g2.draw(leftVertLine);
            g2.draw(rightVertLine);
            g2.draw(topHorizLine);
            g2.draw(bottomHorizLine);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您应该考虑查看" 执行自定义绘画"以获取更多详细信息