Java - 正确处理不同的 JFrame 后 JLabel 损坏

标签 java swing jframe jlabel

我目前正在制作我们的项目,但在将 JLabel 重置回“0”时遇到问题。这是代码

主要代码片段(请检查注释1以了解所使用的帧处理方法):

import javax.swing.*;                                                       //import library
import java.awt.event.*;
import java.awt.*;
import java.util.*;

public class draft_main                                                     //class name
{
    public static void main(String[] args)            
    {                                                                       //method name
        JFrame f0 = new JFrame("POS");                                      //frame
        JPanel p0 = new JPanel();                                           //panel inside the frame
        JPanel p1 = new JPanel();
        JPanel p2 = new JPanel();
        JPanel p3 = new JPanel();
        JPanel p4 = new JPanel();
        JPanel p5 = new JPanel();
        JPanel p6 = new JPanel();
        JPanel p7 = new JPanel();
        JLabel l0 = new JLabel("Amount:");                                  //label inside the panel
        JLabel l1 = new JLabel("0");
        JLabel l2 = new JLabel("Menu Code: ");
        JLabel l3 = new JLabel("--Menu--");
        JTextField tf0 = new JTextField("", 12);                            //user input for menu code
        JButton b0 = new JButton("Checkout");                               //buttons
        JButton b1 = new JButton("Cancel");
        JButton b2 = new JButton("Exit");
        JButton b4 = new JButton("Accept");
        JButton b7 = new JButton("Remove");
        JOptionPane jop = new JOptionPane();                                //JOptionPane
        JTextField tf1 = new JTextField("1. Hot Pockets Pizza", 20);        //list of menu
        JTextField tf2 = new JTextField("2. Burger with Fries", 20);
        JTextField tf3 = new JTextField("3. Sticky Rice (Bico)", 20);
        ArrayList<String> ar = new ArrayList<String>();                     //list of array

        try{
            b4.addActionListener(new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)              //what the accept button does
                    {
                        String order = tf0.getText(), tots="", temp="";
                        int o = Integer.parseInt(order);
                        int tot=0;

                        switch(o)                                           //menu choice
                        {
                            case 1 : temp = l1.getText(); tot=Integer.parseInt(temp); tot=tot+250; tots = Integer.toString(tot); l1.setText(tots); ar.add("Hot Pockets Pizza"); break;
                            case 2 : temp = l1.getText(); tot=Integer.parseInt(temp); tot=tot+65; tots = Integer.toString(tot); l1.setText(tots); ar.add("Burger with Fries"); break;
                            case 3 : temp = l1.getText(); tot=Integer.parseInt(temp); tot=tot+12; tots = Integer.toString(tot); l1.setText(tots); ar.add("Sticky Rice (Bico)"); break;
                            default : jop.showMessageDialog(null, "Menu code not listed in menu", "Error", jop.INFORMATION_MESSAGE); break;
                        }
                    }
                });

            b0.addActionListener(new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)              //what the checkout button does
                    {
                        JFrame f1 = new JFrame("Checkout");
                        JFrame f2 = new JFrame("Order");
                        JPanel p8 = new JPanel();
                        JPanel p9 = new JPanel();
                        JPanel p10 = new JPanel();
                        JPanel p11 = new JPanel();
                        JPanel p12 = new JPanel();
                        JPanel p13 = new JPanel();
                        JPanel p14 = new JPanel();
                        JLabel l5 = new JLabel("Order list");
                        JLabel l6 = new JLabel(/*convert ArrayList to String then put here*/);
                        JLabel l4 = new JLabel("Cash");
                        JTextField tf4 = new JTextField("", 14);
                        JButton b5 = new JButton("Accept");
                        JButton b6 = new JButton("Cancel");
                        JButton b7 = new JButton("Ok");

                        b5.addActionListener(new ActionListener()
                            {
                                public void actionPerformed(ActionEvent e)
                                {
                                    String cas = l1.getText(), in = tf4.getText();
                                    int cash = Integer.parseInt(cas), inp = Integer.parseInt(in), cahs=0;

                                    if(cash>inp)
                                    {
                                        jop.showMessageDialog(null, "Insufficient funds", "Lacking cash? Work for it.", jop.INFORMATION_MESSAGE);
                                    }
                                    else if(cash<inp)
                                    {
                                        cahs = inp - cash;
                                        jop.showMessageDialog(null, "Change: " +cahs+". Thank you");
                                        f1.dispatchEvent(new WindowEvent(f1, WindowEvent.WINDOW_CLOSING));
                                    }
                                    else if(cash==inp)
                                    {
                                        jop.showMessageDialog(null, "Thank you.", "Thank you.", jop.INFORMATION_MESSAGE);
                                        f1.dispatchEvent(new WindowEvent(f1, WindowEvent.WINDOW_CLOSING));
                                    }
                                }
                            });

                        b6.addActionListener(new ActionListener()
                            {
                                public void actionPerformed(ActionEvent e)
                                {
                                    f1.dispatchEvent(new WindowEvent(f1, WindowEvent.WINDOW_CLOSING));
                                }
                            });

                        b7.addActionListener(new ActionListener()
                            {
                                public void actionPerformed(ActionEvent e)
                                {
                                    f2.dispatchEvent(new WindowEvent(f2, WindowEvent.WINDOW_CLOSING));
                                }
                            });

                        p9.add(l0);
                        p9.add(l1);
                        p10.add(l4);
                        p10.add(tf4);
                        p11.add(b5);
                        p11.add(b6);
                        p12.add(l5);
                        p12.add(l6);
                        p13.add(b7);
                        p14.add(p12);
                        p14.add(p13);
                        p8.add(p10);
                        p8.add(p11);
                        p8.add(p9);
                        f1.add(p8);
                        f1.pack();
                        f1.setSize(240,170);
                        f1.setLocationRelativeTo(null);
                        f1.setResizable(false);
                        f1.setDefaultCloseOperation(f1.DISPOSE_ON_CLOSE);
                        f1.setVisible(true);
                        f2.add(p14);
                        f2.pack();
                        f2.setSize(270,100);
                        f2.setResizable(false);
                        f2.setLocationRelativeTo(null);
                        f2.setDefaultCloseOperation(f2.DISPOSE_ON_CLOSE);
                        f2.setVisible(true);
                    }
                });

            b1.addActionListener(new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        l1.setText("0");
                    }
                });

            b2.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    f0.dispose();
                }
            });
        }

        catch(Exception e)
        {
            jop.showMessageDialog(null, "Error");
        }

        tf1.setEditable(false);
        tf2.setEditable(false);
        tf3.setEditable(false);
        p4.add(tf1);
        p5.add(tf2);
        p6.add(tf3);
        p7.add(l3);
        p3.add(l2);
        p3.add(tf0);
        p3.add(b4);
        p1.add(l0);
        p1.add(l1);
        p2.add(b0);
        p2.add(b1);
        p2.add(b2);
        p0.add(p3);
        p0.add(p1);
        p0.add(p2);
        p0.add(p7);
        p0.add(p4);
        p0.add(p5);
        p0.add(p6);
        f0.add(p0);
        f0.pack();
        f0.setSize(303,280);
        f0.setLocationRelativeTo(null);
        f0.setResizable(false);
        f0.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f0.setVisible(true);
    }
}

当主窗口打开时,它会询问一个人从菜单中订购了哪个,然后显示价格。结帐时,用户将被要求输入所给的现金金额,并在有零钱时找零。之后,结账框架被“正确”处理(我认为是这样),暴露了主框架。然而,当我下另一个订单或清除当前订单时,JLabel 似乎没有更新,这让我很困扰,因为主框架应该是完全交互的,直到主框架关闭。

注意#1:我使用了不同的方法来处理弹出的第二个和第三个框架,因为我认为这可能是因为 dispose();并没有真正破坏框架,而是让它在后台运行。

注意#2:是的,该程序尚未完成,但目前这些并不重要,因为这些只是应用程序的一些小功能。

最佳答案

这段代码存在几个问题,但我看到的主要问题(我还没有完成所有问题,所以可能还有更多)

  • 首先,这些 JFrame 子窗口根本不应该是 JFrame,而应该是模态 JDialog。这样做的原因是,当使用这些对话框时,您可以完全控制程序流程,因为您将知道当模式对话框可见时主程序流程将被搁置,然后流程将立即恢复因为对话框不再可见。这样您就可以在处理完对话框后查询其状态,然后使用此信息来更新您的 GUI。
  • 您的金额显示在 l1 变量中,除非您专门对此变量调用 setText(...),否则该金额永远不会改变。订单处理完毕后,您似乎并未执行此操作。模式对话框将再次帮助您。
  • 你的变量命名不好。不要使用无意义的字母和数字作为名称,而应使用有意义的名称,并使您的代码具有 self 注释功能。例如,使用 amountLabel 或类似的东西来代替 l1
  • 您的代码是一个巨大的上帝类,所有内容都塞进了静态 main 方法中,这造成了调试噩梦。 Java 是一种面向对象的语言,如果使用得当,OOP 技术可以帮助您降低程序复杂性,使您的代码更容易为您自己和我们所理解。开始对您的程序进行 OOP 化,您将立即看到红利。

  • 我发现了您的错误 - 您将 l1 JLabel 添加到另一个容器,因此它实际上已从原始 JFrame 中删除。如果您最小化原始 GUI 然后恢复它,您将看到 l1 JLabel 的数量消失。

这里有一些尚未完成的示例代码,但可以让您了解如何将 OOP 添加到程序中:

import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class Draft2 extends JPanel {
    private List<MyItem> selectedItems = new ArrayList<>();
    private NumberFormat formatter = NumberFormat.getCurrencyInstance();
    private double total;
    private JLabel totalAmountLabel = new JLabel(formatter.format(total));
    private DefaultComboBoxModel<MyItem> comboModel = new DefaultComboBoxModel<>();
    private JComboBox<MyItem> menuCombo = new JComboBox<>(comboModel);

    public Draft2() {
        // monospaced to make names and price line up
        menuCombo.setFont(new Font(Font.MONOSPACED, Font.BOLD, 12));

        // fill the JComboBox with items
        comboModel.addElement(new MyItem("Baseball", 21.5));
        comboModel.addElement(new MyItem("Bat", 50.8));
        comboModel.addElement(new MyItem("Football", 22.26));

        // create a JPanel to hold selection components and add components
        JPanel selectionPanel = new JPanel();
        selectionPanel.add(new JLabel("Menu:"));
        selectionPanel.add(menuCombo);
        selectionPanel.add(new JButton(new AcceptAction("Accept", KeyEvent.VK_A)));

        // create a JPanel to hold the total amount information
        JPanel totalAmountPanel = new JPanel();
        totalAmountPanel.add(new JLabel("Total Amount:"));
        totalAmountPanel.add(totalAmountLabel);

        // create a JPanel to hold buttons, uses grid layout with a single row  
        JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0)); 
        btnPanel.add(new JButton(new CheckOutAction("Check Out", KeyEvent.VK_C)));
        btnPanel.add(new JButton(new CancelAction("Cancel", KeyEvent.VK_N)));
        btnPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));

        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        add(selectionPanel);
        add(Box.createVerticalStrut(5)); // so don't crowd things
        add(totalAmountPanel);
        add(Box.createVerticalStrut(5));
        add(btnPanel);
    }

    public void setTotalAmount(double total) {
        totalAmountLabel.setText(formatter.format(total));
    }

    private class AcceptAction extends AbstractAction {

        public AcceptAction(String name, int mnemonic) {
            super(name);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            MyItem myMenuItem = (MyItem) menuCombo.getSelectedItem();
            if (myMenuItem == null) {
                return; // nothing selected, get out
            }
            selectedItems.add(myMenuItem);
            double total = 0.0;
            for (MyItem myItem : selectedItems) {
                total += myItem.getCost();
            }

            setTotalAmount(total);
        }
    }

    private class CheckOutAction extends AbstractAction {
        public CheckOutAction(String name, int mnemonic) {
            super(name);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Finish....
            // open JDialog or JOptionPane

        }
    }

    private class CancelAction extends AbstractAction {
        public CancelAction(String name, int mnemonic) {
            super(name);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Finish...

        }
    }

    private class ExitAction extends AbstractAction {
        public ExitAction(String name, int mnemonic) {
            super(name);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub

        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("My GUI Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new Draft2());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
                createAndShowGui();            
        });
    }
}

class MyItem {
    private NumberFormat formatter = NumberFormat.getCurrencyInstance();
    private String name;
    private double cost;
    public MyItem(String name, double cost) {
        this.name = name;
        this.cost = cost;
    }

    public String getName() {
        return name;
    }

    public double getCost() {
        return cost;
    }

    @Override
    public String toString() {
        return String.format("%-10s %s", name, formatter.format(cost));
    }
}

关于Java - 正确处理不同的 JFrame 后 JLabel 损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35799546/

相关文章:

java - 在 java web 应用程序中,清除任何使用的集合会导致更好的内存管理吗?

java - ProcessBuilder 在 Linux 上运行 jar

javafx datepicker 在 swin 面板上的 swing 中

java - 如何让两个 JPanel 水平拆分,每个 JPanel 始终占据屏幕的一半?

java - 是否可以知道 JFrame 是否完全可见?

java - ScrollView 折叠嵌套相对布局问题

java - 如何在 Windows 中的 ProcessBuilder java 中设置 PATH 环境变量

swing - JTable 疯狂?

java - 如何让我的 GUI Frame 变大?

java - 使用 JFrame 进行边框布局