Java 除非JFrame.validate(),否则JPanel JComponents不会重新绘制;在将组件添加到可视框架后调用

Java 除非JFrame.validate(),否则JPanel JComponents不会重新绘制;在将组件添加到可视框架后调用,java,image,swing,jframe,Java,Image,Swing,Jframe,Frame->MainContentPane->MapPanel->Map->Tile[] JFrame->JPanel(新网格布局)->JPanel->JPanel(新网格布局(31,30)->JComponent 我试图在JPanel上绘制32x32像素的瓷砖,但无论我在哪里调用repaint();它都只会在JFrame上调用validate();时绘制瓷砖。 如果我绕过面板并直接(使用draw()方法)在MapPanel上绘制图像,则只有在我调整或移动JFrame时,图像才会绘制,因此帧必

Frame
->
MainContentPane
->
MapPanel
->
Map
->
Tile[]

JFrame
->
JPanel(新网格布局)
->
JPanel
->
JPanel(新网格布局(31,30)
->
JComponent

我试图在JPanel上绘制32x32像素的瓷砖,但无论我在哪里调用repaint();它都只会在JFrame上调用validate();时绘制瓷砖。 如果我绕过面板并直接(使用draw()方法)在
MapPanel
上绘制图像,则只有在我调整或移动
JFrame
时,图像才会绘制,因此帧必须由
repaintmanager
重新绘制。但是调用
repaint()
validate()
或我的
内容面板上的两者都将不会绘制图像

如果我理解Java.swing是如何正确绘制的,那么如果我在最高级别组件上调用重新绘制,它应该重新绘制
repaitmanager
认为应该重新绘制的所有子组件
在最高级别组件上告诉
重新绘制管理器
有新事物。我的理解正确吗

不起作用的事情:

告诉我在将框架设置为可见之前添加所有组件。
Map
Tile[]
将定期更改,每次添加/删除某些内容时重置框架是非常不切实际的

public class NetScore {

    public static void main(String[] args) {
        MapPanel mapPanel = new MapPanel();
        InfoPanel infoPanel = new InfoPanel();
        ImageLoader imageLoader = new ImageLoader();

        Player player = new Player("Tester", imageLoader);

        JPanel contentPane = new MainContentPane((JPanel)mapPanel, (JPanel)infoPanel);

        System.out.println(mapPanel.getHeight());
        System.out.println(mapPanel.getWidth());

        MapBuilder mapBuilder = new MapBuilder(player, imageLoader);

        Map map = new Map(mapBuilder, mapPanel, player);
        map.drawMap();

        System.out.println();
    }

    }
public class MapPanel extends JPanel implements ActionListener{

    Map map;
    Timer clock;
    public MapPanel(){
        clock = new Timer(500, this);
        clock.start();

    }

    public void addMap(Map map){
        this.map = map;
        this.add(map);
        this.validate();
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        System.out.println(map == null);
        System.out.println("paint mapPanel");
        Graphics2D g2 = (Graphics2D) g;
        if(map == null){
            //map.draw(g2);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //repaint();

    }
    }
public class MainContentPane extends JPanel implements ActionListener{

    public JFrame frame;
    Timer clock;

    public MainContentPane(JPanel mapPanel ,JPanel infoPanel){
        clock = new Timer(500, this);
        clock.start();
        frame = new Frame();
        JPanel contentPane = new JPanel();
        frame.setContentPane(contentPane);
        contentPane.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();

        c.weightx = 2;
        c.gridx = 0;
        c.gridy = 0;
        c.fill = GridBagConstraints.BOTH;
        contentPane.add(mapPanel, c);

        c.weightx = 1;
        c.weighty = 1;
        c.gridx = 1;
        c.gridy = 0;
        c.fill = GridBagConstraints.BOTH;


        contentPane.add(infoPanel, c);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();

    }

    class Frame extends JFrame{

        public Frame(){
            this.setTitle("netScore");
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            this.setBounds(100, 10, 1500, 1000);
            this.setResizable(false);
        }

    }
    }
public class Map extends JPanel{


    private Tile[][] tiles;
    private MapBuilder mapBuilder;
    private Player player;


    public Map(MapBuilder mapBuilder, MapPanel mapPanel, Player player){
        this.player = player;
        this.mapBuilder = mapBuilder;
        this.setLayout(new GridLayout(31,30));
        mapPanel.addMap(this);
    }

    public void loadMap(){
        tiles = mapBuilder.buildMap();
    }

    public void drawMap(){
        loadMap();
        this.removeAll();
        for(int i = 0; i < tiles.length; i++){
            for(int p = 0; p < tiles[i].length; p++){
                this.add(tiles[i][p]);
            }
        }
        validate();
    }
    public void draw(Graphics2D g2){
        if(tiles != null){
            for(int i = 0; i < tiles.length; i++){
                for(int p = 0; p <tiles[i].length; p++){
                    tiles[i][p].draw(g2, i*32, p*32);
                }
            }
        }
    }

      //    private class GlassPanel extends JComponent{
      //        
      //        
      //        @Override
      //        protected void paintComponent(Graphics g) {
      //            super.paintComponent(g);
      //            Graphics2D g2 = (Graphics2D) g;
      //            g2.drawImage(player.getImage(), player.getX(), player.getY(), null);
      //            
      //        }
      //        
      //    }
      }
public class Tile extends JComponent{

    private int id;
    private boolean collision;
    private BufferedImage image;

    public Tile(char diCo, int id, ImageLoader imageLoader){
        this.id = id;

        collision = (Character.isUpperCase(diCo));
        image = imageLoader.getTileImage(id, diCo); 
        setPreferredSize(new Dimension(32, 32));
    }

     // public Dimension getPreferredSize(){
     //     return new Dimension(32,32);
     // }

    public boolean isCollision() {
        return collision;
    }

    public void draw(Graphics2D g2, int x, int y){
        System.out.println("paint tile, id "+ id);
        g2.drawImage(image, null, x, y);
    }

    public void paintComponent(Graphics g){
        System.out.println("paint tile, id "+ id);
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(image, null, 0, 0);
    }
}
公共类NetScore{
公共静态void main(字符串[]args){
MapPanel MapPanel=新建MapPanel();
InfoPanel InfoPanel=新建InfoPanel();
ImageLoader ImageLoader=新的ImageLoader();
玩家=新玩家(“测试者”,图像加载器);
JPanel contentPane=新的主contentPane((JPanel)映射面板,(JPanel)infoPanel);
System.out.println(mapPanel.getHeight());
System.out.println(mapPanel.getWidth());
MapBuilder MapBuilder=新的MapBuilder(播放器、图像加载器);
地图地图=新地图(地图生成器、地图面板、播放器);
drawMap();
System.out.println();
}
}
公共类MapPanel扩展JPanel实现ActionListener{
地图;
定时器时钟;
公共地图面板(){
时钟=新定时器(500,此);
clock.start();
}
公共无效添加映射(映射映射){
this.map=map;
这个。添加(地图);
这个。validate();
}
公共组件(图形g){
超级组件(g);
System.out.println(map==null);
System.out.println(“绘制地图面板”);
图形2d g2=(图形2d)g;
if(map==null){
//地图绘制(g2);
}
}
@凌驾
已执行的公共无效操作(操作事件e){
//重新油漆();
}
}
公共类MainContentPane扩展JPanel实现ActionListener{
公共框架;
定时器时钟;
公共主内容窗格(JPanel mapPanel、JPanel infoPanel){
时钟=新定时器(500,此);
clock.start();
帧=新帧();
JPanel contentPane=新的JPanel();
frame.setContentPane(contentPane);
setLayout(新的GridBagLayout());
GridBagConstraints c=新的GridBagConstraints();
c、 权重x=2;
c、 gridx=0;
c、 gridy=0;
c、 fill=GridBagConstraints.BOTH;
添加(mapPanel,c);
c、 权重x=1;
c、 权重=1;
c、 gridx=1;
c、 gridy=0;
c、 fill=GridBagConstraints.BOTH;
contentPane.add(infoPanel,c);
frame.setVisible(true);
}
@凌驾
已执行的公共无效操作(操作事件e){
重新油漆();
}
类框架扩展了JFrame{
公共框架(){
本文件为.setTitle(“netScore”);
此.setDefaultCloseOperation(关闭时退出);
这个.挫折(100,10,1500,1000);
此参数为.setresizeable(false);
}
}
}
公共类映射扩展了JPanel{
私人瓷砖[][]瓷砖;
私有地图生成器;
私人玩家;
公共地图(地图生成器、地图生成器、地图面板、播放器){
this.player=player;
this.mapBuilder=mapBuilder;
这个.setLayout(新的GridLayout(31,30));
mapPanel.addMap(此);
}
公共void loadMap(){
tiles=mapBuilder.buildMap();
}
公共地图(){
loadMap();
这个。removeAll();
对于(int i=0;i对于(int p=0;p发布的代码的基本问题是,
JFrame
在添加组件之前设置为可见。虽然有一些方法可以添加组件,并在顶级容器变为可见后使其可见,但在这种情况下,它们似乎是不必要的

这是一个工作版本,它使用在运行时生成的图像,在
GridLayout
中有一点空间来显示网格是31 x 30个组件

import java.awt.*;
导入java.awt.event.*;
导入java.awt.image.buffereImage;
导入javax.swing.*;
公共类TestRepain{
公共静态void main(字符串[]args)引发异常{
MapPanel MapPanel=新建MapPanel();
Map Map=newmap();
添加(地图);
loadMap();
新的ContentPanel((JPanel)映射面板);
}
}
类MapPanel扩展了JPanel{
公共地图面板(){
这个.挫折背景(颜色.红色);
}
}
类映射扩展了JPanel{
缓冲图像;
公众的
public class test {
    public static void main(String[] args) throws Exception {

    MapPanel mapPanel = new MapPanel();
    ContentPanel contentPanel = new ContentPanel((JPanel)mapPanel);
    Map map = new Map();
    mapPanel.add(map);
    map.loadMap();

    }
}
class MapPanel extends JPanel{
    public MapPanel(){
    //this.setBackground(Color.BLACK);

    }
}

class Map extends JPanel{
   BufferedImage image;
   public Map(){
        try {
            image = ImageIO.read(new File("graphics//brick_brown0.png"));
        } catch (IOException e) {
            System.err.println("can't find file.");
        }
    setLayout(new GridLayout(31,30));
    setPreferredSize(new Dimension(962,992));
}
public void loadMap(){
    for(int i = 0; i < 30; i++){
        for(int p = 0; p < 31; p++){
            add(new Tile(image));
        }
    }
    validate();
}
}

class Tile extends JComponent{

BufferedImage image;
public Tile(BufferedImage image){
    this.image = image;
    setPreferredSize(new Dimension(32,32));
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.drawImage(image, null, null);
}
}


class ContentPanel extends JPanel implements ActionListener{
Timer clock = new Timer(100, this);

public ContentPanel(JPanel mapPanel){
    clock.start();
    setLayout(new BorderLayout());
    JFrame frame = new Frame();
    frame.setContentPane(this);
    add(mapPanel);
    frame.setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e) {
    repaint();
}

private class Frame extends JFrame{ 
    public Frame(){
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setBounds(100, 100, 1000, 1000);
    }
}
}
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class TestRepaint {

    public static void main(String[] args) throws Exception {

        MapPanel mapPanel = new MapPanel();
        Map map = new Map();
        mapPanel.add(map);
        map.loadMap();
        new ContentPanel((JPanel) mapPanel);
    }
}

class MapPanel extends JPanel {

    public MapPanel() {
        this.setBackground(Color.RED);
    }
}

class Map extends JPanel {

    BufferedImage image;

    public Map() {
        image = new BufferedImage(10, 10, BufferedImage.TYPE_INT_BGR);
        setLayout(new GridLayout(31, 30,2,2));
        //setPreferredSize(new Dimension(962, 992));
    }

    public void loadMap() {
        for (int i = 0; i < 30; i++) {
            for (int p = 0; p < 31; p++) {
                add(new Tile(image));
            }
        }
        validate();
    }
}

class Tile extends JComponent {

    BufferedImage image;

    public Tile(BufferedImage image) {
        this.image = image;
        setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(image, null, null);
    }
}

class ContentPanel extends JPanel implements ActionListener {

    Timer clock = new Timer(100, this);

    public ContentPanel(JPanel mapPanel) {
        clock.start();
        setLayout(new BorderLayout());
        JFrame frame = new Frame();
        frame.setContentPane(this);
        add(mapPanel);
        frame.pack();
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();
    }

    private class Frame extends JFrame {

        public Frame() {
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            //setBounds(100, 100, 1000, 1000);
        }
    }
}