3

我一直在尝试覆盖和使用paint 组件方法而不是paint 方法,因为我已经看到这里的多个问题都建议了它。

我已经查看了很多问题,但我似乎仍然无法让它发挥作用。我正在发布用于渲染屏幕的原始代码。我认为扩展 JFrame 不是正确的方法,相反我需要扩展 JPanel,并从那里使用绘图组件。我有另一个对象,我实际上扩展了 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 对象的更新方法。

如果你们真的需要代码,我可以发布它,但希望这已经足够了。

4

2 回答 2

10
  • 不要画画

    1. 通过paintComponent()直接JFrame使用
    2. 直接上色不是好主意JFrameJFrame不是这项工作的合适容器
    3. 必须使用paint()而不是paintComponent()for JFrame
  • 在您认为应该覆盖父方法的@Override任何方法之前添加,这里是方法。这样,如果您实际上没有覆盖您认为的内容,编译器会警告您。paintComponent(...)

  • 放到JComponent / JPanel_JFrame

  • 覆盖getPreferredSizeJComponent / JPanel你的硬编码 // window size handle),否则JComponent / JPanel返回零维度,简单的屏幕上不会显示任何内容

于 2013-02-23T15:39:00.633 回答
1

你的答案很简单:你只需要扩展JPanel,而不是JFrame

paintComponentmethod 是一个方法 in JPanel,因此你从JPanelnot from覆盖它JFrame

于 2018-08-10T13:01:11.600 回答