【问题标题】:Issues with GUI on a permutation/combination calculator排列/组合计算器上的 GUI 问题
【发布时间】:2013-12-19 15:14:30
【问题描述】:

我能够对此进行编程,而且我看不到任何错误,它甚至显示了 gui。我很确定我正确分配了按钮。但是 GUI 是喜怒无常的,当我运行它时,它会显示,但有时当我输入值时,gui 的内部会消失。但它计算的是 nCr,而不是 pCr。

我有一个驱动程序类。很确定它已正确实施。这是我的面板类。我想知道出了什么问题以及为什么 GUI 无法正常运行

我意识到这是很多代码。我不指望有人为我重写这个。我只想知道我做错了什么,以及如何纠正它。

谢谢。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Color;
import javax.swing.JOptionPane;





public class PermCombCalc extends JPanel {
    JButton permButton = new JButton();
    JButton combButton = new JButton();
    JButton clearButton = new JButton();

    JTextField npermField = new JTextField();
    JTextField rperField = new JTextField();
    JTextField nchooseField = new JTextField();
    JTextField rchooseField = new JTextField();

    JTextField pAnswerField = new JTextField();
    JTextField cAnswerField = new JTextField();




    public PermCombCalc() {

        setLayout(new BorderLayout());
        setPreferredSize(new Dimension(1000, 700));

        JLabel permLabel = new JLabel("Permutation:");
        permLabel.setBounds(10, 20, 100, 20);
        permLabel.setForeground(Color.BLACK);
        add(permLabel);

        JLabel combLabel = new JLabel("Combination:");
        combLabel.setBounds(215, 20, 75, 20);
        combLabel.setForeground(Color.BLACK);
        add(combLabel);

        // Creating Permutation Button
        JLabel PnrLabel = new JLabel("P (n,r)");
        PnrLabel.setForeground(Color.black);
        permButton.setBounds(10, 115, 100, 25);
        add(permButton);
        permButton.add(PnrLabel);
        // Action Listener for permbutton
        permButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                permButton.setActionCommand("Perm");
                permButton.addActionListener(new ButtonListener());

            }

        });

        // Creating combination button
        JLabel CnrLabel = new JLabel("C(n, r)");
        CnrLabel.setForeground(Color.black);
        combButton.setBounds(190, 115, 100, 25);
        add(combButton);
        combButton.add(CnrLabel);
        // ActionListener
        combButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                combButton.setActionCommand("comb");
                combButton.addActionListener(new ButtonListener());


            }
        });

        // Text fields for n and r

        npermField.setBounds(23, 50, 60, 20);
        add(npermField);
        nchooseField.setBounds(230, 50, 60, 20);
        add(nchooseField);

        rperField.setBounds(23, 80, 60, 20);
        add(rperField);
        rchooseField.setBounds(230, 80, 60, 20);
        add(rchooseField);

        // Input fields

        JLabel npLabel = new JLabel("n:");
        npLabel.setForeground(Color.black);
        npLabel.setBounds(10, 55, 10, 10);
        add(npLabel);

        JLabel ncLabel = new JLabel("n:");
        ncLabel.setForeground(Color.BLACK);
        ncLabel.setBounds(217, 55, 10, 10);
        add(ncLabel);

        JLabel rpLabel = new JLabel("r:");
        rpLabel.setForeground(Color.BLACK);
        rpLabel.setBounds(10, 85, 10, 10);
        add(rpLabel);

        JLabel rcLabel = new JLabel("r:");
        rcLabel.setForeground(Color.BLACK);
        rcLabel.setBounds(217, 85, 10, 10);
        add(rcLabel);

        // Fields for answers

        JLabel pAnswerJLabel = new JLabel("<-Answers->");
        pAnswerJLabel.setForeground(Color.BLACK);
        pAnswerJLabel.setBounds(115, 155, 74, 10);
        add(pAnswerJLabel);
        pAnswerField.setBounds(10, 150, 100, 20);
        add(pAnswerField);


        cAnswerField.setBounds(190, 150, 100, 20);  // where is this field?!
        add(cAnswerField);

        // Buttons

        //clearButton.setBounds(10, 210, 110, 25);
        //add(clearButton);

        //JLabel clearLabel = new JLabel("Clear Fields");
        //clearLabel.setForeground(Color.BLACK);
        //clearButton.add(clearLabel);
        // clearButton.addActionListener(new ActionListener() {
        // public void actionPerformed(ActionEvent e) {
        // clearButton.setActionCommand("Clear");

    }
private class ButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("perm")) {
            // contentPane.setBackground(Color.red);
            long Pnr = Permutation();
            if (Pnr != 0) {
                pAnswerField.setText(Pnr + "");
            }
        } else if (e.getActionCommand().equals("comb")) {
            // contentPane.setBackground(Color.black);
            long Cnr = Combination();
            if (Cnr != 0) {
                cAnswerField.setText(Cnr + "");

            }
        } else if (e.getActionCommand().equals("Clear")) {
            // contentPane.setBackground(Color.lightGray);
            npermField.setText(null);
            rperField.setText(null);
            pAnswerField.setText(null);
            nchooseField.setText(null);
            rchooseField.setText(null);
            cAnswerField.setText(null);
        }

    }

    public long Permutation() {
        String npString = npermField.getText();
        String rpString = rperField.getText();
        int npint = 0;
        int rpint = 0;

        try {
            npint = Integer.parseInt(npString);
            rpint = Integer.parseInt(rpString);
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null,"ERROR! The values for 'n' and 'r' \n must be positive integers");
            return 0;
        }
        if (npint <= 0 || rpint <= 0) {
            JOptionPane.showMessageDialog(null,"ERROR! The values for 'n' and 'r' \n must be positive integers");
            return 0;
        }
        if (npint < rpint) {
            JOptionPane.showMessageDialog(null,"ERROR! The value of 'r' must be less than \n or equal to the value of 'n.'");
            return 0;
        }

        long Pnr = 1;
        int mult = npint;
        int nmr = (npint - rpint);
        while (mult > nmr) {
            Pnr = Pnr * mult;
            mult--;
        }

        return Pnr;
    }

    public long Combination()  {
        String ncString = nchooseField.getText();
        String rcString = rchooseField.getText();
        int ncint = 0;
        int rcint = 0;

        try {
            ncint = Integer.parseInt(ncString);
            rcint = Integer.parseInt(rcString);
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null,"ERROR! The values for 'n' and 'r' \n must be positive integers");
            return 0;
        }
        if (ncint <= 0 || rcint <= 0) {
            JOptionPane.showMessageDialog(null,"Error! The values for 'n' and 'r' \n must be positive integers");
            return 0;
        }
        if (ncint < rcint) {
            JOptionPane.showMessageDialog(null,"ERROR! The value of 'r' must be less than \n or equal to the value of 'n.'");
            return 0;
        }

        long nfact = 1;
        for (int i = 2; i <= ncint; i++) {
            nfact = nfact * i;
        }
        long rfact = 1;
        for (int i = 2; i <= rcint; i++) {
            rfact = rfact * i;
        }
        long nmr = ncint - rcint;
        int nmrfact = 1;
        for (int i = 2; i <= nmr; i++) {
            nmrfact = nmrfact * i;
        }

        long Cnr = (nfact / (rfact * nmrfact));

        return Cnr;

    }

}
}

【问题讨论】:

    标签: java swing combinations permutation joptionpane


    【解决方案1】:

    您正在使用BorderLayout,但实际上并没有指定组件的位置,因此它们被渲染在意想不到的地方。

    这是您的应用程序的屏幕截图,pAnswerField 周围有橙色边框,cAnswerField 周围有红色边框

    您应该查看A Visual Guide to Layout Managers 以获取有关正确使用布局管理器的帮助。

    对于您的应用程序,GridLayout 可能是复杂性和布局灵活性之间的合理平衡

    GridBagLayoutSpringLayout 将为您提供最大的灵活性,但使用起来可能会非常复杂。

    编辑 另一个导致permButton 行为不端的小问题。

    在您的按钮创建代码中,您有: permButton.setActionCommand("Perm");

    在你的动作监听器中你有:if (e.getActionCommand().equals("perm"))

    正如所写,当permButton 被按下时,您的ActionListener 将永远不会被调用...要么切换到equalsIgnoreCase,要么定义一个常量而不是使用字符串文字。

    我发现在进行布局工作时添加彩色边框非常有用。以下是如何执行此操作的快速示例:

    npermField.setBounds(23, 50, 60, 20);
    add(npermField);
    nchooseField.setBounds(230, 50, 60, 20);
    
    // add a border to make the component easier to see during layout.
    npermField.setBorder(BorderFactory.createLineBorder(Color.ORANGE));
    
    add(nchooseField);
    

    【讨论】:

    • 谢谢。我会调查一下。
    • 谢谢。不幸的是,我一直在为网格布局而苦苦挣扎。我明白为什么它在这种情况下会有用。
    • 在我看来,在 Swing 中做任何超出琐碎布局的事情都有些痛苦...... NetBeans 有一个 Visual GUI builder 可以为您处理所有布局(我相信它在后台使用 SpringLayout)。你可以在这里使用它吗?
    • 可能。虽然我按照 Netbean 的教程编写了一个简单的摄氏度转换程序,但它写了大约 300 行代码。在课堂上,我们做了一个摄氏度转换器,它几乎没有那么大。我觉得 NetBeans 写了很多冗余代码。我确实喜欢它的想法。我得玩弄它更多
    【解决方案2】:

    如果您喜欢 ButtonListener 类的本来面目(我不喜欢;将在主要问题之后对此发表评论),您可以简单地改写按钮的设置:

    .
    .
    .
    add(permButton);
    permButton.add(PnrLabel);
    // Action Listener for permbutton
    permButton.setActionCommand("Perm");
    permButton.addActionListener(new ButtonListener());
    .
    .
    .
    

    (对于其他按钮也是如此)。

    看到了吗?无需多次添加 ActionListener,也无需添加 ActionListener 为了添加真正的 ActionListener。

    你的应用程序是这样的:

    1. 它在第一次按下按钮时不起作用(因为只有这样才能设置正确的侦听器);
    2. 在第一次按下按钮后,每次新按下都会添加另一个监听器,最终产生意想不到的结果(我没有彻底分析,坦率地说我不会)。

    关于 ButtonListener

    粗略地说,你的班级是这样的:

    if (typeA) {
      doActionA();
    } else if (typeB) {
      doActionB();
    } else if (typeC) {
      doActionC();
    }
    

    您可以简单地创建 3 个独立的 ActionListener,每个只做一件事(doActionA() 或 B 或 C),无需 ifs。然后只使用适当的 ActionListener 设置每个按钮。这样您还可以删除行 setActionCommand(type);,因为它们将变得无用。

    【讨论】:

    • 不知道你现在提到它我在想什么。嗯..我应该只有 Permutation();和组合();里面有方法吗?我想我必须在其他地方分配 buttonListeners
    • 做了一些改变。摆脱了这一点,并在课堂上调用了按钮监听器。当我尝试计算时,仍然有 GUI 内部的问题消失了。嗯。
    • 您只需要分配一次ActionListeners(好吧,理论上您可以即时分配和删除ActionListeners ...这样做是不寻常的,在您的情况下完全毫无意义)。
    • 除此之外,这些按钮的设置(这里:分配 ActionListener)应该在任何 actionPerformed() 方法之外完成。一旦你理解了这个和之前评论的观点,你就完成了。
    • 另见杰森的回答。您需要更正这两个问题才能获得正常工作的 GUI。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    • 1970-01-01
    • 2011-12-15
    • 2012-09-12
    • 1970-01-01
    相关资源
    最近更新 更多