Простой калькулятор Java с использованием Swing

Это калькулятор Java, который я сделал для своего класса программирования. Я знаю, что для улучшения должно быть огромное пространство.

Обратите внимание, что это только принимает целое число, затем оператор, другое целое число и, наконец, кнопку = для правильной работы. Также учтите, что он печатает результат с помощью System.out.print().

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;

public class JavaCalculator
{
    public static boolean isA, isB;
    public static int a, b, answer;
    public static String operator;

    public static void main (String[] args)
    {
        JButton button_one = new JButton ("1");
        button_one.setBounds (6, 86, 100, 40);
        button_one.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 1;
                    isA = true;
                    System.out.print (a);
                }
                else if (isA && !isB)
                {
                    b = 1;
                    isB  = true;
                    System.out.print (" " + b);
                }
            }
        });

        JButton button_two = new JButton ("2");
        button_two.setBounds (106, 86, 100, 40);
        button_two.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 2;
                    isA = true;
                }
                else if (isA && !isB)
                {
                    b = 2;
                    isB  = true;
                }
            }
        });

        JButton button_three = new JButton ("3");
        button_three.setBounds (206, 86, 100, 40);
        button_three.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 3;
                    isA = true;
                }
                else if (isA && !isB)
                {
                    b = 3;
                    isB  = true;
                }
            }
        });

        JButton button_four = new JButton ("4");
        button_four.setBounds (6, 126, 100, 40);
        button_four.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 4;
                    isA = true;
                }
                else if (isA && !isB)
                {
                    b = 4;
                    isB  = true;
                }
            }
        });

        JButton button_five = new JButton ("5");
        button_five.setBounds (106, 126, 100, 40);
        button_five.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 5;
                    isA = true;
                }
                else if (isA && !isB)
                {
                    b = 5;
                    isB  = true;
                }
            }
        });

        JButton button_six = new JButton ("6");
        button_six.setBounds (206, 126, 100, 40);
        button_six.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 6;
                    isA = true;
                }
                else if (isA && !isB)
                {
                    b = 6;
                    isB  = true;
                }
            }
        });

        JButton button_seven = new JButton ("7");
        button_seven.setBounds (6, 168, 100, 40);
        button_seven.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 7;
                    isA = true;
                }
                else if (isA && !isB)
                {
                    b = 7;
                    isB  = true;
                }
            }
        });

        JButton button_eight = new JButton ("8");
        button_eight.setBounds (106, 168, 100, 40);
        button_eight.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 8;
                    isA = true;
                }
                else if (isA && !isB)
                {
                    b = 8;
                    isB  = true;
                }
            }
        });

        JButton button_nine = new JButton ("9");
        button_nine.setBounds (206, 168, 100, 40);
        button_nine.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 9;
                    isA = true;
                }
                else if (isA && !isB)
                {
                    b = 9;
                    isB  = true;
                }
            }
        });

        JButton button_zero = new JButton ("0");
        button_zero.setBounds (106, 208, 100, 40);
        button_zero.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (!isA && !isB)
                {
                    a = 0;
                    isA = true;
                }
                else if (isA && !isB)
                {
                    b = 0;
                    isB  = true;
                }
            }
        });

        JButton button_equals = new JButton ("=");
        button_equals.setBounds (312, 168, 58, 80);
        button_equals.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                if (operator.contains ("-"))
                {
                    answer = a - b;
                    System.out.print (answer);
                }
                else if (operator.contains ("+"))
                {
                    answer = a + b;
                    System.out.print (answer);
                }
                else if (operator.contains ("/"))
                {
                    answer = a / b;
                    System.out.print (answer);
                }
                else if (operator.contains ("*"))
                {
                    answer = a * b;
                    System.out.print (answer);
                }
            }
        });

        JButton button_minus = new JButton ("-");
        button_minus.setBounds (312, 126, 58, 40);
        button_minus.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                operator = "-";
            }
        });

        JButton button_plus = new JButton ("+");
        button_plus.setBounds (312, 86, 58, 40);
        button_plus.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                operator = "+";
            }
        });

        JButton button_divide = new JButton ("/");
        button_divide.setBounds (312, 46, 58, 40);
        button_divide.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                operator = "/";
            }
        });

        JButton button_times = new JButton ("*");
        button_times.setBounds (312, 6, 58, 40);
        button_times.addActionListener (new ActionListener()
        {
            public void actionPerformed (ActionEvent event)
            {
                operator = "*";
            }
        });

        JFrame frame = new JFrame ("Java Calculator");
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        frame.setSize (380, 274);
        frame.setResizable (false);
        frame.setLayout (null);
        frame.add (button_one);
        frame.add (button_two);
        frame.add (button_three);
        frame.add (button_four);
        frame.add (button_five);
        frame.add (button_six);
        frame.add (button_seven);
        frame.add (button_eight);
        frame.add (button_nine);
        frame.add (button_zero);
        frame.add (button_equals);
        frame.add (button_minus);
        frame.add (button_plus);
        frame.add (button_divide);
        frame.add (button_times);
        frame.setVisible (true);
    }
}
11 голосов | спросил AmiableNebula 23 PMpThu, 23 Apr 2015 23:27:26 +030027Thursday 2015, 23:27:26

5 ответов


10

Вам не нужно столько анонимных обработчиков, было бы лучше, если бы один отслеживал источник события и следил за логикой, которую вы хотите. Вы еще не ответили, требуется ли печать на консоль ... поэтому я буду продолжать расширять это, пока на это не ответит.

Кроме того, вы можете упорядочить способ создания кнопок с помощью массива, подумайте об использовании панели с менеджером макета для размещения чисел.

JPanel numberPanel = new JPanel(new GridLayout(0, 3));
JButton[] numbers = new JButton[10];

numbers[0] = new JButton("0"); // while you can do this
// Better to use a loop!
for (int i = 1; i < numbers.length; i++) {
        numbers[i] = new JButton(Integer.toString(i));
        numberPanel.add(numbers[i]);
}
// Of course we don't forget the 0
numberPanel.add(numbers[0]);

Все, что вам нужно сделать в конце, это frame.add(numberPanel)

Вы можете сделать то же самое для операторов, и можете использовать границу для управления расстоянием между ними, добавив в макет рамки с вашим фреймом для управления общим позиционированием.

JPanel operatorPanel = new JPanel(new GridLayout(0, 1));
operatorPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
JButton[] operators = new JButton[5];

Прямо сейчас у меня есть реализация, которая перебирает набор перечислений с операторами и использует выражение lambda внутри для вычисления, но вы еще не ответили на мой вопрос о том, нужно ли это реализовать на консоли, поэтому я не уверен, что это доступно для ваших целей. Хотя, я считаю, что имеет смысл также иметь ваш вывод JLabel, который имеет свое собственное пространство. Теперь вы можете иметь этот цикл через строку символов {"+", "-", "*", "/", "="} и добавить их так же, как уже было выражено.

Итак, в конце, три вещи, которые вы добавили:

frame.add(result, BorderLayout.NORTH);
frame.add(numberPanel, BorderLayout.CENTER);
frame.add(operatorPanel, BorderLayout.EAST);
ответил Legato 24 AMpFri, 24 Apr 2015 00:11:16 +030011Friday 2015, 00:11:16
7

Позвольте мне начать с простейшего улучшения:

Используйте цикл foreach:

frame.add (button_one);
frame.add (button_two);
frame.add (button_three);
frame.add (button_four);
frame.add (button_five);
frame.add (button_six);
frame.add (button_seven);
frame.add (button_eight);
frame.add (button_nine);
frame.add (button_zero);
frame.add (button_equals);
frame.add (button_minus);
frame.add (button_plus);
frame.add (button_divide);
frame.add (button_times);

должен стать:

for (Button : new JButton[]{button_one, button_two, ... button_times}) {
    frame.add (button);
}
ответил Caridorc 23 PMpThu, 23 Apr 2015 23:36:36 +030036Thursday 2015, 23:36:36
5

Вы, похоже, повторяете этот похожий фрагмент кода:

if (!isA && !isB)
{
    a = 1;
    isA = true;
    System.out.print (a);
}
else if (isA && !isB)
{
    b = 1;
    isB  = true;
    System.out.print (" " + b);
}

Подумайте о том, чтобы использовать это в отдельном методе, чтобы вы могли просто определить это один раз и вызвать функцию в этих местах. Вам может просто потребоваться передать значение, которое будет установлено на a и b.

ответил Jamal 24 AMpFri, 24 Apr 2015 00:01:33 +030001Friday 2015, 00:01:33
3

Поскольку вы упомянули о классе программирования, я обнаружил, что большинству студентов было бы полезно получить информацию об модульных тестах. Его не часто учат, но я считаю, что это должно быть. Одна из основных причин заключается в том, что он заставляет вас создавать код, который может иметь автоматические тесты. Автоматизированные тесты являются удивительными, потому что они быстрые и дают вам отзывы, если вы допустили ошибку или нет. Существует несколько видных подходов к написанию тестов, и целью является не то, чтобы вы использовали конкретный. Я могу сказать, что я предпочитаю сначала писать свои тесты, а затем писать свой производственный код. Я делаю это так, потому что для себя я называю методы немного больше с учетом английского языка, чем программирования. Это требует небольшого количества мозговых напряжений из программирования. (FYI парадигма, которую я упоминаю о написании тестов, это TDD, но, как я уже сказал, есть несколько других способов сделать это, у всех есть свои преимущества и недостатки).

Таким образом, хотя для калькулятора может показаться тривиальным, одна вещь, которую он может сделать, - это выбрать, где вы показываете свой результат еще более тривиально. (Я прочитал несколько ответов, на которых люди упоминают, куда они будут выводить вывод.) Вы упомянули, как вы хотите, чтобы ваш код работал, поэтому я сосредоточусь на написании теста, который соответствует желаемому. (Обратите внимание, что окончательный код почти завершен, просто нужно завершить реализацию операторов.)

IntegerCalculatorNGTest.java

import static org.testng.Assert.*;
import org.testng.annotations.Test;

public class IntegerCalculatorNGTest {

    public IntegerCalculatorNGTest() {
    }

    @Test
    public void testWhenNoNumbersAreEnteredErrorMessageIsReturned() {
        IntegerCalculator calculator = new IntegerCalculator();
        String result = calculator.getResult();

        assertEquals(result, "No Numbers Are Present");
    }

    @Test
    public void testWhenOnlyNumberAIsEnteredErrorMessageIsReturned() {
        IntegerCalculator calculator = new IntegerCalculator();
        calculator.addNumber(1);
        String result = calculator.getResult();

        assertEquals(result, "Atleast 2 Numbers Required");
    }

    @Test
    public void testWhenNoOperatorIsEnteredAfterAddingOneNumberExceptionIsThrown() {
        IntegerCalculator calculator = new IntegerCalculator();
        calculator.addNumber(1);
        try{
            calculator.addNumber(2);
        }
        catch(IllegalStateException ex){
            assertEquals(ex.getMessage(), "Operator Must Be Set before Adding Second Number");
            return;
        }
        fail("Method should have thrown an exception");
    }

    @Test
    public void testWhenAThirdNumberIsAddedExceptionIsThrown() {
        IntegerCalculator calculator = new IntegerCalculator();
        calculator.addNumber(1);
        calculator.setOperator("+");
        calculator.addNumber(2);
        try{
            calculator.addNumber(2);
        }
        catch(IllegalStateException ex){
            assertEquals(ex.getMessage(), "For now, only two numbers can be used");
            return;
        }
        fail("Method should have thrown an exception");
    }

    @Test
    public void testWhenNumberThenOperatorThenNumberIsEnteredValidResultIsReturned() {
        IntegerCalculator calculator = new IntegerCalculator();
        calculator.addNumber(1);
        calculator.setOperator("+");
        calculator.addNumber(2);

        String result = calculator.getResult();

        assertEquals(result, "3");
    }
}

ok, так что теперь примерно через 0,015 секунды я вижу, что какие-либо изменения, внесенные в IntegerCalculator, нарушили мою логику. Я также точно знаю, как его использовать и могу ссылаться на мои тесты как на форму документации. Хорошо, если вы вставили этот тест выше, вы узнаете, что IntegerCalculator не существует. Здесь это (ну, большая часть)

IntegerCalculator.java

import java.util.ArrayList;
import java.util.List;

/**
 * @author snyder
 */
public class IntegerCalculator {
    private final List<Integer> _numbers;
    private String _operator;

    public IntegerCalculator() {
        this._numbers = new ArrayList<>();
        this._operator = "";
    }


    String getResult() {
        if(_numbers.isEmpty())
            return "No Numbers Are Present";
        else if (_numbers.size() < 2)
            return "Atleast 2 Numbers Required";
        int result = 0;
        switch(_operator){
            case "+":
                result = _numbers.get(0) + _numbers.get(1);
                break;
        }

        return Integer.toString(result);
    }

    void addNumber(int i) {
        if(!_numbers.isEmpty() && _operator.isEmpty())
            throw new IllegalStateException("Operator Must Be Set before Adding Second Number");

        if(_numbers.size() == 2)
            throw new IllegalStateException("For now, only two numbers can be used");

        _numbers.add(i);
    }

    void setOperator(String operator) {
        this._operator = operator;
    }
}

ok, так теперь, как я могу его использовать? если вы прослушали h.j.k и используете общий actionListener для всех ваших числовых кнопок, а другой для ваших кнопок оператора, то это очень просто.

вот важные части, которые я сделал, чтобы заставить его работать (это не очень красиво)

private static IntegerCalculator _calculator = new IntegerCalculator();

private static JButton createDefaultNumberButton(int index) {
    JButton numberButton = new JButton(Integer.toString(index));
    numberButton.setPreferredSize(new Dimension(50, 25));
    numberButton.addActionListener(event -> {
        try {
            _calculator.addNumber(Integer.valueOf(((JButton) event.getSource()).getText()));
        } catch (IllegalStateException ex) {
            System.out.println(ex.getMessage());
        }
    });
    return numberButton;
}

public static void main(String[] args) {
    JPanel numberPanel = new JPanel(new GridLayout(0, 3));

    for (int i = 1; i < 10; i++) {
        numberPanel.add(createDefaultNumberButton(i));
    }

    numberPanel.add(createDefaultNumberButton(0));
    numberPanel.setBounds(5, 5, 150, 200);

    JButton button_equals = new JButton("=");
    button_equals.setBounds(312, 168, 58, 80);
    button_equals.addActionListener((ActionEvent event) -> {
        System.out.print(_calculator.getResult());
    });

    JButton button_plus = new JButton("+");
    button_plus.setBounds(312, 86, 58, 40);
    button_plus.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            _calculator.setOperator("+");
        }
    });

класс IntegerCalculator по-прежнему немного неполный, и сам GUI, поскольку он стоит прямо сейчас, не может добавлять числа, превышающие 1 число, но вы получаете его.

ответил Robert Snyder 24 AMpFri, 24 Apr 2015 06:23:09 +030023Friday 2015, 06:23:09
2

Разметка

Как упоминалось в ответе @ Legato , вы можете использовать панель и диспетчер компоновки для организации макета, так что вы не ограничены выравниванием целыми числами (пиксели, на которые я верю?).

Проверка потока входов

Вы должны быть в состоянии сделать что-то более умное здесь ... как насчет того, чтобы отключить кнопки операторов перед первым входом, затем отключить кнопки цифр до того, как выбран оператор, а затем, наконец, включить только кнопку равенства после второе число? Использование Collection для ссылки на два набора кнопок упростит код для значительного выполнения этого переключения. :)

Сохранение входных значений

Вам не нужно использовать пару значений boolean сверху для двух полей, чтобы отслеживать, у вас есть один или два числа. Достаточно одного List, и вы можете проверить, есть ли size() - 0 или 1.

Внедрение ActionListener

Если вы используете Java 8, ваш вызов ActionListener также может быть упрощен:

numberButton.addActionListener(event -> {
    // assuming input validation is done, 
    // e.g. the disabling/enabling feature mentioned above
    inputs.add(Integer.valueOf(((JButton) event.getSource()).getText()));
    // now disable all numeric buttons, 
    // and enable either the operators or equals buttons
});
ответил h.j.k. 24 AMpFri, 24 Apr 2015 04:20:20 +030020Friday 2015, 04:20:20

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132