本文介绍了paintComponent中的图像仅在调整窗口大小后显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 paintComponent(Graphics g)使用for循环绘制一些图像。但是,JFrame只显示为白色屏幕,它仅在我调整窗口大小后显示黑色背景和图像。

I want to use paintComponent(Graphics g) to paint a few images using a for loop. However, the JFrame just shows up as a white screen, and it only shows the black background and the images after I resize the window.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.imageio.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.util.Scanner;

 public class SimpleAdventure {
         private JFrame frame;
         private CardLayout cards;
         private Container c;
         private DrawPanel1 gamepanel;
         private BufferedImage greentiles, pinktiles, sandtiles, charsprites;
         private Image left1, right1, left2, right2, front;
         private Image pinkbg, greenbg, sandbg;
         private Image pinktop, greentop, sandtop;
         private int charx, chary;

         public SimpleAdventure()
         {}
         public static void main (String [] args)
         {
                 SimpleAdventure retro = new SimpleAdventure();
                 retro.run();
         }
         public void run()
         {
                 frame = new JFrame("Simple Adventure");
                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                 frame.setSize(576, 576);
                 frame.setVisible(true);
                 // frame.setResizable(false);
                 getImage();


                 c = frame.getContentPane();
                 cards = new CardLayout();
                 c.setLayout(cards);

                 gamepanel = new DrawPanel1();
                 gamepanel.setBackground(Color.black);
                 c.add(gamepanel, "Panel 1");
         }
         public void getImage()
         {

             try
             {
                 greentiles = ImageIO.read(new File("greenTiles.png"));
                 pinktiles = ImageIO.read(new File("pinkTiles.png"));
                 sandtiles = ImageIO.read(new File("sandTiles.png"));
                 charsprites = ImageIO.read(new File("charactersheet.png"));
             }
             catch(IOException e)
             {
                 e.printStackTrace();
             }


             left1 = charsprites.getSubimage(18, 0, 6, 6);
             left2 = charsprites.getSubimage(24, 0, 6, 6);
             right1 = charsprites.getSubimage(0, 0, 6, 6);
             right2 = charsprites.getSubimage(6, 0, 6, 6);
             front = charsprites.getSubimage(12, 0, 6, 6);

             greenbg = greentiles.getSubimage(240, 0, 16, 16);
             sandbg = sandtiles.getSubimage(240, 0, 16, 16);
             pinkbg = pinktiles.getSubimage(240, 0, 16, 16);

             greentop = greentiles.getSubimage(224, 0, 16, 16);
             sandtop = sandtiles.getSubimage(224, 0, 16, 16);
             pinktop = pinktiles.getSubimage(224, 0, 16, 16);
         }

         class DrawPanel1 extends JPanel implements KeyListener
         {
                 // private BottomPanel lower;
                 public DrawPanel1()
                 {
                     /*this.setLayout(new BorderLayout());
                     lower = new BottomPanel();
                     this.add(lower, BorderLayout.SOUTH);*/
                     addKeyListener(this);
                 }

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

                         for(int i = 0; i < 7; i++)
                         {
                             g.drawImage(greentop, 0 + (i * 96), 480, 96, 96, this);
                         }
                         System.out.println("check");
                 }
                 public void keyPressed(KeyEvent e)
                 {

                 }
                 public void keyReleased(KeyEvent e)
                 {

                 }
                 public void keyTyped(KeyEvent e)
                 {

                 }
         } }


推荐答案

你需要调用 frame.pack()来做初始布局。自动调整窗口大小会导致布局被修复,但 frame.setSize(...)不会*。

You need to call frame.pack() to do the initial layout. Resizing the window automatically causes the layout to be fixed, but frame.setSize(...) does not*.

frame.setVisible(true)移动到 run 方法的末尾(即在构建完所有方法之后) UI元素)并在 frame.setVisible(true)之前放置 frame.pack()。 (感谢Hovercraft和MadProgrammer指出这一点)

Move frame.setVisible(true) to the end of your run method (i.e. after you've constructed all the UI elements) and put frame.pack() just before frame.setVisible(true). (Thanks Hovercraft and MadProgrammer for pointing this out)

*至少,如果框架不可见则不会。如果框架已经可见,它可能会起作用;试试吧看看。

*At least, it doesn't if the frame is not visible. It might work if the frame is already visible; try it and see.

编辑:现在我重新阅读了javadoc,你可能不想要 pack 毕竟 - 它会为你调整框架的大小。如果不进行测试,我想最终将 setVisible 移动到底;如果没有,则使用 revalidate 而不是 pack 来运行布局引擎。

Now that I re-read the javadoc, you probably don't want pack after all - it will resize the frame for you. Without testing it, I guess that moving setVisible to the end will work; if it doesn't then use revalidate rather than pack to get the layout engine to run.

编辑2:现在我重新读取了javadoc, setVisible 将验证窗口是否尚未显示。因此,您不需要显式调用 revalidate setSize 使组件无效但不会重新验证

EDIT 2: Now that I re-re-read the javadoc, setVisible will validate the window if it is not already displayable. So you won't need an explicit call to revalidate. setSize will invalidate the component but will not revalidate it.

TL; DR:值得一读的有关验证和可显示性如何在Swing中工作,这样你就不会犯错误。

TL;DR: It's worth reading up on how validation and displayability work in Swing so you don't make the mistakes I just did.

这篇关于paintComponent中的图像仅在调整窗口大小后显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 04:56