【问题标题】:paintComponent is not working (Java)油漆组件不工作(Java)
【发布时间】:2013-02-23 15:31:54
【问题描述】:

我一直在尝试覆盖和使用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 对象的更新方法。

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

【问题讨论】:

  • public void paintComponent(Graphics graphics) { 更改为 @Override public void paintComponent(Graphics graphics) { 以获得一些在编译时的输出。每当覆盖方法检查签名并且该方法存在时使用它。 ;)
  • 除了其他建议 - 不要覆盖 update()!也不要调用您的自定义类 Window,该名称已经有一个 AWT 组件,这可能会导致混淆。类应该有描述性的名称。
  • 不要使用 graphics.dispose()。该注释与您创建 Graphics 对象时更相关。在这种情况下,Graphics 对象被传递给组件,并且可能被其他组件使用。

标签: java swing jframe repaint paintcomponent


【解决方案1】:
  • 不要画画

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

  • JComponent / JPanel放到JFrame

  • 覆盖getPreferredSizeJComponent / JPanel(您的硬编码// window size handle),otherwise JComponent / JPanel returns zero dimension,屏幕上将看不到任何内容

【讨论】:

  • 抱歉,您能否进一步解释一下,我在跟上时遇到问题。我不明白,“将 JComponent/JPanel 放入 JFrame”。我仍然不确定我需要修复什么:/
  • 你试过我帖子中链接的代码示例吗,这里有关于 Oracles 教程的基本内容Trail: 2D Graphics
  • @Linkxgl:mKorbel 的建议是正确的。 1+。如果您无法实施他的建议,请将您的尝试显示为对原始问题底部的修改,并让我们知道此尝试存在的任何问题。
  • 所以,我有点让它工作......我将编辑上面的帖子。我能做些什么让它看起来不那么凌乱吗?非常感谢您的帮助。很抱歉没有查看链接。我不知道这是一个链接!我是该网站的新手。
  • +1 所有建议。虽然我建议在阅读 2D 图形教程之前阅读 Swing 教程:Custom Painting 教程。这是最基础的绘画教程。
【解决方案2】:

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

paintComponent 方法是 JPanel 中的一个方法,因此您从 JPanel 而不是 JFrame 覆盖它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    相关资源
    最近更新 更多