在Java中创建矩形时,我实际上是否调用了paintComponent方法? [英] Do I actually call the paintComponent method I make when creating a rectangle in Java?

查看:141
本文介绍了在Java中创建矩形时,我实际上是否调用了paintComponent方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我当前的RectangleComponent类,我将它添加到我的主JFrame中的面板,但它永远不会出现。我认为它不是绘图所以我决定在Rectangle的构造函数中调用paintComponent方法,并在通过4-5 nullPointerExceptions进行排序后,没有任何更改。我已经阅读了有关如何绘制矩形的多个指南,并且我已经看到了多个代码示例,但我永远无法让面板与多个JComponent一起使用。如果可以的话,请简要查看我的代码,看看你是否可以设计一个解决方案。
谢谢你的时间。还列出了我调用矩形构造函数的框架。

This is my current RectangleComponent class and I add it to a panel in my main JFrame but it never appears. I thought it wasn't drawing so I decided to call the paintComponent method in the Rectangle's constructor, and after sorting through 4-5 nullPointerExceptions, nothing has changed. I've read multiple guides on how to draw rectangles and I have seen multiple code examples, but I can never get the panels to work with more than one JComponent. If you could, please take a brief look at my code and see if you can devise a solution. Thank you for your time. Also listed is the Frame I call the rectangle constructor in.

public class GameFrame extends JFrame
{
    private SpellBarComponent bar;
    private JPanel mainPanel = new JPanel();
    private JPanel buttonPanel = new JPanel();
    private JPanel healthPanel = new JPanel();
    Color green = new Color(29, 180, 29);
    Color red = new Color(255, 0, 0);
    private RectangleComponent life;
    private RectangleComponent death;
    private JFrame frame = new JFrame();

    public GameFrame(char x)
    {
        frame.setSize(1024, 768);
        frame.setTitle("Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        FlowLayout layout = new FlowLayout();
        createPanels(x);
        healthPanel.setLayout(layout);
        buttonPanel.setLayout(layout);
        mainPanel.setLayout(layout);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        repaint();
    }

    public RectangleComponent getLife()
    {
        return life;
    }

    private void createHealth()
    {
        life = new RectangleComponent(green, healthPanel);
        death = new RectangleComponent(red, healthPanel);
    }

    private void createPanels(char x)
    {
        add(healthPanel);
        pack();
        createBar(x);
        createHealth();
        mainPanel.add(buttonPanel);
        mainPanel.add(healthPanel);
        healthPanel.add(death);
        healthPanel.add(life);
        buttonPanel.add(bar.getSpell1());
        buttonPanel.add(bar.getSpell2());
        buttonPanel.add(bar.getSpell3());
        add(mainPanel);
    }

    private void createBar(char x)
    {
        bar = new SpellBarComponent(x, mainPanel);
    }
}


public class RectangleComponent extends JComponent
{
    Color color;
    int width;
    int height = 18;
    RoundRectangle2D roundedRectangle;
    private JPanel panel;
    public RectangleComponent(Color color, JPanel panel)
    {
        this.panel = panel;
        this.color = color;
        paintComponent(panel.getGraphics());
    }

    public void paintComponent(Graphics g)
    {
        Graphics2D graphics2 = (Graphics2D) g;
        width = 125;
        roundedRectangle = new RoundRectangle2D.Float(10, 10, width, height, 10, 10);
        graphics2.setPaint(color);
        graphics2.fill(roundedRectangle);
        graphics2.draw(roundedRectangle); 
    }

    public void subtractLife(int amount)
    {
        width -= amount;
        roundedRectangle.setRoundRect(10, 10, width, height, 10, 10);
        repaint();
    }
}


推荐答案

In为了使您的Swing应用程序按预期工作,您需要记住许多事项。为了逃避可能出现的某些障碍,必须遵循一定的步骤,因为您以错误的方式编码。为了坚持Swing Programming的基础知识,并遵循它们。

In order for your Swing Application to work as expected, there are many a things you need to keep in mind. There are always certain steps that one must follow in order to escape certain hurdles, that might can arise, since you coded in the wrong way. For this stick to the basics of Swing Programming Strictly, and follow them.


  • 就像@HovercraftFullOfEels所提到的那样,你直接打电话给你的
    图形,哪一个不应该做。

  • Like as mentioned by @HovercraftFullOfEels , you calling to your Graphics directly, which one should never do.

其次,看看你的 GameFrame()构造函数,你把它设置为
visible,甚至在你添加任何组件之前,在它的实际尺寸确定之前已经花了很多

Secondly, look at your GameFrame() constructor, you set it to visible, even before you had added any components to it and much before it's real size has been established

编码中的循环孔可能会引起很多麻烦,因为你坐下来编写大型程序,所以最好从一开始就走在安全的道路上,然后在后期诅咒自己。正如他们所说预防胜于治疗。

Such loop holes inside your coding might can give rise to many a headaches, as you sit down to write huge programs, so better to be on the safe road from the beginning, then to curse yourself at the later stage. As they say Prevention is better than Cure.

现在进入你的程序,你错过了主要的东西,因为你没有指定大小您的 CustomComponent JComponent ,因此您无法在屏幕上看到它。当你将 JCompoent 扩展到你的类时,让它成为习惯的习惯来覆盖它的 getPreferredSize(),与覆盖它的 paintComponent(...)方法。

Now coming to your program, you missed the main thingy, since you failed to specify the size of your CustomComponent i.e. JComponent, hence you are not been able to see it on your screen. As you extends a JCompoent to your class, make it a customary habbit to override it's getPreferredSize(), in the same manner you override it's paintComponent(...) method.

看看这个小程序,我为你精心设计,可能是这个能够帮助你,理解逻辑更多。

Have a look at this small program, I had crafted for you, might be this be able to help you out, to understand the logic a bit more.

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import javax.swing.*;

public class CustomPainting {

    private RectangleComponent life;
    private RectangleComponent death;

    private void createAndDisplayGUI() {
        JFrame frame = new JFrame("Custom Painting");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new GridLayout(0, 2, 5, 5));
        // Specifying the WIDTH, HEIGHT and Colour for this JComponent.
        life = new RectangleComponent(Color.GREEN.darker(), 20, 20);
        death = new RectangleComponent(Color.RED.darker(), 20, 20);
        centerPanel.add(life);
        centerPanel.add(death);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
        JButton incLifeButton = new JButton("INCREASE LIFE");
        incLifeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                life.addLife(1);
            }
        });

        JButton decLifeButton = new JButton("DECREASE LIFE");
        decLifeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                life.subtractLife(1);
            }
        });

        JButton incDeathButton = new JButton("INCREASE DEATH");
        incDeathButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                death.addLife(1);
            }
        });

        JButton decDeathButton = new JButton("DECREASE DEATH");
        decDeathButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                death.subtractLife(1);
            }
        }); 

        buttonPanel.add(incLifeButton);
        buttonPanel.add(decLifeButton);
        buttonPanel.add(incDeathButton);
        buttonPanel.add(decDeathButton);

        frame.getContentPane().add(centerPanel, BorderLayout.CENTER);
        frame.getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String\u005B\u005D args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new CustomPainting().createAndDisplayGUI();
            }
        });
    }
}

class RectangleComponent extends JComponent {

    private Color colour;
    private static final int MARGIN = 10;
    private int width;
    private int height;
    private int originalWidth;
    private RoundRectangle2D roundedRectangle;

    public RectangleComponent(Color c, int w, int h) {
        colour = c;
        width = w;
        height = h;
        originalWidth = width;
    }

    /*
     * Overriding this method, so that
     * the size of the JComponent
     * can be determined, on the screen
     * or by the LayoutManager concern.
     */
    @Override 
    public Dimension getPreferredSize() {
        return (new Dimension(width, height));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        roundedRectangle = new RoundRectangle2D.Float(MARGIN, MARGIN,
                                        width, height, MARGIN, MARGIN);
        g2d.setPaint(colour);
        g2d.draw(roundedRectangle);
        g2d.fill(roundedRectangle);
    }

    public void subtractLife(int amount) {
        width -= amount;
        System.out.println("ORIGINAL Width : " + originalWidth);
        System.out.println("Width : " + width);
        if (width > 0) {
            roundedRectangle.setRoundRect(MARGIN, MARGIN, width, height,
                                            MARGIN, MARGIN);
            /*
             * This repaint() will call the paintComponent(...)
             * by itself, so nothing else to be done.
             */
            repaint();
        } else {
            width += amount;
        }
    }

    public void addLife(int amount) {
        width += amount;
        System.out.println("ORIGINAL Width : " + originalWidth);
        System.out.println("Width : " + width);
        if (width < originalWidth) {
            roundedRectangle.setRoundRect(MARGIN, MARGIN, width, height,
                                            MARGIN, MARGIN);
            repaint();
        } else {
            width -= amount;
        }
    }
}

请问任何问题,当你通过这个程序可能会出现:-),我很乐意帮忙: - )

Do ask any question, that might can arise as you go through this program :-), I be HAPPY to help on that :-)

**两种颜色的最新编辑:**

**LATEST EDIT WITH TWO COLOURS : **

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import javax.swing.*;

public class CustomPainting {

    private RectangleComponent lifeDeath;

    private void createAndDisplayGUI() {
        JFrame frame = new JFrame("Custom Painting");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new GridLayout(0, 2, 5, 5));
        // Specifying the WIDTH, HEIGHT and Colour for this JComponent.
        lifeDeath = new RectangleComponent(Color.GREEN, Color.RED, 20, 20);
        centerPanel.add(lifeDeath);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1, 2, 5, 5));
        JButton incLifeButton = new JButton("INCREASE LIFE");
        incLifeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                lifeDeath.addLife(1);
            }
        });

        JButton decLifeButton = new JButton("DECREASE LIFE");
        decLifeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                lifeDeath.subtractLife(1);
            }
        });

        buttonPanel.add(incLifeButton);
        buttonPanel.add(decLifeButton);

        frame.getContentPane().add(centerPanel, BorderLayout.CENTER);
        frame.getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String\u005B\u005D args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new CustomPainting().createAndDisplayGUI();
            }
        });
    }
}

class RectangleComponent extends JComponent {

    private Color lifeColour;
    private Color deathColour;
    private static final int MARGIN = 10;
    private int widthLife;
    private int widthDeath;
    private int height;
    private int originalWidth;
    private RoundRectangle2D roundedRectangle;

    public RectangleComponent(Color lc, Color dc, int w, int h) {
        lifeColour = lc;
        deathColour = dc;
        widthLife = w;
        height = h;
        originalWidth = widthLife;
        widthDeath = 0;     
    }

    /*
     * Overriding this method, so that
     * the size of the JComponent
     * can be determined, on the screen
     * or by the LayoutManager concern.
     */
    @Override 
    public Dimension getPreferredSize() {
        return (new Dimension(originalWidth, height));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        roundedRectangle = new RoundRectangle2D.Float((MARGIN + widthDeath), MARGIN,
                                        widthLife, height, MARGIN, MARGIN);
        g2d.setPaint(lifeColour);
        g2d.draw(roundedRectangle);
        g2d.fill(roundedRectangle);

        roundedRectangle.setRoundRect(MARGIN, MARGIN,
                                        widthDeath, height, MARGIN, MARGIN);
        g2d.setPaint(deathColour);
        g2d.draw(roundedRectangle);
        g2d.fill(roundedRectangle);
    }

    public void subtractLife(int amount) {
        widthLife -= amount;
        widthDeath += amount;
        System.out.println("ORIGINAL Width : " + originalWidth);
        System.out.println("Width Life : " + widthLife);
        System.out.println("Width Death : " + widthDeath);
        if (widthLife > 0 && widthDeath < originalWidth) {
            /*
             * This repaint() will call the paintComponent(...)
             * by itself, so nothing else to be done.
             */
            repaint();
        } else {
            widthLife += amount;
            widthDeath -= amount;
        }
    }

    public void addLife(int amount) {
        widthLife += amount;
        widthDeath -= amount;
        System.out.println("ORIGINAL Width : " + originalWidth);
        System.out.println("Width Life : " + widthLife);
        System.out.println("Width Death : " + widthDeath);
        if (widthLife < originalWidth && widthDeath > 0) {
            repaint();
        } else {
            widthLife -= amount;
            widthDeath += amount;
        }   
    }
}

这篇关于在Java中创建矩形时,我实际上是否调用了paintComponent方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆