我是一个java新手,到目前为止我在java中最薄弱的地方是使用图形。我正在尝试制作一个退休计算器,允许用户通过JTextFields将几个数据输入到应用程序中,然后按一个按钮计算每年的帐户余额(即在每个结束时创建一个余额数组)年)。但是,我想使用表示这些余额的条形图来显示此信息,因此条形图必须使用数组中的数字绘制其矩形。但是,由于在程序开始时调用了paintComponent,并且在按下JButton之前没有初始化数组的值,我不能让paintComponent方法引用那些值,否则在运行时会得到nullPointerException。事情没有正确呈现。这是我的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Calculator extends JPanel
{
static double start;
static double age;
static double retirement;
static double apr;
static double inflation;
static double daily;
static double life;
static double income;
static int yearsToRetirement = (int)(retirement - age);
static int yearsPostRetirement = (int)(life - retirement);
static double real = (1.0 + (apr / 100.0))/(1.0 + (inflation/100.0)) - 1.0;
static double[] balance;
static double[] yearEndBalance;
static double[] balance2;
public Calculator()
{
setLayout(new BorderLayout());
JPanel subpanel = new JPanel();
add(subpanel, BorderLayout.LINE_END);
subpanel.setBackground(Color.GRAY);
subpanel.setLayout(new GridLayout(9, 1));
// Daily savings
JPanel pnlDailySavings = new JPanel();
JLabel lblDailySavings = new JLabel("Daily savings amount:");
final JTextField txtDailySavings = new JTextField(10);
pnlDailySavings.add(lblDailySavings);
pnlDailySavings.add(txtDailySavings);
subpanel.add(pnlDailySavings);
// Age
JPanel pnlAge = new JPanel();
JLabel lblAge = new JLabel(" Current age:");
final JTextField txtAge = new JTextField(10);
pnlAge.add(lblAge);
pnlAge.add(txtAge);
subpanel.add(pnlAge);
// Starting amount of savings
JPanel pnlStart = new JPanel();
JLabel lblStart = new JLabel("Starting amount of savings:");
final JTextField txtStart = new JTextField(10);
pnlStart.add(lblStart);
pnlStart.add(txtStart);
subpanel.add(pnlStart);
// Age of retirement
JPanel pnlRetirement = new JPanel();
JLabel lblRetirement = new JLabel("Expected age of retirement:");
final JTextField txtRetirement = new JTextField(10);
pnlRetirement.add(lblRetirement);
pnlRetirement.add(txtRetirement);
subpanel.add(pnlRetirement);
// Annual retirement income
JPanel pnlIncome = new JPanel();
JLabel lblIncome = new JLabel("Annual retirement income:");
final JTextField txtIncome = new JTextField(10);
pnlIncome.add(lblIncome);
pnlIncome.add(txtIncome);
subpanel.add(pnlIncome);
// Life expectancy
JPanel pnlLife = new JPanel();
JLabel lblLife = new JLabel("Life expectancy:");
final JTextField txtLife = new JTextField(10);
pnlLife.add(lblLife);
pnlLife.add(txtLife);
subpanel.add(pnlLife);
// Estimated rate of return on savings
JPanel pnlReturn = new JPanel();
JLabel lblReturn = new JLabel("Estimated rate of return on savings:");
final JTextField txtReturn = new JTextField(10);
pnlReturn.add(lblReturn);
pnlReturn.add(txtReturn);
subpanel.add(pnlReturn);
// Estimated rate of inflation
JPanel pnlInflation = new JPanel();
JLabel lblInflation = new JLabel("Estimated rate of inflation:");
final JTextField txtInflation = new JTextField(10);
pnlInflation.add(lblInflation);
pnlInflation.add(txtInflation);
subpanel.add(pnlInflation);
JButton btnCalculate = new JButton("Calculate your retirement savings");
btnCalculate.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
daily = Double.parseDouble(txtDailySavings.getText());
age = Double.parseDouble(txtAge.getText());
start = Double.parseDouble(txtStart.getText());
retirement = Double.parseDouble(txtRetirement.getText());
income = Double.parseDouble(txtIncome.getText());
life = Double.parseDouble(txtLife.getText());
apr = Double.parseDouble(txtReturn.getText());
inflation = Double.parseDouble(txtInflation.getText());
System.out.printf("%f%n%f%n%f%n%f%n%f%n%f%n%f%n%f%n", daily, age, start, retirement, income, life, apr, inflation);
balance = new double[365 * yearsToRetirement];
yearEndBalance = new double[yearsToRetirement];
balance2 = new double[yearsPostRetirement];
double total = start;
for (int i = 0; i < balance.length; i++)
{
total = total * (1 + real/365.0) + daily;
balance[i] = total;
}
for (int i = 0; i < balance2.length; i++)
{
total = total * Math.pow((1 + real/365.0), 365) - income;
balance2[i] = total;
}
for (int i = 0; i < yearEndBalance.length; i++)
{
yearEndBalance[i] = balance[365 * i];
}
printArray(yearEndBalance);
printArray(balance2);
printArray(balance);
repaint();
}
});
subpanel.add(btnCalculate);
}
public static void printArray(double[] array)
{
for (int i = 0; i < array.length; i++)
{
System.out.println(array[i]);
}
}
public void paintComponent(Graphics g)
{
int width = this.getWidth();
int height = this.getHeight();
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawLine((int)(width - 0.9 * width), (int)(height - 0.1 * height), (int)(width - 0.1 * width), (int)(height - 0.1 * height));
for (int i = 0; i < balance2.length; i++)
{
g.fillRect(((int)(width - 0.9 * width) + 5 * i), ((int)(height - 0.1 * height) - 5 * i), 5, 5 * i);
}
}
}
这段代码显然是一项正在进行的工作,但是现在我最大的障碍是促进在JButton上创建的数组与创建条形图之间的通信。有人可以帮忙吗?
答案 0 :(得分:2)
五件事......
balance2
不是null
且不为空(length
&gt; 0
)paintComponent
而不是paint
,有关详细信息,请参阅Performing Custom Painting。super.paint
,请致电super.paintComponent
(或paintComponent
)以保留油漆链。有关详细信息,请参阅Painting in AWT and Swing(nb:您正在super.paintComponent
内调用paint
,这不是一个好主意,可能会影响对GUI的更新)repaint
醇>
例如......
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = this.getWidth();
int height = this.getHeight();
if (balance2 != null && balance2.length > 0) {
g.setColor(Color.BLACK);
g.drawLine((int)(width - 0.9 * width), (int)(height - 0.1 * height), (int)(width - 0.1 * width), (int)(height - 0.1 * height));
for (int i = 0; i < balance2.length; i++)
{
g.fillRect(((int)(width - 0.9 * width) + 5 * i), ((int)(height - 0.1 * height) - 5 * i), 5, 5 * i);
}
}
}