java 计算器SWT/RAP(版本3)键盘鼠标兼容,之前版本也对,但存在线程失效问题,当多人访问时,就容易线程失效,一直犯得一个错误就是一直用static变量和static方法,
之前加了什么js界面控制什么的,都没用,去掉static就好了
package cn.lesaas.nof.rwtswt.ui.dialog;
import java.math.BigDecimal;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import cn.lesaas.nof.conn.base.MyAsyncCallback;
import cn.lesaas.nof.rsclient.UC;
import cn.lesaas.nof.rwtswt.ui.widgets.rules.FieldVerify;
/*
*计算器类,没有继承模态窗口
*/
public class CalcDialog extends Dialog {
private static final long serialVersionUID = 1L;
/** 计算器上的键的显示名字 */
private String[] keys = { "←左键删除", "C", "+", "-", "*", "%除号", "7", "8", "9", "4", "5", "6", "1", "2",
"3", "0", ".", "=默认焦点" };
/** 计算器上的功能键的显示名字 */
/** 计算结果文本框 */
private Text labtopNum;// 上面存放的是数字和符号
private Text labdownresult;// 每次输入的的数字及两个数的和
// 标志用户按的是否是整个表达式的第一个数字,或者是运算符后的第一个数字
private boolean firstDigit = true;
// 计算的中间结果。
private double resultNum = 0.0;
// 当前运算的运算符
private String operator = "=";
// 操作是否合法
private boolean operateValidFlag = true;
private Button buttonKey = null;
boolean closed;
Shell shell;
private MyAsyncCallback cbOpen;
public CalcDialog(Shell parent) {
super(parent, SWT.TITLE);
}
// 创建窗口大小
protected void createShell() {
shell = new Shell(getParent(), getStyle());
shell.setLayout(new FormLayout());
onCreateShell();
}
protected void onCreateShell() {
shell.setText("计算器");
shell.setSize(327, 370);
// shell.setSize(width, height);
Composite composite = new Composite(shell, SWT.NONE);
try {
onCreateMainPanel(composite);
onCreateButtons(composite);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void onCreateMainPanel(Composite parent) throws Exception {
Calc(parent);
}
/**
* 初始化计算器
*/
public void Calc(Composite parent) {
parent.setLayout(new GridLayout());
labtopNum = new Text(parent, SWT.RIGHT | SWT.READ_ONLY | SWT.BORDER);//
GridData gridDataLab = new GridData(GridData.FILL_HORIZONTAL);// GridData是指定子控件的信息
gridDataLab.heightHint = 25;// 初始高度为20
gridDataLab.horizontalSpan = 3;// 跨三列
//gridDataLab.widthHint = 300;
labtopNum.setLayoutData(gridDataLab);
labtopNum.setText("");// 只用来存放每次输入的数字和符号
labtopNum.setFont(UC.getLoginFont());
// 创建数字显示框
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);// GridData是指定子控件的信息
// resultText = new Text(parent, SWT.RIGHT | SWT.BORDER|SWT.READ_ONLY);
labdownresult = new Text(parent, SWT.RIGHT | SWT.READ_ONLY | SWT.BORDER);// |
// SWT.BORDER
gridData.heightHint = 25;// 初始高度为20
gridData.horizontalSpan = 3;// 跨三列
labdownresult.setLayoutData(gridData);
labdownresult.setText("");// 存放这个是对数的结果
labdownresult.setFont(UC.getLoginFont());
// labdownresult.setFocus();
Composite composite = new Composite(parent, SWT.NONE);
GridLayout gridLayoutKey = new GridLayout(3, true);
gridLayoutKey.marginWidth = 0;// 设置按钮距离父控件的左边距为0
gridLayoutKey.marginHeight = 0;// 设置按钮距离父控件的右边距为0
composite.setLayout(gridLayoutKey);
GridData gridDataKey = new GridData(GridData.FILL_HORIZONTAL);
// gridDataKey.horizontalSpan = 3;
composite.setLayoutData(gridDataKey);
// 初始化功能键,都用红色标示。将功能键放在一个画板内
// 用网格布局器,1行,3列的网格,网格之间的水平方向间隔为3个象素,垂直方向间隔为3个象素
int length = keys.length;
int i = 0;
for (i = 0; i < length; i++) {
buttonKey = new Button(composite, SWT.PUSH);
gridDataKey = new GridData(GridData.FILL_BOTH);
buttonKey.setLayoutData(gridDataKey);
buttonKey.setText(keys[i]);
buttonKey.forceFocus();
Listener listener = new Listener() {
public void handleEvent(Event e) {
if (e.type == SWT.KeyDown) {
// 0-9.----131072+
char c = e.character;
String str = String.valueOf(c);
if (c >= ‘0‘ && c <= ‘9‘ || c == ‘.‘) {
// String markStr = String.valueOf(c);
boolean flag = topRecord(str);
if (flag) {
handleNumber(str);
}
} else if ((c == ‘+‘ && e.keyCode == 107) || (c == ‘+‘ && e.keyCode == 61)
|| (c == ‘-‘ && e.keyCode == 109) || (c == ‘-‘ && e.keyCode == 173) || c == ‘*‘
|| c == ‘%‘) {// 61是+也是=,53此按钮%,173此按钮-,191你单击KeyDown了此按钮/
c = e.character;// "\r"
String markStr = String.valueOf(c);
boolean flag = topRecord(markStr);
if (flag) {
handleOperator(markStr);
}
} else if (e.keyCode == 108 || e.keyCode == 13 || (e.keyCode == 61 && c == ‘=‘)) {// 专门针对Enter就是=-=-e.keyCode==187+=
String markStr = "=";
boolean flag = topRecord(markStr);
if (flag) {
handleOperator(markStr);
}
buttonKey.forceFocus();
} else if (e.keyCode == 16777219) {// <--用户按了"Backspace"键e.keyCode
// == 8
String btnMark = "←左键删除";
// 用户按了"Backspace"键
handleBackspace(btnMark, labdownresult);//
// handleBackspace();/////????W
} else if (e.keyCode == 127 || e.keyCode == ‘C‘) {// Delete||C
// 用户按了"C"键
String btnMark = "C";
handleC(btnMark);
}
}
if (e.type == SWT.Selection) {
Button button = (Button) e.widget;
String btnText = button.getText();
// 获取事件源的标签
if (btnText.equals("←左键删除")) {// ←
String btnMark = "←左键删除";
// 用户按了"Backspace"键
handleBackspace(btnMark, labdownresult);//
} else if (btnText.equals("C")) {
// 用户按了"C"键
String btnMark = "C";
handleC(btnMark);
} else if ("0123456789.".indexOf(btnText) >= 0) {
// 用户按了数字键或者小数点键
// topRecord(btnText);
handleNumber(btnText);
// handlezero(zero);
} else if (btnText.equals("+") || btnText.equals("-") || btnText.equals("*")
|| btnText.equals("%除号") || btnText.equals("=默认焦点")) {
// 用户按了运算符键
if (btnText.equals("%除号"))
btnText = "%";
if (btnText.equals("=默认焦点"))
btnText = "=";
boolean flag = topRecord(btnText);
if (flag) {
handleOperator(btnText);
}
}
}
}
};
buttonKey.addListener(SWT.Selection, listener);
buttonKey.addListener(SWT.KeyDown, listener);
// 方案2键盘鼠标都兼容,不用=来切换的,就是把SWT.KeyDown放进循环里,但存在容易失效,
}
}
/**
* 处理Backspace键被按下的事件
*
* @param btnMark
*/
private void handleBackspace(String btnMark, Text downText) {
if (btnMark.equals("←左键删除")) {
btnMark="B";
FieldVerify.verifBackspace(btnMark, labdownresult);
String text = labdownresult.getText();/// W
int i = text.length();
if (i > 0) {
// 退格,将文本最后一个字符去掉
text = text.substring(0, i - 1);
if (text.length() == 0) {
// 如果文本没有了内容,则初始化计算器的各种值
labdownresult.setText("0");
firstDigit = true;
operator = "=";
} else {
// 显示新的文本
labdownresult.setText(text);
}
}
}
}
/**
* 处理Backspace键被按下的事件
*
* @param btnMark
*
* private void handleBackspace(String btnMark) { if
* (btnMark.equals("←左键删除")) { String text =
* labdownresult.getText();///W int i = text.length(); if (i > 0)
* { // 退格,将文本最后一个字符去掉 text = text.substring(0, i - 1); if
* (text.length() == 0) { // 如果文本没有了内容,则初始化计算器的各种值
* labdownresult.setText("0"); firstDigit = true; operator = "=";
* } else { // 显示新的文本 labdownresult.setText(text); } } } }
*/
/**
* 当前输入的操作符号是否需要记录显示
*
* @param key
* @return
*/
private boolean topRecord(String key) {
char c = key.charAt(0);
if (c >= ‘0‘ && c <= ‘9‘ && c != ‘.‘) {
} else if ((c == ‘+‘ || c == ‘-‘ || c == ‘*‘ || c == ‘%‘ || c == ‘=‘)) {
String downStr = labdownresult.getText();
String top = labtopNum.getText();
if (downStr.isEmpty() && top.isEmpty() && !key.equals("=")) {
labtopNum.setText(0 + key);
} else if (!downStr.isEmpty() && !top.isEmpty() && !key.equals("=")) {
String topMark = top.substring(top.length() - 1, top.length());
// double downParst = Double.parseDouble(downStr);
if (!operator.equals("=") && !key.equals("=") && firstDigit
&& (topMark.equals("+") || topMark.equals("-") || topMark.equals("*") || topMark.equals("%"))) {// 12+1+-
String topFirst = top.substring(0, top.length() - 1);// firstDigit是true证明没有新数没有输入进来
labtopNum.setText(topFirst + key);
// labdownresult.setText(downStr);
operator = key;/// 替换了符号,但符号不能去计算
return false;
}
else {
String str = labdownresult.getText();
// String str=String.valueOf(resultNum);
if (str.contains(".")) {
String first = str.substring(0, str.indexOf("."));
String last = str.substring(str.indexOf(".") + 1, str.length());
if (last.equals("0")) {
labtopNum.setText(top + first + key);
} else {
labtopNum.setText(top + str + key);
}
} else {
labtopNum.setText(top + str + key);
}
}
// labtopNum.setText(top+str+key);
} else if (!downStr.isEmpty() && !top.isEmpty() && operator.equals("=") && !key.equals("=")) {
// String str=labdownresult.getText();
String str = String.valueOf(resultNum);
if (str.contains(".")) {
String first = str.substring(0, str.indexOf("."));
String last = str.substring(str.indexOf(".") + 1, str.length());
if (last.equals("0")) {
labtopNum.setText(top + first + key);
} else {
labtopNum.setText(top + str + key);
}
} else {
labtopNum.setText(str + key);
}
// labtopNum.setText(top+str+key);
}
else if (!downStr.isEmpty() && top.isEmpty() && !key.equals("=")) {
String str = labdownresult.getText();
if (str.contains(".")) {
String first = str.substring(0, str.indexOf("."));
String last = str.substring(str.indexOf(".") + 1, str.length());
if (last.equals("0")) {
labtopNum.setText(first + key);
} else {
labtopNum.setText(str + key);
}
} else {
labtopNum.setText(str + key);
}
} else if (key.equals("=")) {
labtopNum.setText("");
}
}
return true;
}
/**
* 当前输入值及运算结果显示
*
* @param key
*/
private void handleNumber(String key) {
if (firstDigit && key.equals(".")) {
// 输入的第一个数字
labdownresult.setText(0 + key);
} else if (firstDigit) {
labdownresult.setText(key);
} else if ((key.equals(".")) && (labdownresult.getText().indexOf(".") < 0)
&& !labdownresult.getText().contains(".")) {
// 输入的是小数点,并且之前没有小数点,则将小数点附在结果文本框的后面
labdownresult.setText(labdownresult.getText() + ".");
} else if (!key.equals(".")) {
// 如果输入的不是小数点,则将数字附在结果文本框的后面
labdownresult.setText(labdownresult.getText() + key);
}
// 以后输入的肯定不是第一个数字了
firstDigit = false;
}
/**
* 处理C键被按下的事件
*
* @param btnMark
*/
private void handleC(String btnMark) {
if (btnMark.equals("C")) {
FieldVerify.verifCalc(labtopNum, labdownresult, btnMark, null);//为了防止线程失效
// 初始化计算器的各种值
resultNum = 0.0;// 为了清除上次保留的静态值
labdownresult.setText("0");
firstDigit = true;
operator = "=";
}
}
/**
* 处理C键被按下的事件
*
* @param btnMark
*
* private static void handleC(String btnMark) { if
* (btnMark.equals("C")) { String txtNum =
* labtopNum.getText();/////// if (!txtNum.isEmpty()) {
* labtopNum.setText(""); } // 初始化计算器的各种值 resultNum = 0.0;//
* 为了清除上次保留的静态值 labdownresult.setText("0"); firstDigit = true;
* operator = "="; }
*
* }
*/
/**
* 处理运算符键被按下的事件
*
* @param key
*/
private void handleOperator(String key) {
// operator = key;
if (operator.equals("%")) {
// 除法运算
// 如果当前结果文本框中的值等于0
if (getNumberFromText() == 0.0) {
// 操作不合法
operateValidFlag = false;
labdownresult.setText("除数不能为零");
} else {
if (key.equals("%"))
key = "/";
// resultNum /= getNumberFromText();
resultNum = div(resultNum, getNumberFromText());
}
} else if (operator.equals("+")) {
// 加法运算
// resultNum += getNumberFromText();
resultNum = add(resultNum, getNumberFromText());
} else if (operator.equals("-")) {
// 减法运算
// resultNum -= getNumberFromText();
resultNum = sub(resultNum, getNumberFromText());
} else if (operator.equals("*")) {
// 乘法运算
// resultNum *= getNumberFromText();
resultNum = mul(resultNum, getNumberFromText());
} else if (operator.equals("=")) {
// 赋值运算11+23+55;--resultNum=8--+3===-1+2+5+3
resultNum = getNumberFromText();
// labtopNum.setText("");
}
if (operateValidFlag) {
// 双精度浮点数的运算
long t1;
double t2;
t1 = (long) resultNum;
t2 = resultNum - t1;
if (t2 == 0) {
labdownresult.setText(String.valueOf(t1));
} else {
labdownresult.setText(String.valueOf(resultNum));
}
}
// 运算符等于用户按的按钮
operator = key;
firstDigit = true;
operateValidFlag = true;
}
/**
* 从结果文本框中获取数字
*
* @return
*/
private double getNumberFromText() {
double result = 0;
String down = labdownresult.getText();
try {
result = Double.valueOf(down).doubleValue();
} catch (NumberFormatException e) {
}
return result;
}
private static final int DEF_DIV_SCALE = 10;
/**
* * 两个Double数相加 *
*
* @param v1
* *
* @param v2
* *
* @return Double
*/
public static Double add(Double v1, Double v2) {
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
return new Double(b1.add(b2).doubleValue());
}
/**
* * 两个Double数相减 *
*
* @param v1
* *
* @param v2
* *
* @return Double
*/
public static Double sub(Double v1, Double v2) {
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
return new Double(b1.subtract(b2).doubleValue());
}
/**
* * 两个Double数相乘 *
*
* @param v1
* *
* @param v2
* *
* @return Double
*/
public static Double mul(Double v1, Double v2) {
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
return new Double(b1.multiply(b2).doubleValue());
}
/**
* * 两个Double数相除 * java 中的加减乘除
*
* @param v1
* *
* @param v2
* *
* @return Double
*/
public static Double div(Double v1, Double v2) {
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
return new Double(b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue());
}
// /**
// * * 两个Double数相除,并保留scale位小数 *
// *
// * @param v1 *
// * @param v2 *
// * @param scale *
// * @return Double
// */
// public static Double div(Double v1, Double v2, int scale) {
// if (scale < 0) {
// throw new IllegalArgumentException(
// "The scale must be a positive integer or zero");
// }
// BigDecimal b1 = new BigDecimal(v1.toString());
// BigDecimal b2 = new BigDecimal(v2.toString());
// return new Double(b1.divide(b2, scale,
// BigDecimal.ROUND_HALF_UP).doubleValue());
// }
public void open(boolean isCenter, MyAsyncCallback cbOpen) {
this.cbOpen = cbOpen;
closed = false;
try {
createShell();
if (!closed)
shell.open();
if (isCenter) {
UC.centerShell(shell);
// onCreateShell(shell);
}
} catch (Exception e) {
e.printStackTrace();
}
}
protected void onCreateButtons(Composite composite) {
// Button context = new Button(composite,SWT.BORDER|SWT.MULTI);
// //Text context = new Text(composite, SWT.BORDER|SWT.MULTI);
// GridData gridData0 = new GridData(SWT.FILL, SWT.FILL, true, false);
// context.setLayoutData(gridData0);
// context.setText("使用说明:键盘操作=默认焦点,等于号选中;上下左右键里<—左键删除最后一位数,Delete全删");
Button button = new Button(composite, SWT.BORDER);
GridData gridData1 = new GridData(SWT.FILL, SWT.FILL, true, false);
button.setLayoutData(gridData1);
button.setBackground(UC.getColor());
button.setText("关闭");
button.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent arg0) {
resultNum = 0.0;
close();
}
@Override
public void widgetDefaultSelected(SelectionEvent arg0) {
// TODO Auto-generated method stub
}
});
}
public final void close() {
closed = true;
shell.close();
}
}