所以我是 java 的新手。
这个程序现在运行。这是一个食品订购系统。它使用每个带有网格的选项卡。每个标签都有自己的价格。
我的问题是当我运行和编译程序时,它运行但价格不相加。 基本上,在下面列出的 GUI 类中,有一种方法可以从每个选项卡中获取价格并将它们相加……除了它没有这样做。它确实出现了,但“$0.00”没有改变。
就像我说的那样它可以编译,但是,当我按下按钮时,我可以看到编译器出现了这个错误:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
这是主类:
import javax.swing.JFrame;
public class Pizzamain
{
public static void main (String[] args)
{
JFrame frame = new JFrame ("Pizza Mutt Ordering Service");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new PizzaMuttPanel());
frame.pack();
frame.setVisible(true);
}
}
这个类包含所有的 GUI。它还将每个选项卡中的价格相加。我注释掉了其他选项卡。
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.text.NumberFormat;
public class PizzaMuttPanel extends JPanel
{
private JLabel totalLabel;
private double total;
public PizzaMuttPanel()
{
setLayout (new BorderLayout());
JLabel name = new JLabel("Pizza Mutt Ordering Service WOOF! WOOF!");
JPanel namePanel = new JPanel();
namePanel.add(name);
add(namePanel, BorderLayout.NORTH);
JTabbedPane mainTabPane = new JTabbedPane();
mainTabPane.add("Pizza", new PizzaPanel());
// mainTabPane.add("Drinks", new DrinksPanel());
// mainTabPane.add("Specials", new SpecialsPanel());
add(mainTabPane, BorderLayout.CENTER);
total = 0.0;
JPanel totalPanel = new JPanel();
totalPanel.add (new JLabel("Your total is:"));
totalLabel = new JLabel("$0.00");
totalPanel.add(totalLabel);
add(totalPanel, BorderLayout.SOUTH);
}
public void addTotal (double intake)
{
total += intake;
NumberFormat dollars = NumberFormat.getCurrencyInstance();
totalLabel.setText(dollars.format(total));
}
}
这是其中一个选项卡的示例。顺便说一句,所有选项卡都遵循此逻辑。如您所见,在操作部分,每次按下按钮时都会添加价格,然后将数据中继到 GUI 类。
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class PizzaPanel extends JPanel
{
private double price;
private final JButton pl;
private final JButton ps;
private final JButton cl;
private final JButton cs;
private final JButton vl;
private final JButton vs;
private PizzaMuttPanel mainPanel;
public PizzaPanel()
{
setLayout (new GridLayout (2, 3));
setBackground (Color.red);
pl = new JButton ("Large Pepperoni: $7");
ps = new JButton ("Small Pepperoni: $4");
cl = new JButton ("Large Cheese: $6.50");
cs = new JButton ("Small Cheese: $3.50");
vl = new JButton ("Large Vegetable: $7");
vs = new JButton ("Small Vegetable: $4");
add (pl);
add (ps);
add (cl);
add (cs);
add (vl);
add (vs);
pl.addActionListener(new ButtonListener());
ps.addActionListener(new ButtonListener());
cl.addActionListener(new ButtonListener());
cs.addActionListener(new ButtonListener());
vl.addActionListener(new ButtonListener());
vs.addActionListener(new ButtonListener());
}
//Here we listen for button presses
private class ButtonListener implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
if (e.getSource().equals(pl))
{
price+=7;
}
if(e.getSource().equals(ps))
{
price+=4;
}
if (e.getSource().equals(cl))
{
price+=6.5;
}
if (e.getSource().equals(cs))
{
price+=3.5;
}
if (e.getSource().equals(vl))
{
price+=7;
}
if (e.getSource().equals(vs))
{
price+=4;
}
//This adds all the prices together.
mainPanel.addTotal(price);
}}}
最佳答案
一种方法,对你来说可能有点过头了,但这是一种非常有用的技术,了解和使用是使保存由 JPanel 显示的信息的对象成为“绑定(bind)属性”,它允许其他类能够监听并响应其状态的变化。
具体来说:
- 为包含感兴趣信息的类提供一个 SwingPropertyChangeSupport 字段。
- 如果您的类扩展了 JComponent 或 JPanel(或派生自 JComponent 的任何类),则它已经具有其中之一。
- 给你的类一个私有(private)的
count
int 字段 - 为该字段提供一个公共(public)的 getter 和 setter 方法。
- 在 setter 字段中,使用更新后的值和旧值调用 SwingPropertyChangeSupport 的
firePropertyChange(String propertyName, int oldValue, int newValue)
方法。 - 切勿直接更改绑定(bind)属性,只能通过其设置方法。
- 让任何想要监听变化的类添加一个 PropertyChangeListener 到这个类。
如果您需要更具体的示例,请考虑创建并发布 sscce ,我可以向您展示如何修改它以使其正常工作。
编辑
您当前的代码在引用方面存在问题——您需要子面板具有对主面板的有效引用,您应该通过传递引用来解决此问题。
例如
private MainPanel mainPanel;
public SubPanelA(MainPanel mainPanel) {
this.mainPanel = mainPanel;
然后在填充标签时:
mainTabPane.add("A", new SubPanelA(this));
mainTabPane.add("B", new SubPanelB(this));
mainTabPane.add("C", new SubPanelC(this));
通过这种方式,您的选项卡 Pane 类可以根据对显示的主类的有效引用从主类调用方法。
编辑2
你声明:
I'm a little confused. But I have a reference, right? In the buttonlistener class, first I private PizzaMuttPanel mainPanel; at the top, and then I referenced it as mainPanel.addTotal(price);. Addtotal is in the main GUI class, and holds the prices. Price is the price being taken from the button presses in that specific tab's classes. Are you saying I should change the latter to: mainTabPane.add("A", new SubPanelA(this));
积分:
- This:
PizzaMuttPanel mainPanel;
不是引用,而只是引用变量的声明。声明后,它引用 null,直到您给它一个有效的引用。 - 你声明
“然后我将其引用为 mainPanel.addTotal(price);”
,???这不会产生任何引用,在我看来只会抛出 NPE。要为变量提供引用,您必须分配 对它的引用,这意味着您需要一些以mainPanel = something goes here
开头的语句。
关于java - 为什么我的方法没有将其他类中的值相加? (包括 sscce),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20576586/