简体   繁体   English

JPanel仅在调整窗口大小(JFrame)时显示

[英]JPanel only displaying when I resize Window (JFrame)

I have a JFrame with a JPanel, that's only displaying when I resize my window(making it smaller still displays everything, so not fitting is not an issue). 我有一个带有JPanel的JFrame,仅当我调整窗口大小时才显示(使其变小仍会显示所有内容,因此不适合不是问题)。 I tried calling revalidate() and validate() after, and made sure to set setVisible(true) after adding everything, however this seemed to do nothing. 我尝试在之后调用revalidate()和validate(),并确保在添加所有内容后设置setVisible(true),但这似乎无济于事。

Here is my JFrame code (It's a monopoly game): 这是我的JFrame代码(这是一个垄断游戏):

public class BoardWindow extends JFrame
{

/** Constructor
 * 
 */
Board board;
public BoardWindow(Player[] players)
    {
    super("MONOPOLY GameBoard");

    setLayout(new FlowLayout());

    board = new Board(players);
    add(board);
    add(new JButton("Refresh"));
    setSize(900, 900);

    //setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
    }
}

Here is my JFrame code 这是我的JFrame代码

class Board extends JPanel {




public Player players[];

Board(Player[] players)
{
    this.players = players;
    setVisible(true)

}

@Override
public void paintComponent(Graphics g) 
    {
    super.paintComponent(g);

    setPreferredSize(new Dimension(800, 800));

    ImageIcon boardPic = new ImageIcon("images/board.png");

    boardPic.paintIcon(this, g, 0, 0);

    setBackground(Color.WHITE);

    int x = 0;
    int y = 0;

    for(Player i: this.players) 
    {
        g.setColor(i.getColor());
        int position = i.getGamePosition();


        if(position == 0)
        {
            x = 25;
            y = 700;
        }
        else if (position > 0 && position < 9)
        {
            x = 25;
            y = ((10-position)*63)+31;
        }
        else if (position == 9)
        {
            x = 25;
            y = 25;
        }
        else if (position > 9 && position < 18)
        {
            y = 25;
            x = ((position-9)*63)+98;
        }
        else if(position == 18)
        {
            x = 750;
            y = 10;
        }
        else if(position > 18 && position < 27)
        {
            x = 745;
            y = ((position-18)*63)+95;
        }
        else if (position == 27)
        {
            x = 750;
            y = 660;
        }
        else if(position > 27)
        {
            x = ((20-position)*63)+1105; 
            y= 700;
        }


        g.fillRect(x, y, 40, 40);
    }



    }

}

You're doing much too much within paintComponent. 您在paintComponent中做了太多事情。 Never read in images there, and instead read them in once at the start, such as in your class's constructor. 永远不要在其中读入图像,而应该在一开始就读入它们,例如在类的构造函数中。 Don't set preferredSize or set background from within this method either. 也不要在此方法内设置preferredSize或设置背景。 Else you risk hamstringing your method override. 否则,您可能会陷入束缚方法覆盖的风险。 This method should be for drawing and drawing only and nothing else. 此方法应仅用于绘制和绘制,而不能用于其他任何事情。

eg, 例如,

class Board extends JPanel {
    public Player players[];
    private BufferedImage boardPic; // use a BufferedImage

    Board(Player[] players) {
        this.players = players;
        setPreferredSize(new Dimension(800, 800));
        setBackground(Color.WHITE);

        // much better to use resources and not files
        // you'll need to handle an exception here.
        boardPic = new ImageIO.read(new File("images/board.png"));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(boardPic, 0, 0, this);

        int x = 0;
        int y = 0;
        for(Player i: this.players) {
            g.setColor(i.getColor());
            int position = i.getGamePosition();

            if(position == 0) {
                x = 25;
                y = 700;
            }  else if (position > 0 && position < 9)  {
                x = 25;
                y = ((10-position)*63)+31;
            }  else if (position == 9)  {
                x = 25;
                y = 25;
            } else if (position > 9 && position < 18) {
                y = 25;
                x = ((position-9)*63)+98;
            } else if(position == 18) {
                x = 750;
                y = 10;
            } else if(position > 18 && position < 27) {
                x = 745;
                y = ((position-18)*63)+95;
            } else if (position == 27) {
                x = 750;
                y = 660;
            } else if(position > 27) {
                x = ((20-position)*63)+1105; 
                y= 700;
            }
            g.fillRect(x, y, 40, 40);
        }
    }
}

More: 更多:

I would read the image in using something similar to this: 我将使用类似以下内容来读取图像:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;

public class MyMonopoly extends JPanel {
    private static final String IMG_PATH = "http://dl.gamesradar.com/photos/gameopoly/monopoly_original.jpg";
    private static final int PREF_W = 900;
    private static final int PREF_H = PREF_W;
    private BufferedImage board = null;

    public MyMonopoly() throws IOException {
        URL url = new URL(IMG_PATH);
        board = ImageIO.read(url);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (board != null) {
            g.drawImage(board, 0, 0, getWidth(), getHeight(), this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private static void createAndShowGui() {
        MyMonopoly mainPanel = null;
        try {
            mainPanel = new MyMonopoly();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        JFrame frame = new JFrame("My Monopoly");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            createAndShowGui();
        });
    }
}

Only I'd have it as a resource in my JAR file. 只有我将其作为资源保存在JAR文件中。

I would also create a custom layout for the JPanel and then place my piece sprites into ImageIcons, those into JLabels and then move them into my JPanel by way of its custom layout. 我还将为JPanel创建一个自定义布局,然后将我的块精灵放置到ImageIcons中,将它们放置到JLabel中,然后通过其自定义布局将它们移动到我的JPanel中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM