计算器程序的第一步是首先输入需要求值的表达式,以下是本款计算器软件输入表达式时的状态:
分组处理按钮
计算器差不多是按钮最多的应用程序,因此如何处理这些按钮就成了必须解决的一个问题。在本软件中我们采用分组方式简化按钮的处理。
对于大多数按钮我们只要将按钮的内容文字添加到求值表达式即可;对于函数功能也可以按相同方式处理,但是为了更加简化输入过程,除了添加函数名以外,后面再加一个左括号。
首先是直接输入的情况:
代码语言:javascript复制private void prepareDirectionButtons(){
int direct_button[] = {
//token_area
ResourceTable.Id_i_button,
ResourceTable.Id_angle_button,
ResourceTable.Id_degree_button,
ResourceTable.Id_left_parentheses_button,
ResourceTable.Id_comma_button,
ResourceTable.Id_right_parentheses_button,
ResourceTable.Id_sharp_button,
//number_area
ResourceTable.Id_number0_button,
ResourceTable.Id_number1_button,
ResourceTable.Id_number2_button,
ResourceTable.Id_number3_button,
ResourceTable.Id_number4_button,
ResourceTable.Id_number5_button,
ResourceTable.Id_number6_button,
ResourceTable.Id_number7_button,
ResourceTable.Id_number8_button,
ResourceTable.Id_number9_button,
ResourceTable.Id_plus_button,
ResourceTable.Id_minus_button,
ResourceTable.Id_mul_button,
ResourceTable.Id_div_button,
ResourceTable.Id_dot_button,
ResourceTable.Id_exp_button,
ResourceTable.Id_percent_button,
};
for(int id:direct_button){
Button button = (Button) findComponentById(id);
button.setClickedListener(new Component.ClickedListener() {
public void onClick(Component v) {
appendQuestionString(((Button)v).getText());
}
});
}
}
代码中将所有需要相同处理的按钮保存到一个数组中,然后使用一个循环结构为每个按钮增加相同的处理代码。
对于标准函数按钮,处理方式和内容与标准按钮大致相同,只是在最后向表达式增加内容时多输入一个左括号:
代码语言:javascript复制private void prepareFunButtons(){
int std_fun_button[] = {
//fun_area1
ResourceTable.Id_sin_button,
ResourceTable.Id_cos_button,
ResourceTable.Id_tan_button,
ResourceTable.Id_asin_button,
ResourceTable.Id_acos_button,
ResourceTable.Id_atan_button,
//fun_area2
ResourceTable.Id_x2_button,
ResourceTable.Id_x3_button,
ResourceTable.Id_sqrt_button,
ResourceTable.Id_subtriplicate_button,
ResourceTable.Id_power_button,
ResourceTable.Id_root_button,
};
for(int id:std_fun_button){
Button button = (Button) findComponentById(id);
button.setClickedListener(new Component.ClickedListener() {
public void onClick(Component v) {
appendQuestionString(((Button)v).getText() "(");
}
});
}
}
数量最多的两类按钮的处理完成之后,再加上一个退格键和和清除键,我们今天演示的动作就基本完成了。
代码语言:javascript复制Button back_button = (Button)findComponentById(ResourceTable.Id_back_button);
back_button.setClickedListener(new Component.ClickedListener() {
public void onClick(Component v) {
backQuestion();
}
});
Button ac_button = (Button)findComponentById(ResourceTable.Id_ac_button);
ac_button.setClickedListener(new Component.ClickedListener() {
public void onClick(Component v) {
clearQuestion();
}
});
最后就是向表达式中增加内容,退格和清除三个方法的具体实现,它们都很简单:
代码语言:javascript复制private void appendQuestionString(String str){
TextField question = (TextField)findComponentById(ResourceTable.Id_question_field);
question.setText(question.getText() str);
}
private void backQuestion(){
TextField question = (TextField)findComponentById(ResourceTable.Id_question_field);
String current = question.getText();
if(current.length() > 0)
question.setText(current.substring(0, current.length() - 1));
}
private void clearQuestion(){
TextField question = (TextField)findComponentById(ResourceTable.Id_question_field);
question.setText("");
}
以下是动作视频:
关于计算器的具体实现,读者也可以参照下面的《实战Python设计模式》一书,书中有本文正在介绍的计算器的设计思路,只是具体实现时使用了Python语言。
新书介绍
《实战Python设计模式》是作者最近出版的新书,拜托多多关注!
本书利用Python 的标准GUI 工具包tkinter,通过可执行的示例对23 个设计模式逐个进行说明。这样一方面可以使读者了解真实的软件开发工作中每个设计模式的运用场景和想要解决的问题;另一方面通过对这些问题的解决过程进行说明,让读者明白在编写代码时如何判断使用设计模式的利弊,并合理运用设计模式。
对设计模式感兴趣而且希望随学随用的读者通过本书可以快速跨越从理解到运用的门槛;希望学习Python GUI 编程的读者可以将本书中的示例作为设计和开发的参考;使用Python 语言进行图像分析、数据处理工作的读者可以直接以本书中的示例为基础,迅速构建自己的系统架构。