Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
178 views
in Technique[技术] by (71.8m points)

java - Images in paintComponent only show up after resizing the window

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

                 }
         } }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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*.

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.

EDIT: 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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...