创建一个可用的Java GUI

时间:2011-11-26 04:47:36

标签: java swing user-interface

我是一个Java新手。我参加了一个大学入门Java课程,现在我的课程都没有。

这一点是在GUI创建章节。我不确定我做错了什么。我已经连续工作了一个多星期没有进展。我在Java论坛,YouTube视频,之前的StackOverflow问题,Oracle演示和教程中进行了广泛的搜索。为了以防万一,我将Java JDK更新为1.7,没有任何效果。

首先我要提一下,我以前遇到过一个问题,它会说" javaw.exe遇到问题需要关闭,"但是这个proglem在更新到1.7之后似乎已经消失了我没关系。我正在IDE Eclipse helios中运行该程序。

我决定尝试将程序更改为JApplet以查看这是否会有所帮助,但它还没有。我试过调试,但它甚至不让我完成调试。我究竟做错了什么?当我运行JApplet时,我会在控制台上输出,但StackOverflow不允许我发布它。

这是我的代码的副本。 javadoc尚未完成,我为此道歉。我刚刚做了很多改变,试图修复我已经能够跟上创建所有javadoc的步伐。我还应该警告你,我确实创建了一个输入格式验证(do-while try-catch),但我在此省略了这一点,因为我先试着弄清楚我做错了什么,然后继续加上这个。我也为代码中的草率缩进道歉。不知怎的,它没有很好地转移到StackOverflow网站。

package assignment12;

/*
 * File: CalculateBill.java
 * ------------------------
 * This program calculates a table's bill at a restaurant.
 * The program uses a frame user interface with the following components: 
 * input textfields for the waiter name and table number
 * four interactive combo boxes for each category of the menu containing all the menu items
 * a listbox that keeps track of menu item that is ordered
 * buttons that allow the user to delete an item or clear all the items on the listbox
 * a textarea that displays the table and waiter name entered 
 * a label that refreshes the total, subtotal, and tax when an item is entered or deleted
 * a restaurant logo for "Charlotte's Apple tree restaurant"
 */
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/* CalculateBill.java uses these additional files:
 * images/appletree.gif
 */
/**
 * 
 * @version     1.7                                   
 * @since       2011-11-21          
 */
@SuppressWarnings("serial")
public class CalculateBill extends JPanel implements ActionListener {

    JComboBox beverageList;
    JComboBox appetizerList;
    JComboBox dessertList;
    JComboBox maincourseList;
    JLabel restaurantLogo;
    JTextField textTableNum;  //where the table number is entered
    JTextField waiterName; //where the waiter name is entered
    JTextArea textArea;//where the waiter name and table number appears at the bottem
    JLabel waiter;
    JLabel table;
    DefaultListModel model;//model 
    JList list; // list 
    static int tableNum = 0; // setting table number to an integer outside the range (1-10) keeps loop going until 
    // valid user entry in textTableNum textfield
    String tn; //string value of table number
    String wn; //string value of waiter name
    JScrollPane scrollpane;
    public double subtotal = 0.00;
    public double tax = 0.00;
    public double total = 0.00;
    JLabel totallabel;

    CalculateBill() {

        super(new BorderLayout());
        //create and set up the window.
        JFrame frame = new JFrame("Charlotte's Appletree Restaurant");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(300, 600));


        String[] beverages = {"Beverages", "Soda", "Tea", "Coffee", "Mineral Water", "Juice", "Milk"};
        String[] appetizers = {"Appetizers", "Buffalo Wings", "Buffalo Fingers", "Potato Skins", "Nachos", "Mushroom Caps", "Shrimp Cocktail", "Chips and Salsa"};
        String[] maincourses = {"Main Courses", "Seafood Alfredo", "Chicken Alfredo", "Chicken Picatta", "Turkey Club", "Lobster Pie", "Prime Rib", "Shrimp Scampi", "Turkey Dinner", "Stuffed Chicken"};
        String[] desserts = {"Desserts", "Apple Pie", "Sundae", "Carrot Cake", "Mud Pie", "Apple Crisp"};

        /*create the combo boxes, selecting the first item at index 0.
        indices start at 0, so so 0 is the name of the combo box*/

        // beverages combobox
        beverageList = new JComboBox(beverages);
        beverageList.setEditable(false);
        beverageList.setSelectedIndex(0);
        add(new JLabel("  Beverages:"), BorderLayout.CENTER);
        add(beverageList, BorderLayout.CENTER);
        // appetizers combobox
        appetizerList = new JComboBox(appetizers);
        appetizerList.setEditable(false);
        appetizerList.setSelectedIndex(0);
        add(new JLabel("  Appetizers:"), BorderLayout.CENTER);
        add(appetizerList, BorderLayout.CENTER);

        // maincourses combobox
        maincourseList = new JComboBox(maincourses);
        maincourseList.setEditable(false);
        maincourseList.setSelectedIndex(0);
        add(new JLabel(" Main courses:"), BorderLayout.CENTER);
        add(maincourseList, BorderLayout.CENTER);

        // desserts combox
        dessertList = new JComboBox(desserts);
        dessertList.setEditable(false);
        dessertList.setSelectedIndex(0);
        add(new JLabel("  Desserts:"), BorderLayout.CENTER);
        add(dessertList, BorderLayout.CENTER);

        // listbox
        model = new DefaultListModel();
        JPanel listPanel = new JPanel();
        list = new JList(model);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));



        // list box continued
        JScrollPane listPane = new JScrollPane();
        listPane.getViewport().add(list);
        listPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        listPanel.add(listPane);

        // total label
        totallabel = new JLabel(setTotalLabelAmount());
        add((totallabel), BorderLayout.SOUTH);
        totallabel.setVisible(false);

        // sets up listbox buttons
        add(new JButton("Delete"), BorderLayout.SOUTH);
        add(new JButton("Clear All"), BorderLayout.SOUTH);


        // sets up restaurant logo
        restaurantLogo = new JLabel();
        restaurantLogo.setFont(restaurantLogo.getFont().deriveFont(Font.ITALIC));
        restaurantLogo.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
        restaurantLogo.setPreferredSize(new Dimension(123, 200 + 10));
        ImageIcon icon = createImageIcon("images/appletree.gif");
        restaurantLogo.setIcon(icon);
        restaurantLogo.setText("Charlotte's Apple Tree Restaurant");
        add((restaurantLogo), BorderLayout.NORTH);

        // sets up the label next to textfield for table number
        table = new JLabel("     Enter Table Number (1-10):");


        /**
         * @throws InputMismatchException if the textfield entry is not an integer
         *
         */
        // sets up textfield next to table lable
        table.setLabelFor(textTableNum);
        add((table), BorderLayout.NORTH);

        // sets up label for waiter name
        waiter = new JLabel("      Enter Waiter Name: ");
        // sets up textfield next to waiter lable
        waiter.setLabelFor(waiterName);
        add((waiter), BorderLayout.NORTH);


        // listens to the textfields
        textTableNum.addActionListener(this);
        waiterName.addActionListener(this);


        // sets up textarea
        textArea = new JTextArea(5, 10);
        textArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textArea);


        // lays out listpanel
        listPanel.setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();

        c.gridwidth = GridBagConstraints.REMAINDER;

        c.fill = GridBagConstraints.HORIZONTAL;
        add(listPane, c);

        c.fill = GridBagConstraints.BOTH;

        c.weightx = 1.0;

        c.weighty = 1.0;

        add(scrollPane, c);

        scrollPane.setVisible(true);

    }

    private double getPrices(String item) {
        // create hashmap to store menu items with their corresponding prices

        HashMap<String, Double> hm = new HashMap<String, Double>();

        // put elements to the map
        hm.put("Soda", new Double(1.95));
        hm.put("Tea", new Double(1.50));
        hm.put("Coffee", new Double(1.25));
        hm.put("Mineral Water", new Double(2.95));
        hm.put("Juice", new Double(2.50));
        hm.put("Milk", new Double(1.50));
        hm.put("Buffalo Wings", new Double(5.95));
        hm.put("Buffalo Fingers", new Double(6.95));
        hm.put("Potato Skins", new Double(8.95));
        hm.put("Nachos", new Double(8.95));
        hm.put("Mushroom Caps", new Double(10.95));
        hm.put("Shrimp Cocktail", new Double(12.95));
        hm.put("Chips and Salsa", new Double(6.95));
        hm.put("Seafood Alfredo", new Double(15.95));
        hm.put("Chicken Alfredo", new Double(13.95));
        hm.put("Chicken Picatta", new Double(13.95));
        hm.put("Turkey Club", new Double(11.95));
        hm.put("Lobster Pie", new Double(19.95));
        hm.put("Prime Rib", new Double(20.95));
        hm.put("Shrimp Scampi", new Double(18.95));
        hm.put("Turkey Dinner", new Double(13.95));
        hm.put("Stuffed Chicken", new Double(14.95));
        hm.put("Apple Pie", new Double(5.95));
        hm.put("Sundae", new Double(3.95));
        hm.put("Carrot Cake", new Double(5.95));
        hm.put("Mud Pie", new Double(4.95));
        hm.put("Apple Crisp", new Double(5.95));

        double price = hm.get(item);
        return price;
    }

    /**
     * validates that the correct path for the image was found to prevent crash
     *
     * @param path is the icon path of the restaurant logo
     *
     * @return nothing if you can't find the image file
     *
     * @return imageIcon(imgURL) the path to image if you can find it
     */
    protected static ImageIcon createImageIcon(String path) {
        java.net.URL imgURL = CalculateBill.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            JOptionPane.showMessageDialog(null, "Couldn't find file: "
                + path, "image path error", JOptionPane.ERROR_MESSAGE);
            return null;
        }

    }

    //Listens to the combo boxes 
    private void getSelectedMenuItem(JComboBox cb) {
        String mnItem = (String) cb.getSelectedItem();
        updateListBox(mnItem);

    }

    /**
     * updates the list box
     * 
     * @param name the element to be added to the list box
     */
    private void updateListBox(String name) {
        totallabel.setVisible(false);
        model.addElement(name);
        Addition(getPrices(name));
        totallabel.setVisible(true);
    }

    void showWaiterAndTableNum() {
        textArea.append("Table Number: " + tn + " Waiter: " + wn);
        textArea.setCaretPosition(textArea.getDocument().getLength());
    }

    /**
     * adds to the subtotal/total calculator.
     *
     * @param s The name of the menu item which will be used to access its hashmap key value. 
     *
     */
    private void Addition(double addedP) {

        subtotal = subtotal + addedP;

        tax = .0625 * subtotal;

        total = subtotal + tax;



    }

    /**
     * subtracts from to the subtotal/total calculator.
     *
     * @param subtractedp The price of the menu item which will be used to access its hashmap key value. 
     *
     */
    // sets up the 'total' label which shows subtotal, tax, total
    private void Subtraction(double subtractedp) {

        subtotal = subtotal - subtractedp;

        tax = subtotal * .0625;
        total = subtotal + tax;

    }

    private void resetCalculator() {
        subtotal = 0.00;
        tax = 0.00;
        total = 0.00;
    }

    // listens to list buttons
    @Override
    public void actionPerformed(ActionEvent e) {
        JTextField tf = (JTextField) e.getSource();
        if (tf.equals("textTableNum")) {
            tn = tf.getText();
        } else if (tf.equals("waiterName")) {
            wn = tf.getText();
        }

        String cmd = e.getActionCommand();
        if (cmd.equals("Delete")) {
            totallabel.setVisible(false);
            ListSelectionModel selmodel = list.getSelectionModel();
            int index = selmodel.getMinSelectionIndex();
            String foodName = (String) list.getSelectedValue();
            Subtraction(getPrices(foodName));
            totallabel.setVisible(true);
            //subtracts from the subtotal
            if (index >= 0) {
                model.remove(index);
            }
        } else if (cmd.equals("Clear all")) {
            model.clear();
            resetCalculator();
        }
    }

    //combobox mouse listener
    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2) {
            JComboBox cb = (JComboBox) e.getSource();
            getSelectedMenuItem(cb);
        }
    }

    private String setTotalLabelAmount() {
        String totlab = "Subtotal: $ " + subtotal + " Tax: $" + tax + "\n" + "Total: $ " + total;
        return totlab;
    }
}

**my applet:**
package assignment12;

import javax.swing.JApplet;


import javax.swing.SwingUtilities;



@SuppressWarnings("serial")
public class Main extends JApplet {

    /**
     * @param args
     */
    public void init() {

        // schedule job for event-dispatching
        //while showing Aplication GUI
        try {
            SwingUtilities.invokeLater(new Runnable() {

                public void run() {
                    createAndShowGUI();
                }
            });
        } catch (Exception e) {
            System.err.println("createAndShowGUI didn't complete successfully");
        }
    }

    // create and show GuI
    private void createAndShowGUI() {

        //Create and set up the content pane.
        CalculateBill newContentPane = new CalculateBill();
        newContentPane.setOpaque(true); //content panes must be opaque
        setContentPane(newContentPane);
    }
}

3 个答案:

答案 0 :(得分:4)

嗯,一方面,“没有错”会浮现在脑海中,但实际上你已经走了很远。

这里有几个问题。我只对他们中的一些人进行了抨击。

将JPanel子类化为JFrame会更容易。创建一个面板,并将其添加到框架中。请参阅Eric关于如何构建它的答案,并参见下面的主要方法。

您有两个缺少的JTextField:textTableNum和waiterName。我建立的第一件事是在这两个地方的NPE。接下来,GridBag的约束是错误的。我不是GridBag的人。 GridBag给了我荨麻疹,所以我不能说那些有什么问题,所以我删除了约束并用'null'替换它们。一旦我这样做了,我至少得到了一个框架和一个GUI。

接下来,您的所有BorderLayout代码都是错误的。在边框布局上指定位置时,这正是您正在执行的操作 - 指定位置。如果你在BorderLayout.NORTH中放入3个东西,它们都将会在那里,并且层叠在彼此之上(你将只看到其中一个)。所以,显然,你的所有布局代码都需要做很多工作。

经过一些屠宰后,我们有了这个:

package soapp;

/*
 * File: CalculateBill.java
 * ------------------------
 * This program calculates a table's bill at a restaurant.
 * The program uses a frame user interface with the following components:
 * input textfields for the waiter name and table number
 * four interactive combo boxes for each category of the menu containing all the menu items
 * a listbox that keeps track of menu item that is ordered
 * buttons that allow the user to delete an item or clear all the items on the listbox
 * a textarea that displays the table and waiter name entered
 * a label that refreshes the total, subtotal, and tax when an item is entered or deleted
 * a restaurant logo for "Charlotte's Apple tree restaurant"
 */
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/* CalculateBill.java uses these additional files:
 * images/appletree.gif
 */
/**
 *
 * @version     1.7
 * @since       2011-11-21
 */
@SuppressWarnings("serial")
public class CalculateBill extends JPanel implements ActionListener {

    JComboBox beverageList;
    JComboBox appetizerList;
    JComboBox dessertList;
    JComboBox maincourseList;
    JLabel restaurantLogo;
    JTextField textTableNum;  //where the table number is entered
    JTextField waiterName; //where the waiter name is entered
    JTextArea textArea;//where the waiter name and table number appears at the bottem
    JLabel waiter;
    JLabel table;
    DefaultListModel model;//model
    JList list; // list
    static int tableNum = 0; // setting table number to an integer outside the range (1-10) keeps loop going until
    // valid user entry in textTableNum textfield
    String tn; //string value of table number
    String wn; //string value of waiter name
    JScrollPane scrollpane;
    public double subtotal = 0.00;
    public double tax = 0.00;
    public double total = 0.00;
    JLabel totallabel;

    public static void main(String[] args) {
        // TODO code application logic here
        JFrame frame = new JFrame("SO App");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        CalculateBill cb = new CalculateBill();
        frame.getContentPane().add(cb);
        frame.pack();
        frame.setVisible(true);
    }

    CalculateBill() {
        super(new BorderLayout());
        JPanel panel;
        //create and set up the window.
//        JFrame frame = new JFrame("Charlotte's Appletree Restaurant");
//        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        frame.setPreferredSize(new Dimension(300, 600));

        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

        String[] beverages = {"Beverages", "Soda", "Tea", "Coffee", "Mineral Water", "Juice", "Milk"};
        String[] appetizers = {"Appetizers", "Buffalo Wings", "Buffalo Fingers", "Potato Skins", "Nachos", "Mushroom Caps", "Shrimp Cocktail", "Chips and Salsa"};
        String[] maincourses = {"Main Courses", "Seafood Alfredo", "Chicken Alfredo", "Chicken Picatta", "Turkey Club", "Lobster Pie", "Prime Rib", "Shrimp Scampi", "Turkey Dinner", "Stuffed Chicken"};
        String[] desserts = {"Desserts", "Apple Pie", "Sundae", "Carrot Cake", "Mud Pie", "Apple Crisp"};

        /*create the combo boxes, selecting the first item at index 0.
        indices start at 0, so so 0 is the name of the combo box*/

        // beverages combobox
        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        beverageList = new JComboBox(beverages);
        beverageList.setEditable(false);
        beverageList.setSelectedIndex(0);
        panel.add(new JLabel("  Beverages:"), BorderLayout.CENTER);
        panel.add(beverageList, BorderLayout.CENTER);
        add(panel);
        // appetizers combobox
        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        appetizerList = new JComboBox(appetizers);
        appetizerList.setEditable(false);
        appetizerList.setSelectedIndex(0);
        panel.add(new JLabel("  Appetizers:"), BorderLayout.CENTER);
        panel.add(appetizerList, BorderLayout.CENTER);

        // maincourses combobox
        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        maincourseList = new JComboBox(maincourses);
        maincourseList.setEditable(false);
        maincourseList.setSelectedIndex(0);
        panel.add(new JLabel(" Main courses:"), BorderLayout.CENTER);
        panel.add(maincourseList, BorderLayout.CENTER);
        add(panel);
        // desserts combox
        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));

        dessertList = new JComboBox(desserts);
        dessertList.setEditable(false);
        dessertList.setSelectedIndex(0);
        panel.add(new JLabel("  Desserts:"), BorderLayout.CENTER);
        panel.add(dessertList, BorderLayout.CENTER);
        add(panel);
        // listbox
        model = new DefaultListModel();
        JPanel listPanel = new JPanel();
        list = new JList(model);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));



        // list box continued
        JScrollPane listPane = new JScrollPane();
        listPane.getViewport().add(list);
        listPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        listPanel.add(listPane);
        add(listPanel);

        // total label
        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        totallabel = new JLabel(setTotalLabelAmount());
        panel.add((totallabel), BorderLayout.SOUTH);
        totallabel.setVisible(false);
        add(panel);

        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        // sets up listbox buttons
        panel.add(new JButton("Delete"), BorderLayout.SOUTH);
        panel.add(new JButton("Clear All"), BorderLayout.SOUTH);
        add(panel);

        // sets up restaurant logo
//        restaurantLogo = new JLabel();
//        restaurantLogo.setFont(restaurantLogo.getFont().deriveFont(Font.ITALIC));
//        restaurantLogo.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
//       restaurantLogo.setPreferredSize(new Dimension(123, 200 + 10));
//        ImageIcon icon = createImageIcon("images/appletree.gif");
//        restaurantLogo.setIcon(icon);
//        restaurantLogo.setText("Charlotte's Apple Tree Restaurant");
//        add((restaurantLogo), BorderLayout.NORTH);

        // sets up the label next to textfield for table number

        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        table = new JLabel("     Enter Table Number (1-10):");


        /**
         * @throws InputMismatchException if the textfield entry is not an integer
         *
         */
        // sets up textfield next to table lable
        textTableNum = new JTextField();
        table.setLabelFor(textTableNum);
        panel.add((table), BorderLayout.NORTH);
        panel.add(textTableNum, BorderLayout.NORTH);
        add(panel);

        // sets up label for waiter name
        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        waiter = new JLabel("      Enter Waiter Name: ");
        waiterName = new JTextField();
        // sets up textfield next to waiter lable
        waiter.setLabelFor(waiterName);
        panel.add((waiter), BorderLayout.NORTH);
        panel.add(waiterName, BorderLayout.NORTH);
        add(panel);

        // listens to the textfields
        textTableNum.addActionListener(this);
        waiterName.addActionListener(this);


        // sets up textarea
        textArea = new JTextArea(5, 10);
        textArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textArea);


        // lays out listpanel
//        listPanel.setLayout(new GridBagLayout());

//        GridBagConstraints c = new GridBagConstraints();

//        c.gridwidth = GridBagConstraints.REMAINDER;

//        c.fill = GridBagConstraints.HORIZONTAL;
//        add(listPane, c);
//        add(listPane, null);

//        c.fill = GridBagConstraints.BOTH;

//        c.weightx = 1.0;

//        c.weighty = 1.0;

//        add(scrollPane, c);
        add(scrollPane, null);

        scrollPane.setVisible(true);


    }

    private double getPrices(String item) {
        // create hashmap to store menu items with their corresponding prices

        HashMap<String, Double> hm = new HashMap<String, Double>();

        // put elements to the map
        hm.put("Soda", new Double(1.95));
        hm.put("Tea", new Double(1.50));
        hm.put("Coffee", new Double(1.25));
        hm.put("Mineral Water", new Double(2.95));
        hm.put("Juice", new Double(2.50));
        hm.put("Milk", new Double(1.50));
        hm.put("Buffalo Wings", new Double(5.95));
        hm.put("Buffalo Fingers", new Double(6.95));
        hm.put("Potato Skins", new Double(8.95));
        hm.put("Nachos", new Double(8.95));
        hm.put("Mushroom Caps", new Double(10.95));
        hm.put("Shrimp Cocktail", new Double(12.95));
        hm.put("Chips and Salsa", new Double(6.95));
        hm.put("Seafood Alfredo", new Double(15.95));
        hm.put("Chicken Alfredo", new Double(13.95));
        hm.put("Chicken Picatta", new Double(13.95));
        hm.put("Turkey Club", new Double(11.95));
        hm.put("Lobster Pie", new Double(19.95));
        hm.put("Prime Rib", new Double(20.95));
        hm.put("Shrimp Scampi", new Double(18.95));
        hm.put("Turkey Dinner", new Double(13.95));
        hm.put("Stuffed Chicken", new Double(14.95));
        hm.put("Apple Pie", new Double(5.95));
        hm.put("Sundae", new Double(3.95));
        hm.put("Carrot Cake", new Double(5.95));
        hm.put("Mud Pie", new Double(4.95));
        hm.put("Apple Crisp", new Double(5.95));

        double price = hm.get(item);
        return price;
    }

    /**
     * validates that the correct path for the image was found to prevent crash
     *
     * @param path is the icon path of the restaurant logo
     *
     * @return nothing if you can't find the image file
     *
     * @return imageIcon(imgURL) the path to image if you can find it
     */
    protected static ImageIcon createImageIcon(String path) {
        java.net.URL imgURL = CalculateBill.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            JOptionPane.showMessageDialog(null, "Couldn't find file: " + path, "image path error", JOptionPane.ERROR_MESSAGE);
            return null;
        }

    }

    //Listens to the combo boxes
    private void getSelectedMenuItem(JComboBox cb) {
        String mnItem = (String) cb.getSelectedItem();
        updateListBox(mnItem);

    }

    /**
     * updates the list box
     *
     * @param name the element to be added to the list box
     */
    private void updateListBox(String name) {
        totallabel.setVisible(false);
        model.addElement(name);
        Addition(getPrices(name));
        totallabel.setVisible(true);
    }

    void showWaiterAndTableNum() {
        textArea.append("Table Number: " + tn + " Waiter: " + wn);
        textArea.setCaretPosition(textArea.getDocument().getLength());
    }

    /**
     * adds to the subtotal/total calculator.
     *
     * @param s The name of the menu item which will be used to access its hashmap key value.
     *
     */
    private void Addition(double addedP) {

        subtotal = subtotal + addedP;

        tax = .0625 * subtotal;

        total = subtotal + tax;



    }

    /**
     * subtracts from to the subtotal/total calculator.
     *
     * @param subtractedp The price of the menu item which will be used to access its hashmap key value.
     *
     */
    // sets up the 'total' label which shows subtotal, tax, total
    private void Subtraction(double subtractedp) {

        subtotal = subtotal - subtractedp;

        tax = subtotal * .0625;
        total = subtotal + tax;



    }

    private void resetCalculator() {
        subtotal = 0.00;
        tax = 0.00;
        total = 0.00;



    }

    // listens to list buttons
    @Override
    public void actionPerformed(ActionEvent e) {
        JTextField tf = (JTextField) e.getSource();
        if (tf.equals("textTableNum")) {
            tn = tf.getText();
        } else if (tf.equals("waiterName")) {
            wn = tf.getText();
        }


        String cmd = e.getActionCommand();
        if (cmd.equals("Delete")) {
            totallabel.setVisible(false);
            ListSelectionModel selmodel = list.getSelectionModel();
            int index = selmodel.getMinSelectionIndex();
            String foodName = (String) list.getSelectedValue();
            Subtraction(getPrices(foodName));
            totallabel.setVisible(true);
            //subtracts from the subtotal
            if (index >= 0) {
                model.remove(index);
            }
        } else if (cmd.equals("Clear all")) {
            model.clear();
            resetCalculator();

        }
    }

    //combobox mouse listener
    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2) {
            JComboBox cb = (JComboBox) e.getSource();
            getSelectedMenuItem(cb);
        }
    }

    private String setTotalLabelAmount() {
        String totlab = "Subtotal: $ " + subtotal + " Tax: $" + tax + "\n" + "Total: $ " + total;
        return totlab;
    }
}

这不是代表性的代码。它唯一的功能是它至少可以显示出你想要的东西。

另请注意,我注释掉了所有徽标代码,因为我没有图像文件 - 为了方便起见,我只是在那部分上进行了抨击。

它的作用是创建一个JPanel子类。该面板有一个BoxLayout,垂直排列。通过将多个组件放入同一个插槽,您误解了BorderLayout的工作原理。例如,您可以将“删除”和“全部清除”JButton放入BorderLayout.SOUTH。这意味着它们都消耗相同的空间,最后一个最终位于另一个的顶部,因此它看起来只有一个组件。

BoxLayout有一个Flow,就像你向它们添加组件一样,组件不重叠并添加并扩展空间。基本的JPanels布局是一个垂直的BoxLayout,因此当添加组件时,它们将堆叠并显示在行中。

接下来,Swing中常见的习惯用法,特别是手工制作的GUI,是使用JPanels作为容器。如果您曾经使用绘图程序并使用Group函数将4行转换为单个框,则Swing和布局中的JPanel的工作方式相同。每个JPanel都有自己的布局,然后一旦完成,JPanel就会被视为一个整体。

所以,在这里我再次使用了BoxLayout,这次只使用了LINE_AXIS样式,它将组件端对端放置,将它们排成一行。

您可以看到我创建了几个JPanel,将布局设置为BoxLayout,然后将组件添加到每个JPanel,然后将这些JPanel添加到主JPanel。各个JPanel中的组件是端到端的,但是当它们被添加到主JPanel时,它的BoxLayout会从上到下堆叠。

请注意,BorderLayout细节的残留仍然存在,因为我没有清理它。我会删除所有这些。

这是我停下来的地方,因为代码编译并显示了GUI,这至少应该可以让你使用400行以外的黑盒子“nothings happening”代码。它可能看起来不像你想象的那样,这也不是我的目标。我会玩JPanel和子JPanel成语和布局管理器,直到你接近你想要的。如果有点分散,从Javadoc for Swing链接的Java Swing教程非常好。因此,更多的阅读存在。

正如其他人所提到的那样,当你开始做类似的东西时,你最好从小开始(比如让2个下拉框工作)。那么你只需要关注一些事情就可以让它们发挥作用,然后你可以在最终项目的基础上进行构建。

我希望这对你有所帮助。

答案 1 :(得分:2)

首先,您应该从Applet切换回常规应用程序。并在主方法中创建JFrame,而不是在面板中执行:

将您的主班级更改为:

public class Main{

  public static void main(String[] args){
     JFrame frame = new JFrame("Charlotte's Appletree Restaurant");
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     CalculateBill newContentPane = new CalculateBill();
     frame.getContentPane().add(newContentPane);
     frame.setPreferredSize(new Dimension(300, 600));
     frame.setVisible(true);
  }

然而,问题的主要部分似乎是在尝试向其添加ActionListener之前,您没有初始化textTableNum。

每当您尝试访问未引用实际对象的变量时,就会发生NullPointerException。要诊断它们,请转到行号并查看该行上取消引用的变量。

在这种情况下,堆栈跟踪告诉您在CalculateBill.java的第186行发生异常,即:

 textTableNum.addActionListener(this);

因此,基于该行代码,唯一可能出现问题的变量是textTableNum。在使用变量之前,需要确保变量已初始化。


您在评论中提到的第二个问题是,当您声明CalculateBill使用BorderLayout时,您开始使用GridBagConstraints将组件添加到CalculateBill面板。

另外,我注意到你在同一个BorderLayout区域添加了几个组件。你不能这样做。您只能添加一个。如果你想在NORTH区域中有多个组件,那么你需要创建一个子面板,在那里布局你想要的组件,然后将子面板添加到BorderLayout的NORTH。

答案 2 :(得分:2)

似乎有许多属性,从waiterName开始,已声明但未初始化。