paintComponent方法无法工作(Java)

3

我一直在尝试覆盖并使用paint组件方法,而不是paint方法,因为我看到多个问题都建议这样做。

我查看了许多问题,但仍然无法使其正常工作。我正在发布用于呈现屏幕的原始代码片段。我认为扩展JFrame不是正确的方法,而是需要扩展JPanel,并从那里使用paint组件。我有另一个对象,在那里我实际上扩展了JPanel,并添加了JFrame(用于呈现)。

这是我用来呈现的对象,顺便说一句,覆盖paint方法可以完美地工作。

package render;


import java.util.Arrays;

import javax.swing.*;

import java.awt.*; //Graphics, Graphics2D, Image

import sprites.Picture;


public class Window extends JFrame{
    private static final long serialVersionUID = 1L;

    public static Picture[] image_list =  new Picture[0]; // All the images I want to render
    private static String win_title = "Window"; // The name of the window
    private static CustomComponents cc = new CustomComponents();


    public Window(){
        setTitle(win_title); // set my title
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // close when you hit x button
        setUndecorated(true); // window has nothing on it

    }


    // paints all the images in image list according to their priority

    public void display(){
        add(cc);
        CustomComponents.updateImageList(image_list);
        pack();

        setMinimumSize(getSize());
        setLocationRelativeTo(null); // puts the screen in the middle
        setResizable(false); // can't resize the window
        setVisible(true); // to see the window


    }



    public double[] getWinSize(){
        double[] size = {this.getSize().getWidth(),this.getSize().getWidth()};

        return size;
    }

    public static void endAll(){
        for (Picture i:image_list){
            i = null;
        }
        image_list = new Picture[0];
        CustomComponents.updateImageList(image_list);
    }

    // close the window (seen in the game object)
    public static void close(){
        System.exit(0);
    }

    // called when adding a new sprite to the image_list array
    public static void addPicture(Picture element){
        Picture[] result = Arrays.copyOf(image_list, image_list.length +1); // does the same thing as the addObject method in objects
        result[image_list.length] = element;
        image_list = result;
        Arrays.sort(image_list);
        CustomComponents.updateImageList(image_list);

    }

    // updates the screen... Just repaints everything
    public void update() {
        cc.repaint();

    }

}


class CustomComponents extends JComponent {

    private static final long serialVersionUID = 1L;

    private static Picture[] image_list;

    public static void updateImageList(Picture[] image_list){
        CustomComponents.image_list = image_list;
    }

    @Override
    public Dimension getMinimumSize() {
        return new Dimension(640,360);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(640,360);
    }

    @Override
    public Dimension getMaximumSize() {
        return new Dimension(640,360);
    }

    @Override
    public void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);
        Graphics2D g2d = (Graphics2D) graphics;
        for (Picture i:image_list){
            if (i.getVisibility()){
            g2d.drawImage(i.getPic(), i.getXY()[0], i.getXY()[1], this);
            }
        }
        Toolkit.getDefaultToolkit().sync(); // this is for linux machines
        graphics.dispose(); // just good programming practice to collect the garbage
    }
}

我会把实际向窗口添加对象的代码贴出来,但是现在它太复杂了,而且只有一些事情发生。在构造函数中,我先向上添加JFrame窗口,然后使用计时器调用JFrame对象的更新方法。
如果您们确实需要代码,我可以贴出来,但是希望这已经足够了。

public void paintComponent(Graphics graphics) { 改为 @Override public void paintComponent(Graphics graphics) {,这样在编译时会有明确的输出。每当重写方法时使用它来检查签名和方法是否存在。 ;) - Andrew Thompson
除了其他建议之外,不要覆盖 update()! 也不要将您的自定义类命名为 Window,因为已经有一个名为 AWT 的组件,可能会导致混淆。 类应该具有描述性名称。 - camickr
不要使用 graphics.dispose()。那个注释更多地涉及创建 Graphics 对象的情况。在这种情况下,Graphics 对象被传递给组件,并且可能被其他组件使用。 - camickr
2个回答

11
  • 不要直接使用paintComponent()JFrame上进行绘制,这不是一个好的方法,JFrame不适合这项工作。

  • 在任何你认为需要覆盖父类方法的方法(例如paintComponent(...)方法)之前添加@Override。这样,如果实际上没有覆盖你认为覆盖的方法,编译器会发出警告。

  • JComponent / JPanel添加到JFrame中。

  • JComponent / JPanel覆盖getPreferredSize方法(处理窗口大小),否则JComponent / JPanel将返回零尺寸,屏幕上将什么也看不到。


抱歉,您能再解释一下吗?我有点跟不上。 我不明白,“将JComponent/JPanel放到JFrame中”是什么意思。 我还不确定我需要修复什么 :/ - Linkxgl
你尝试过我在这里发布的代码示例吗?其中包含有关Oracle教程Trail:2D图形的基本内容。 - mKorbel
@mKorbel的建议一针见血。1+。如果您无法实施他的建议,请在原始问题底部编辑您的尝试,并让我们知道任何问题。 - Hovercraft Full Of Eels
所以,我有点让它工作了...我会编辑上面的帖子。有什么我可以做的,使它看起来不那么混乱吗?非常感谢您的帮助。抱歉没有查看链接。我不知道它是个链接!我是这个网站的新手。 - Linkxgl
2
对于所有的建议都点个赞。虽然我建议在2D图形教程之前阅读Swing教程:自定义绘制教程。这是关于绘画最基本的教程。 - camickr

1
你的答案很简单:你只需要扩展 JPanel,而不是 JFramepaintComponent 方法是 JPanel 中的一个方法,因此你要从 JPanel 覆盖它,而不是从 JFrame

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接