Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中创建矩形时,我真的调用了paintComponent方法吗?_Java_Swing_Jframe_Jpanel_Jcomponent - Fatal编程技术网

在Java中创建矩形时,我真的调用了paintComponent方法吗?

在Java中创建矩形时,我真的调用了paintComponent方法吗?,java,swing,jframe,jpanel,jcomponent,Java,Swing,Jframe,Jpanel,Jcomponent,这是我当前的RectangleComponent类,我将它添加到主JFrame中的面板中,但它从未出现过。我认为它不是绘图,所以我决定在矩形的构造函数中调用paintComponent方法,在对4-5个NullPointerException进行排序后,没有任何变化。我已经阅读了多个关于如何绘制矩形的指南,并且看到了多个代码示例,但是我永远无法让面板与多个JComponent一起工作。如果可以的话,请简单看看我的代码,看看你是否能想出一个解决方案。 谢谢你抽出时间。还列出了我在其中调用矩形构造函

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

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();
    }
}

无需将
JPanel
传递给
RectangleComponent
的构造函数,只需获取
Graphics
,也无需手动调用
paintComponent
。看见查看这个演示绘制矩形的自定义组件

您的代码有点创意,有点疯狂,而且逻辑很难理解。最不寻常的是,它有两个JFrame,一个称为“frame”,另一个是GameFrame对象本身,两个都添加了组件,但只有一个显示。还有许多方法返回void(如果过度使用会增加代码的味道),只会增加代码的混乱程度

比如说,

public GameFrame(char x) {

  // here you set up the "frame" JFrame
  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);

  // here you add content to the frame JFrame, and pack it
  frame.getContentPane().add(mainPanel);
  frame.pack();
  repaint();  // and then call repaint on the "this" JFrame?
}

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); // now you add content to the "this" JFrame
  pack();  // and pack it
  createBar(x);
  createHealth();
  mainPanel.add(buttonPanel);
  mainPanel.add(healthPanel); // and then re-add a JPanel into a second JPanel?
  healthPanel.add(death);
  healthPanel.add(life);
  buttonPanel.add(bar.getSpell1());
  buttonPanel.add(bar.getSpell2());
  buttonPanel.add(bar.getSpell3());
  add(mainPanel); // and then re -add the mainPanel into the "this" JFrame???
}
这一切都非常混乱,不太可能奏效

然后,您尝试直接调用paintComponent,并在JComponent上调用getGraphics,这两项都不应该完成。您需要阅读图形教程,了解如何正确执行此操作


我建议您考虑重新编写这篇文章,首先,只使用一个JFrand,更好地组织您的代码。

为了使Swing应用程序如期工作,您需要记住很多事情。为了避免可能出现的某些障碍,必须遵循某些步骤,因为您的编码方式是错误的。为此,请严格遵循Swing编程的基础知识

  • 就像@HovercraftFullOfEels提到的,你打电话给你的 图形直接,这是一个永远不应该做的

  • 其次,查看您的
    GameFrame()
    构造函数,将其设置为 可见,甚至在您向其添加任何组件之前 在确定它的实际大小之前

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

现在来到您的程序,您错过了主要内容,因为您没有指定
自定义组件的大小,即
JComponent
,因此您无法在屏幕上看到它。当您将
jcomponent
扩展到您的类时,将其作为一种习惯习惯来重写,就像重写它的
paintComponent(…)
方法一样

看一看这个小程序,我为你精心编制的,也许这能帮助你,理解更多的逻辑

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;
        }
    }
}
import java.awt.*;
导入java.awt.event.*;
导入java.awt.geom.RoundRectangle2D;
导入javax.swing.*;
公共级定制绘画{
私人生活;
私人矩形管死亡;
私有void createAndDisplayGUI(){
JFrame=新JFrame(“定制绘画”);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel centerPanel=新的JPanel();
setLayout(新的GridLayout(0,2,5,5));
//指定此组件的宽度、高度和颜色。
寿命=新矩形组件(Color.GREEN.darker(),20,20);
死亡=新的矩形组件(Color.RED.darker(),20,20);
添加(生活);
添加(死亡);
JPanel buttonPanel=新的JPanel();
buttonPanel.setLayout(新的FlowLayout(FlowLayout.LEFT,5,5));
JButton incLifeButton=新JButton(“增加寿命”);
incLifeButton.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
生活。生活(1);
}
});
JButton decleivebutton=新JButton(“减少寿命”);
addActionListener(新ActionListener()){
@凌驾
已执行的公共无效行动(行动事件ae){
生活。减去生活(1);
}
});
JButton incdeath按钮=新JButton(“增加死亡”);
incDeathButton.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
死亡。生命(1);
}
});
JButton decDeathButton=新JButton(“减少死亡”);
decDeathButton.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
死亡。减去生命(1);
}
}); 
按钮面板添加(包括按钮);
按钮面板。添加(取消按钮);
按钮面板。添加(incDeathButton);
按钮面板。添加(decDeathButton);
frame.getContentPane().add(中心面板,BorderLayout.CENTER);
frame.getContentPane().add(buttonPanel,BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串\u005B\u005D参数){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新建CustomPaint().createAndDisplayGUI();
}
});
}
}
类RectangleComponent扩展了JComponent{
私人色彩
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;
        }   
    }
}