繁体   English   中英

我的JFrame没有显示任何内容

[英]My JFrame doesn't show anything

我正在尝试为我的游戏引擎架构中的类构建一个简单的游戏基础。 但我的JFrame只是不会显示任何东西。

我的代码目前的结构如下:

Implementation.java(这是我正在创建的Engine-package的一些任意实现)

public class Implementation {
    public static void main(String[] args){
        World w = new World("Hej", "M:\\workspace\\SP6\\pics\\tulips.jpg",1024,768);
    }
}

World.java

public class World extends JFrame{
private static final long serialVersionUID = 1L;
private SpritePanel spritePanel;
private JPanel bottom;
private int width;
private int height;

public World(String windowCaption, String bgPath, int width, int height){
    super(windowCaption);

    spritePanel = new SpritePanel(bgPath);
    add(spritePanel, BorderLayout.CENTER);
    System.out.println(spritePanel);

    bottom = new JPanel();
    bottom.add(new JLabel("Hej"));
    add(bottom, BorderLayout.SOUTH);

    Dimension size = new Dimension(width,height);
    setSize(size);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    pack();
    setVisible(true);

    validate();
    repaint();      
}

SpritePanel.java

public class SpritePanel extends JPanel {
private static final long serialVersionUID = 1L;
private ImageIcon background;
private ArrayList<Sprite> sprites = new ArrayList<Sprite>();

public SpritePanel(String bgPath){
    background = new ImageIcon(bgPath);
    setLayout(null);
    Dimension size = new Dimension(background.getIconWidth(), background.getIconHeight());
    setPreferredSize(size);
    setMaximumSize(size);
    setMinimumSize(size);
}

@Override
protected void paintComponent(Graphics g){
    super.paintComponent(g);
    g.drawImage(background.getImage(), 0, 0, this);
    System.out.println("painted panel");
}
}

所以现在的基本动作流程(从我可以看到):

  1. 我在Implementation中创建了一个新的World对象
  2. 使用给定参数调用World-constructor
  3. 窗口标题已设置(此工作)
  4. 我用给定的bgPath创建一个新的SpritePanel对象
  5. 调用SpritePanel构造函数并将ImageIcon设置为给定路径中存在的图像
  6. SpritePanel将添加到BorderLayout.CENTER中的框架中
  7. 我在BorderLayout.CENTER中向框架添加了一个新的JPanel
  8. 我设定了尺寸和东西
  9. 我打包并将框架设置为可见
  10. 我验证和重绘

事情是JPanel和SpritePanel中的paintComponent方法似乎没有被调用。 如您所见,我在SpritePanel的paintComponent中添加了一个System.out.println,并且该行永远不会执行。

我注意到的另一件事是包装似乎知道组件在那里。 因为如果我评论这三行

spritePanel = new SpritePanel(bgPath);
add(spritePanel, BorderLayout.CENTER);
System.out.println(spritePanel);

运行程序时的窗口大小减小到“底部”-JPanel的大小。 我看不到我添加到面板的JLabel,但窗口大小是它的大小。 所以pack()方法似乎找到了我的组件的尺寸。

如果我评论添加底部面板的三条线,窗口尺寸减小到没有高度,宽度从标准图标得到。

我一直在尝试不同的东西让它工作,但无济于事。 我以前用Swing编程并制作了工作程序,但我似乎无法在这里找到问题。

非常感谢帮助。

你的String路径可能有问题。 你应该做什么,而不是读取文件,你应该读取一个URL,从类路径加载。 在部署时,您会发现文件路径不起作用,因此最好将图像打包为嵌入式资源 ,将图像放在类路径中。 这样做我没有问题。 这就是我做的。

  • 将路径更改为相对于类路径的路径

     World w = new World("Hej", "/resources/stackoverflow5.png", 1024, 768); 
  • 将文件加载从我的类路径中的URL更改为加载

     background = new ImageIcon(SpritePanel.class.getResource(bgPath)); 
  • 将图像放在我的类路径中的resources包中

在此输入图像描述

一切正常

在此输入图像描述

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Implementation {

    public static void main(String[] args) {
        World w = new World("Hej", "/resources/stackoverflow5.png", 1024, 768);
    }
}

class World extends JFrame {

    private static final long serialVersionUID = 1L;
    private SpritePanel spritePanel;
    private JPanel bottom;
    private int width;
    private int height;

    public World(String windowCaption, String bgPath, int width, int height) {
        super(windowCaption);

        spritePanel = new SpritePanel(bgPath);
        add(spritePanel, BorderLayout.CENTER);
        System.out.println(spritePanel);

        bottom = new JPanel();
        bottom.add(new JLabel("Hej"));
        add(bottom, BorderLayout.SOUTH);

        Dimension size = new Dimension(width, height);
        setSize(size);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        pack();
        setVisible(true);

        validate();
        repaint();
    }

    class SpritePanel extends JPanel {

        private static final long serialVersionUID = 1L;
        private ImageIcon background;
//private ArrayList<Sprite> sprites = new ArrayList<Sprite>();

        public SpritePanel(String bgPath) {
            background = new ImageIcon(SpritePanel.class.getResource(bgPath));
            setLayout(null);
            Dimension size = new Dimension(background.getIconWidth(), background.getIconHeight());
            setPreferredSize(size);
            setMaximumSize(size);
            setMinimumSize(size);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(background.getImage(), 0, 0, this);
            System.out.println("painted panel");
        }
    }
}

附注

  • 无需setSize() 你已经pack() 无论如何最好还是打包。
  • pack()放在setLocationRelativeTo()之前。 如果你pack() 之后 ,你会注意到你的框架不在所需的位置。
  • 像这样从Event Dispatch Thread(EDT)运行你的Swing应用程序

     public static void main(String[] args){ SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { new World("Hej", "/resources/stackoverflow5.png", 1024, 768); } }); } 
  • 如果要使框架填满屏幕,请不要设置尺寸。 不同的机器有不同的屏幕尺寸。 而是使用setExtendedState(JFrame.MAXIMIZED_BOTH);

  • 此外,你的setSize()无论如何都无法工作,因为你之后调用pack()

我的问题是我在世界级中重写了getWidth()和getHeight()方法。 但是看看peeskillets对如何让事情变得更好的反应!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM