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

标签 java swing

我有一个带有 JPanel 的 JFrame,它仅在我调整窗口大小时显示(使其变小仍会显示所有内容,因此不适合不是问题)。我尝试在添加所有内容后调用 revalidate() 和 validate() ,并确保设置 setVisible(true) ,但这似乎没有任何作用。

这是我的 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);
    }
}

这是我的 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);
    }



    }

}

最佳答案

你在paintComponent中做了太多的事情。切勿在那里读取图像,而是在开始时读取它们一次,例如在类的构造函数中。也不要在此方法中设置preferredSize 或设置背景。否则,您可能会面临阻碍方法覆盖的风险。此方法应该仅用于绘图和绘图,而不能用于其他用途。

例如,

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

更多:

我会使用类似的东西来阅读图像:

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

只有我将其作为 JAR 文件中的资源。

我还会为 JPanel 创建一个自定义布局,然后将我的片段 Sprite 放入 ImageIcons、JLabels 中,然后通过其自定义布局将它们移动到我的 JPanel 中。

关于java - JPanel 仅在调整窗口大小时显示(JFrame),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35399237/

相关文章:

java - 在 Java 中重新绘制 BufferedImage 不会更改面板的内容

java - 在 IntelliJ IDEA 2018.1 中运行 JUnit 5 测试时出错

java - 如何对一个对象(实际上是一个数组)进行排序

java - JFrame Repaint() 单个组件

java - 从 JXDatePicker 获取时间

java - JFrame打开很小

java - 在 Swing GUI 中提供空白

java - 使用 Spring 测试 Dao

java - Java 中查找 2 个集合的差异

java - 如何使用 Java Config 将文件从一个文件夹移动到远程 sftp 服务器上的另一个文件夹并动态提供文件名?