1

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

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)
                 {

                 }
         } }
4

2 回答 2

5

您需要调用frame.pack()以进行初始布局。自动调整窗口大小会导致布局固定,但frame.setSize(...)不会*。

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

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

编辑:现在我重新阅读了 javadoc,你可能根本不想要pack- 它会为你调整框架的大小。如果不对其进行测试,我想移动setVisible到最后会起作用;如果它不使用revalidate而不是pack让布局引擎运行。

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: It's worth reading up on how validation and displayability work in Swing so you don't make the mistakes I just did.

于 2013-06-06T04:00:42.057 回答
3

setVisible仅在构建 UI 后调用...

public void run()
{
    frame = new JFrame("Simple Adventure");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(576, 576);
    // 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");

    // Lucky last...   
    frame.setVisible(true);
}

否则,您将需要重新验证框架

于 2013-06-06T04:00:22.317 回答