问题描述
我想使用 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中的图像仅在调整窗口大小后显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!