java - 为什么我的方法没有将其他类中的值相加? (包括 sscce)

标签 java swing awt

所以我是 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/

相关文章:

java - 如何在按下按钮之前暂停方法?

java - 2D map 编辑器 Tiles Palette - 最适合使用的 Java 元素?

java - JSON文件有很多元素,如何使用java读取和打印?

java - 浮点精度

java - 您可以使用泛型进行方法重载并且只更改方法签名的泛型类型吗?

java - 可将光栅写入图像-png 格式?

java - 如何使用 GridBagLayout 创建 3 个 JPanel,一个放在另一个之上,高度可变

java - 从另一个 JPanel 中重新绘制一个 JPanel

java - 如何实现我扩展到 Frame 而不是 JFrame 的类?

java - 如何在java中的Graphics2D对象上创建事件