Java JSwing-从构造函数中调用子例程不会';初始化数组(它应该这样做)

Java JSwing-从构造函数中调用子例程不会';初始化数组(它应该这样做),java,swing,constructor,initialization,paintcomponent,Java,Swing,Constructor,Initialization,Paintcomponent,我有一个PieChart类,它扩展了JPanel组件,我用它来绘制(你相信吗)一个饼图 我有一个名为createArcs()的子例程,它创建用于绘制饼图的圆弧数组。必须在类中的其他位置访问这些正在创建的圆弧(用于测试鼠标是否在其上) 当我从paintComponent()子例程中调用createArcs()时,一切正常。这并不理想,因为这意味着每次调用paintComponent()时,都会不必要地重新计算圆弧 当从构造函数中调用createArcs()时,会弹出JPanel,但只绘制背景。我还

我有一个PieChart类,它扩展了JPanel组件,我用它来绘制(你相信吗)一个饼图

我有一个名为
createArcs()
的子例程,它创建用于绘制饼图的圆弧数组。必须在类中的其他位置访问这些正在创建的圆弧(用于测试鼠标是否在其上)

当我从
paintComponent()
子例程中调用
createArcs()
时,一切正常。这并不理想,因为这意味着每次调用
paintComponent()
时,都会不必要地重新计算圆弧

当从构造函数中调用
createArcs()
时,会弹出JPanel,但只绘制背景。我还有其他正在测试的图形对象,它们除了背景(纯白色)之外也无法渲染任何东西。它还显示为数组已初始化,因为我可以从paintComponent()子文件中访问数组中圆弧的属性,但无法绘制它们

下面是工作代码,我想从构造函数中调用
createArcs()
,而不是
paintComponent()
sub。感谢所有帮助:)

对于任何格式错误,我深表歉意:^)

import java.awt.*;
导入java.awt.geom.Arc2D;
导入javax.swing.*;
公共类PieChart扩展了JPanel{
公共静态最终整数xBuffer=10;
公共静态最终int yBuffer=10;
公共Arc2D圆弧[];
私有静态最终长serialVersionUID=1L;
int y[];
公共PieChart(int y[]){//构造函数设置数组
这个。y=y;
}
public void收进边界(int x,int y,int width){//覆盖,因此面板只能是正方形
超级立根(x,y,宽度,宽度);
}
公共整数段(整数x,整数y){
int-ret=-1;
对于(int i=0;i
}

以下是不起作用的代码:

import java.awt.*;
import java.awt.geom.Arc2D;

import javax.swing.*;

public class PieChart extends JPanel {

public static final int xBuffer = 10;
public static final int yBuffer = 10;

public Arc2D arcs[];

private static final long serialVersionUID = 1L;

int y[];

public PieChart(int y[]) { //Constructor sets up the array
    this.y = y;
    createArcs();
}

public void setBounds(int x, int y, int width) { //Overrides so that the panel can only ever be a square
    super.setBounds(x, y, width, width);
}

public int getSegment(int x, int y) {
    int ret = -1;
    for (int i = 0; i < arcs.length; i++) {
        if (arcs[i].contains(x, y)) {
            ret = i;
        }
    }
    return ret;
}

public void paintComponent(Graphics g) {

    //Arcs are calculated every time paintComponent is called :((

    //Sets up background
    super.paintComponent(g);
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, getWidth(), getHeight());

    //Create an array same size as the int array

    Graphics2D g2 = (Graphics2D) g;

    g.setColor(Util.generateColor(true));

    //Draws the arcs for the pie chart
    g.setColor(Util.generateColor(true));
    for (int i = 0; i < arcs.length; i++) {
        g2.fill(arcs[i]);
        g.setColor(Util.generateColor(false));
    }

}

public void createArcs() {
    arcs = new Arc2D[y.length];
    float normalisedY[] = new float[y.length];

    int maxY = 0;
    int total = 0;

    //Find maximum element and total of the data
    for (int i = 0; i < y.length; i++) {
        if (maxY < y[i]) {
            maxY = y[i];
        }
        total += y[i];
    }

    //Normalise the Y values in degrees
    for (int i = 0; i < y.length; i++) {
        normalisedY[i] = 360 * (((float) y[i] / (float) total));
    }

    int degreesTravelled = 0;
    //Creates arcs in a circle
    for (int i = 0; i < normalisedY.length; i++) {
        Arc2D arc = new Arc2D.Double(0, 0, getWidth(), getHeight(), degreesTravelled, Math.round(normalisedY[i]), Arc2D.PIE);
        arcs[i] = arc;
        degreesTravelled += Math.round(normalisedY[i]);
    }
}
import java.awt.*;
导入java.awt.geom.Arc2D;
导入javax.swing.*;
公共类PieChart扩展了JPanel{
公共静态最终整数xBuffer=10;
公共静态最终int yBuffer=10;
公共Arc2D圆弧[];
私有静态最终长serialVersionUID=1L;
int y[];
公共PieChart(int y[]){//构造函数设置数组
这个。y=y;
createArcs();
}
public void收进边界(int x,int y,int width){//覆盖,因此面板只能是正方形
超级立根(x,y,宽度,宽度);
}
公共整数段(整数x,整数y){
int-ret=-1;
对于(int i=0;i
}

看起来您有基于面板宽度/高度的逻辑

显然,在创建面板时,在框架可见之前,面板不会有大小

绘制方法应仅绘制零部件的状态,而不更改状态

因此,可能需要在面板中添加一个
ComponentListener
,以进行列表
import java.awt.*;
import java.awt.geom.Arc2D;

import javax.swing.*;

public class PieChart extends JPanel {

public static final int xBuffer = 10;
public static final int yBuffer = 10;

public Arc2D arcs[];

private static final long serialVersionUID = 1L;

int y[];

public PieChart(int y[]) { //Constructor sets up the array
    this.y = y;
    createArcs();
}

public void setBounds(int x, int y, int width) { //Overrides so that the panel can only ever be a square
    super.setBounds(x, y, width, width);
}

public int getSegment(int x, int y) {
    int ret = -1;
    for (int i = 0; i < arcs.length; i++) {
        if (arcs[i].contains(x, y)) {
            ret = i;
        }
    }
    return ret;
}

public void paintComponent(Graphics g) {

    //Arcs are calculated every time paintComponent is called :((

    //Sets up background
    super.paintComponent(g);
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, getWidth(), getHeight());

    //Create an array same size as the int array

    Graphics2D g2 = (Graphics2D) g;

    g.setColor(Util.generateColor(true));

    //Draws the arcs for the pie chart
    g.setColor(Util.generateColor(true));
    for (int i = 0; i < arcs.length; i++) {
        g2.fill(arcs[i]);
        g.setColor(Util.generateColor(false));
    }

}

public void createArcs() {
    arcs = new Arc2D[y.length];
    float normalisedY[] = new float[y.length];

    int maxY = 0;
    int total = 0;

    //Find maximum element and total of the data
    for (int i = 0; i < y.length; i++) {
        if (maxY < y[i]) {
            maxY = y[i];
        }
        total += y[i];
    }

    //Normalise the Y values in degrees
    for (int i = 0; i < y.length; i++) {
        normalisedY[i] = 360 * (((float) y[i] / (float) total));
    }

    int degreesTravelled = 0;
    //Creates arcs in a circle
    for (int i = 0; i < normalisedY.length; i++) {
        Arc2D arc = new Arc2D.Double(0, 0, getWidth(), getHeight(), degreesTravelled, Math.round(normalisedY[i]), Arc2D.PIE);
        arcs[i] = arc;
        degreesTravelled += Math.round(normalisedY[i]);
    }
}
Arc2D arc = new Arc2D.Double(0, 0, getWidth(), getHeight(), degreesTravelled, Math.round(normalisedY[i]), Arc2D.PIE);