- First Java Swing calculator – простой калькулятор на Java
- Как создать калькулятор на Java — полное руководство с кодом
- Создание проекта
- Включение привязки данных в проекте
- Разработка макета калькулятора
- Общие принципы создания виджетов макета
- Создание макета калькулятора
- Внутренние компоненты калькулятора
- Обработка нажатий на цифры
- Обработка кликов по кнопкам операторов
- Заключение
First Java Swing calculator – простой калькулятор на Java
2) Класс JFrameApp наследуем от JFame . Создаем окно нашего приложения, указываем его размеры (setBounds(100, 100, 265, 400)) , добавляем в него стандартные кнопки (свернуть, закрыть, развернуть на весь экран, setDefaultCloseOperation(EXIT_ON_CLOSE)) , а также панель JPanelApp на которой мы будем размещать все наши кнопки. С помощью setVisible(true) говорим что нужно показать окно нашего приложения.
import javax.swing.JFrame; public class JFrameApp extends JFrame < public JFrameApp() < setBounds(100, 100, 265, 400); setTitle("Calculator"); setDefaultCloseOperation(EXIT_ON_CLOSE); add( new JPanelApp()); setVisible(true); >>
3) На панель JPanelApp мы располагаем все наши элементы калькулятора (кнопки, текстовое поле) и интерфейс слушателя на каждую кнопку калькулятора.
import java.awt.Font; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JTextField; public class JPanelApp extends JPanel < JTextField txt1 = null; int res = 0; int res1 = 0; String op = ""; public JPanelApp() < try < setLayout(null); // Specifies the position of the element final TextField txt1 = new TextField(); txt1.setBounds(10, 10, 235, 25); JButton b0 = new JButton("0"); b0.setBounds(10, 270, 75, 50); JButton b1 = new JButton("1"); b1.setBounds(10, 190, 50, 50); JButton b2 = new JButton("2"); b2.setBounds(60, 190, 50, 50); JButton b3 = new JButton("3"); b3.setBounds(110, 190, 50, 50); JButton b4 = new JButton("4"); b4.setBounds(10, 110, 50, 50); JButton b5 = new JButton("5"); b5.setBounds(60, 110, 50, 50); JButton b6 = new JButton("6"); b6.setBounds(110, 110, 50, 50); JButton b7 = new JButton("7"); b7.setBounds(10, 40, 50, 50); JButton b8 = new JButton("8"); b8.setBounds(60, 40, 50, 50); JButton b9 = new JButton("9"); b9.setBounds(110, 40, 50, 50); JButton bRes = new JButton("="); bRes.setBounds(85, 270, 75, 50); Font bigFont = new Font("serif", Font.BOLD, 22); bRes.setFont(bigFont); JButton bPlus = new JButton("+"); bPlus.setBounds(170, 40, 75, 50); Font bigFontPlus = new Font("serif", Font.BOLD, 22); bPlus.setFont(bigFontPlus); JButton bMinus = new JButton("-"); bMinus.setBounds(170, 110, 75, 50); Font bigFontMinus = new Font("serif", Font.BOLD, 22); bMinus.setFont(bigFontMinus); JButton bMulti = new JButton("*"); bMulti.setBounds(170, 190, 75, 50); Font bigFontMulti = new Font("serif", Font.BOLD, 22); bMulti.setFont(bigFontMulti); JButton bDivision = new JButton("/"); bDivision.setBounds(170, 270, 75, 50); Font bigFontDivision = new Font("serif", Font.BOLD, 22); bDivision.setFont(bigFontDivision); add(txt1); add(b0); add(b1); add(b2); add(b3); add(b4); add(b5); add(b6); add(b7); add(b8); add(b9); add(bRes); add(bPlus); add(bMinus); add(bMulti); add(bDivision); b1.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 1); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); b2.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 2); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); b3.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 3); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); b4.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 4); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); b5.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 5); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); b6.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 6); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); b7.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 7); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); b8.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 8); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); b9.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 9); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); b0.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < txt1.setText(txt1.getText() + 0); if (res==0) < res = Integer.valueOf(txt1.getText()); >else < res1 = Integer.valueOf(txt1.getText()); >> >); bPlus.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < res = Integer.valueOf(txt1.getText()); txt1.setText(""); op = "+"; >>); bMinus.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < res = Integer.valueOf(txt1.getText()); txt1.setText(""); op = "-"; >>); bMulti.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < res = Integer.valueOf(txt1.getText()); txt1.setText(""); op = "*"; >>); bDivision.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg1) < res = Integer.valueOf(txt1.getText()); txt1.setText(""); op = "/"; >>); bRes.addActionListener(new ActionListener() < @Override public void actionPerformed(ActionEvent arg0) < int num = Integer.valueOf(res); int num1 = Integer.valueOf(res1); String strOp = op; MetodCalc mc = new MetodCalc(); String strRes = String.valueOf(mc.calc(num, strOp, num1 )); txt1.setText(strRes); >>); > catch (ArithmeticException exception) < //System.out.println("Can not divide by zero "); >> >
4) Класс MetodCalc . В нем мы реализовываем метод, который будет выполнять действия над числами в зависимости от знака операции.
public class MetodCalc < public int calc ( int n1, String op, int n2) < int res = 0; switch (op) < case "+": res = n1+n2; break; case "-": res = n1-n2; break; case "*": res = n1*n2; break; case "/": res = n1/n2; break; default: res = 0; break; >return res; > >
import static org.junit.Assert.assertEquals; public class Tests_Calculator < //testing main functions +, - , *, / @org.junit.Test public void testPlus() < MetodCalc mc = new MetodCalc(); int res= mc.calc(15, "+", 5); assertEquals(20, res); >@org.junit.Test public void test_Minus() < MetodCalc mc = new MetodCalc(); int res=mc.calc(15, "-", 5); assertEquals(10, res); >@org.junit.Test public void test_Multiply() < MetodCalc mc = new MetodCalc(); int res=mc.calc(15, "*", 5); assertEquals(75, res ); >@org.junit.Test public void test_Divide() < MetodCalc mc = new MetodCalc(); int res=mc.calc(15, "/", 5); assertEquals(3, res ); >///////////////division by zero////////////////////// @org.junit.Test (expected = ArithmeticException.class) public void test_Divide_zero() < MetodCalc mc = new MetodCalc(); mc.calc(15, "/", 0); >>
Как создать калькулятор на Java — полное руководство с кодом
В этом руководстве мы расскажем, как создать калькулятор на Java для Android. Если вы новичок в программировании и никогда раньше не создавали приложения, ознакомьтесь с нашим предыдущим руководством по написанию первого приложения для Android:
Предполагается, что у вас есть хотя бы минимальный базовый опыт создания Android – приложений .
Полный исходный код калькулятора, описанного ниже, доступен для использования и изменения на github .
Создание проекта
Первое, что нужно сделать — это создать в Android Studio новый проект: Start a new Android Studio project или File — New — New Project :
Для этого руководства мы выбрали в панели « Add an Activity to Mobile » опцию « EmptyActivity », для « MainActivity » мы оставили имя по умолчанию – « Activity ». На этом этапе структура должна выглядеть, как показано на рисунке ниже. У вас есть MainActivity внутри пакета проекта и файл activity_main.xml в папке layout :
Включение привязки данных в проекте
Перед тем, как создать приложение для Андроид с нуля, нужно уяснить, что использование привязки данных помогает напрямую обращаться к виджетам ( Buttons , EditText и TextView ), а не находить их с помощью методов findViewById() . Чтобы включить привязку данных, добавить следующую строку кода в файл build.gradle .
Разработка макета калькулятора
Для включения привязки данных в файле activity_main.xml требуется еще одно изменение. Оберните сгенерированный корневой тег ( RelativeLayout ) в layout , таким образом сделав его новым корневым тегом.
Как научиться создавать приложения для Андроид? Читайте наше руководство дальше.
Тег layout — это предупреждает систему построения приложения, что этот файл макета будет использовать привязку данных. Затем система генерирует для этого файла макета класс Binding . Поскольку целевой XML-файл называется activity_main.xml , система построения приложения создаст класс ActivityMainBinding , который можно использовать в приложении, как и любой другой класс Java . Имя класса составляется из имени файла макета, в котором каждое слово через подчеркивание будет начинаться с заглавной буквы, а сами подчеркивания убираются, и к имени добавляется слово « Binding ».
Теперь перейдите к файлу MainActivity.java . Создайте закрытый экземпляр ActivityMainBinding внутри вашего класса, а в методе onCreate() удалите строку setContentView () и вместо нее добавьте DataBindingUtil.setContentView() , как показано ниже.
public class MainActivity extends AppCompatActivity < private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); >>
Общие принципы создания виджетов макета
В приложении калькулятора есть четыре основных элемента:
RelativeLayout — определяет, как другие элементы будут укладываться или отображаться на экране. RelativeLayout используется для позиционирования дочерних элементов по отношению друг к другу или к самим себе.
TextView — элемент используется для отображения текста. Пользователи не должны взаимодействовать с этим элементом. С помощью TextView отображается результат вычислений.
EditText — похож на элемент TextView, с той лишь разницей, что пользователи могут взаимодействовать с ним и редактировать текст. Но поскольку калькулятор допускает только фиксированный набор вводимых данных, мы устанавливаем для него статус « не редактируемый ». Когда пользователь нажимает на цифры, мы выводим их в EditText .
Button — реагирует на клики пользователя. При создании простого приложения для Андроид мы используем кнопки для цифр и операторов действий в калькуляторе.
Создание макета калькулятора
Код макета калькулятора объемный. Это связано с тем, что мы должны явно определять и тщательно позиционировать каждую из кнопок интерфейса. Ниже представлен фрагмент сокращенной версии файла макета activity_main :
Внутренние компоненты калькулятора
Перед тем, как создать приложение на телефон Android , отметим, что valueOne и valueTwo содержат цифры, которые будут использоваться. Обе переменные имеют тип double , поэтому могут содержать числа с десятичными знаками и без них. Мы устанавливаем для valueOne специальное значение NaN ( не число ) — подробнее это будет пояснено ниже.
private double valueOne = Double.NaN; private double valueTwo;
Этот простой калькулятор сможет выполнять только операции сложения, вычитания, умножения и деления. Поэтому мы определяем четыре статических символа для представления этих операций и переменную CURRENT_ACTION , содержащую следующую операцию, которую мы намереваемся выполнить.
private static final char ADDITION = '+'; private static final char SUBTRACTION = '-'; private static final char MULTIPLICATION = '*'; private static final char DIVISION = '/'; private char CURRENT_ACTION;
Затем мы используем класс DecimalFormat для форматирования результата. Конструктор десятичного формата позволяет отображать до десяти знаков после запятой.
decimalFormat = new DecimalFormat("#.##########");
Обработка нажатий на цифры
В нашем создаваемом простом приложении для Андроид всякий раз, когда пользователь нажимает на цифру или точку, нам нужно добавить эту цифру в editText . Пример кода ниже иллюстрирует, как это делается для цифры ноль ( 0 ).
binding.buttonZero.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View view) < binding.editText.setText(binding.editText.getText() + "0"); >>);
Обработка кликов по кнопкам операторов
Обработка нажатия кнопок операторов ( действий ) выполняется по-другому. Сначала нужно выполнить все ожидающие в очереди вычисления. Поэтому мы определяем метод computeCalculation . В computeCalculation , если valueOne является допустимым числом, мы считываем valueTwo из editText и выполняем текущие операции в очереди. Если же valueOne является NaN , для valueOne присваивается цифра в editText .
private void computeCalculation() < if(!Double.isNaN(valueOne)) < valueTwo = Double.parseDouble(binding.editText.getText().toString()); binding.editText.setText(null); if(CURRENT_ACTION == ADDITION) valueOne = this.valueOne + valueTwo; else if(CURRENT_ACTION == SUBTRACTION) valueOne = this.valueOne - valueTwo; else if(CURRENT_ACTION == MULTIPLICATION) valueOne = this.valueOne * valueTwo; else if(CURRENT_ACTION == DIVISION) valueOne = this.valueOne / valueTwo; >else < try < valueOne = Double.parseDouble(binding.editText.getText().toString()); >catch (Exception e)<> > >
Продолжаем создавать копию приложения на Андроид . Для каждого оператора мы сначала вызываем computeCalculation() , а затем устанавливаем для выбранного оператора CURRENT_ACTION . Для оператора равно (=) мы вызываем computeCalculation() , а затем очищаем содержимое valueOne и CURRENT_ACTION .
Заключение
Если вы запустите и протестируете данное приложение, то увидите некоторые моменты, которые можно улучшить: 1) возможность нажимать на кнопку оператора, когда editText очищен ( т. е. без необходимости ввода первой цифры ), 2) возможность продолжать вычисления после нажатия кнопки « Равно ».
Полный код примера доступен на github .