簡易関数電卓JsCalcWをさらにもうちょっと改良してみました。(^_^;
何かちょっと足らないと思っていたら、[Ans]アンサーキーを付けるのを忘れていました。(^_^;
ついでに、[M]キーも電卓っぽい感じが出るように、[MC],[MR],[MS],[M+],[M-]と増やしてみました。(^_^;
おまけに、関数キーもいくつか([Rad],[Deg],[Rnd],[x!],[int])追加しておきました。(^_^;
P.S.
メモリーをただの変数 M から内部メモリーに変更しました。仕様はソースを参照して下さい。(^_^;
● JsCalcW5.java
import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; import javax.script.*; public class JsCalcW5 { // JsCalcW.java [java] public static void main(final String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } private static void createAndShowGUI() { // フレームの作成 JFrame frame = new JFrame("JsCalcW"); // JFrameオブジェクトを生成 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // ウィンドウを閉じるとプログラムが終了 MyPanel h = new MyPanel(); frame.add(h, BorderLayout.CENTER); // フレームにオブジェクトを置く frame.pack(); // フレームを必要最小の大きさにする frame.setMinimumSize(new Dimension(frame.getSize().width, frame.getSize().height)); // 最小サイズを指定 1.6以上で有効 frame.setAlwaysOnTop(true); // 最前面ウィンドウへ設定します frame.setVisible(true); // フレームを表示する } } class MyPanel extends JPanel implements ActionListener { // JPanelを継承 JButton btn1, btn2; JTextField txt1, txt2; JLabel lbl1 = new JLabel(); ArrayList<String> sHis = new ArrayList<String>(); int iCnt = 0; JsCalc jsc = new JsCalc(); String Ans = "", Mem = "0.0"; // 追加ボタンの設定 String [] sBtD = { // 表示用 "arc","hyp","sin","cos","tan", "Rad","Deg","Rnd","x!","int", "x^y","10^x","exp","ln","log", "Ans","1/x","3√","π","e", "MC","MR","MS","M+","M−", "7","8","9","÷","CE", "4","5","6","×","√", "1","2","3","−","%", "0",".","(","+",")" }; String [] sBtO = { // 出力用 "a","h()","sin()","cos()","tan()", "Rad()","Deg()","Rnd()","fact()","floor()", "pow(,)","ten()","exp()","ln()","log10()", "","rcp()","cbrt()","PI","E", "","","","","", "7","8","9","/","", "4","5","6","*","sqrt()", "1","2","3","-","%", "0",".","(","+",")" }; int nBtn = sBtD.length; // 追加するボタンの数 JButton[] aBtn = new JButton[nBtn]; // 追加ボタン public MyPanel() { setBackground(SystemColor.control); // 背景を灰色にする txt1 = new JTextField(14); // txtの設定 txt1.addActionListener(this); txt1.addKeyListener(new MyKeyListener()); // リスナーオブジェクトを指定 txt1.setFont(new Font("SansSerif",Font.PLAIN,16)); txt2 = new JTextField(14); // txtの設定 txt2.setFont(new Font("SansSerif",Font.ITALIC,16)); txt2.setHorizontalAlignment(JTextField.RIGHT); btn1 = new JButton("="); btn1.addActionListener(this); btn1.addMouseListener(new MyMouseAdapter()); // ボタン上での右クリック btn2 = new JButton("C"); btn2.addActionListener(this); btn2.addMouseListener(new MyMouseAdapter()); // ボタン上での右クリック for(int i = 0; i< nBtn; i++) aBtn[i] = new JButton(sBtD[i]); for(JButton b : aBtn) b.addActionListener(this); JPanel pa = new JPanel(); pa.setLayout(new BorderLayout(2,2)); pa.add(txt1, BorderLayout.NORTH); pa.add(txt2, BorderLayout.CENTER); pa.add(lbl1, BorderLayout.WEST); JPanel pb = new JPanel(); pb.setLayout(new GridLayout(2,1,2,2)); pb.add(btn1); pb.add(btn2); JPanel pc = new JPanel(); pc.setLayout(new GridLayout(nBtn/5,5,2,2)); for(JButton b : aBtn) pc.add(b); setLayout(new BorderLayout(2,2)); add(pa, BorderLayout.CENTER); add(pb, BorderLayout.EAST); add(pc, BorderLayout.SOUTH); sHis.add(""); iCnt = sHis.size()-1; } public void actionPerformed(ActionEvent e) { // ボタンクリック if(e.getSource()==btn1||e.getSource()==txt1) { String s = txt1.getText(); sHis.add(s); iCnt = sHis.size()-1; Ans = jsc.sEval(s); txt2.setText(Ans); txt1.select(0,s.length()); } else if(e.getSource()==btn2) { txt1.setText(""); txt2.setText(""); } else if(e.getSource()==aBtn[Arrays.asList(sBtD).indexOf("CE")]) { String s = txt1.getText(); // [CE]ボタンの処理 int stt = txt1.getSelectionStart(); int end = txt1.getSelectionEnd(); if(stt> end) { int t = stt; stt = end; end = t; } if(stt==end && stt> 0){ // BS s = s.substring(0,stt-1)+s.substring(stt); txt1.setText(s); txt1.setCaretPosition(stt-1); }else if(stt< end){ // Cut txt1.cut(); } } else if(e.getSource()==aBtn[Arrays.asList(sBtD).indexOf("Ans")]) { setStrings(Ans); // [Ans]ボタンの処理 } else if(e.getSource()==aBtn[Arrays.asList(sBtD).indexOf("MC")]) { Mem = "0.0"; lbl1.setText(""); // [MC]ボタンの処理 } else if(e.getSource()==aBtn[Arrays.asList(sBtD).indexOf("MR")]) { setStrings(Mem); // [MR]ボタンの処理 } else if(e.getSource()==aBtn[Arrays.asList(sBtD).indexOf("MS")]) { Mem = txt2.getText(); // [MS]ボタンの処理 if(Mem.equals("") || Mem.contains("error: ")) Mem = "0.0"; if(Mem.equals("0.0")) lbl1.setText(""); else lbl1.setText("M"); } else if(e.getSource()==aBtn[Arrays.asList(sBtD).indexOf("M+")]) { String s = txt2.getText(); if(s.equals("") || s.contains("error: ")) s = "0.0"; Mem = jsc.sEval(Mem+"+"+s); // [M+]ボタンの処理 if(Mem.equals("0.0")) lbl1.setText(""); else lbl1.setText("M"); } else if(e.getSource()==aBtn[Arrays.asList(sBtD).indexOf("M−")]) { String s = txt2.getText(); if(s.equals("") || s.contains("error: ")) s = "0.0"; Mem = jsc.sEval(Mem+"-("+s+")"); // [M−]ボタンの処理 if(Mem.equals("0.0")) lbl1.setText(""); else lbl1.setText("M"); } for(int i = 0; i< nBtn; i++) if(e.getSource()==aBtn[i] && sBtO[i]!="") setStrings(sBtO[i]); txt1.requestFocus(); } public void setStrings(String s) { int stt = txt1.getSelectionStart(); int end = txt1.getSelectionEnd(); int n = 0; if (s.contains("()") ) n = 1; else if (s.contains("(,)")) n = 2; if (s=="Rnd()") n = 0; if (stt> end) { int t = stt; stt = end; end = t; } String t = txt1.getText(); t=t.substring(0,stt)+s+t.substring(end); txt1.setText(t); txt1.setCaretPosition(stt+s.length()-n); } class MyKeyListener extends KeyAdapter { // リスナークラス public void keyPressed(KeyEvent e){ int k = e.getKeyCode(); if (k == KeyEvent.VK_DOWN) { iCnt++; if(iCnt> sHis.size()) iCnt = sHis.size(); txt2.setText(""); txt1.setText(sHis.get(iCnt % sHis.size())); } else if(k == KeyEvent.VK_UP) { iCnt--; if(iCnt< 1) iCnt = 1; txt2.setText(""); txt1.setText(sHis.get(iCnt % sHis.size())); } } } class MyMouseAdapter extends MouseAdapter { public void mouseClicked(MouseEvent e) { // 右クリックが押されたかどうかの判定 if(e.getModifiers()!=MouseEvent.BUTTON3_MASK) return; if (e.getSource()==btn1) setStrings("="); else if (e.getSource()==btn2){ txt1.setText(""); txt2.setText(""); // [C] Mem = "0.0"; lbl1.setText(""); // [MC] } txt1.requestFocus(); } } } class JsCalc { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("JavaScript"); //--- コンストラクター ---// JsCalc() { defUserFunc(); // ユーザー定義関数の設定 } // JavaでJavaScriptのeval()関数を呼び出す public String sEval(String sExpr) { String sScript = "with(Math){"+sExpr+"}"; // 「Math.」を省略可にするため try{ return( engine.eval(sScript).toString() ); } catch(Exception e) { return("error: "+e); } } // ユーザー定義関数の設定 private void defUserFunc() { sEval("radians = function(x) {return(x*PI/180);}"); sEval("degrees = function(x) {return(x/PI*180);}"); sEval("sinDeg = function(x) {return(sin(radians(x)));}"); sEval("cosDeg = function(x) {return(cos(radians(x)));}"); sEval("tanDeg = function(x) {return(tan(radians(x)));}"); sEval("gcd = function(a,b) {return((b == 0)? a : gcd(b,a%b));}"); sEval("lcm = function(a,b) {return(a*(b/gcd(a,b)));}"); String sScript = ""; sScript = "horner = function(coeff,x) {var r=0;" + "for(var i=0; i< coeff.length; i++){r=r*x+coeff[i];}" + "return(r);}"; sEval(sScript); sScript = "sum = function(a) {var sum=0;" + "for(var i=0; i< a.length; i++) sum+=a[i];" + "return(sum);}"; sEval(sScript); // 関数を追加(JsCalcW3から) sScript = "sign = function(x) {x=+x;" + "if(x===0||isNaN(x)){return x;}" + "return (x> 0)?1:-1;}"; sEval(sScript); sEval("cbrt = function(x) {return sign(x)*pow(abs(x),1/3);}"); sEval("rcp = function(x) {return 1/x;}"); sEval("Rnd = function() {return random();}"); sEval("sinh = function(x) {return (exp(x)-exp(-x))/2;}"); sEval("sinh = function(x) {return (exp(x)-exp(-x))/2;}"); sEval("cosh = function(x) {return (exp(x)+exp(-x))/2;}"); sScript = "tanh = function(x) {" + "if(abs(x)===Infinity){return sign(x);}" + "else{var y=exp(2*x);return (y-1)/(y+1);}}"; sEval(sScript); sEval("asinh = function(x) {return(x===-Infinity)?x:log(x+sqrt(x*x+1));}"); sEval("acosh = function(x) {return log(x+sqrt(x*x-1));}"); sEval("atanh = function(x) {return log((1+x)/(1-x))/2;}"); sEval("ln = function(x) {return log(x);}"); sEval("log10 = function(x) {return log(x)/LN10;}"); sEval("ten = function(x) {return pow(10,x);}"); sEval("log_ = function(a,x) {return log(x)/log(a);}"); // 関数を追加(JsCalcW5から) sEval("Rad = function(x) {return radians(x);}"); sEval("Deg = function(x) {return degrees(x);}"); sEval("fact = function(x) {var r=1; for(var i=2; i<=min(x,171); r*=i++); return r;}"); // 後はご自由に追加してください。 sEval(""); } }
※参考URL
http://stackoverflow.com/questions/3959211/fast-factorial-function-in-javascript
●簡易関数電卓JsCalc - Java
●簡易関数電卓JsCalcをGUI化してみた。JsCalcW - Java
●簡易関数電卓JsCalcをGUI化してみた。JsCalcW - Java (2)
●簡易関数電卓JsCalcをGUI化してみた。JsCalcW - Java (3)
●簡易関数電卓JsCalcWを改良してみた。
- 作者: 立木秀樹,有賀妙子
- 出版社/メーカー: 共立出版
- 発売日: 2007/09/22
- メディア: 単行本
- 購入: 1人 クリック: 2回
- この商品を含むブログを見る
鉛筆パズルゲームプログラミング ナンバープレース・お絵かきパズル・ナンバークロスワードのアルゴリズム
- 作者: 棚床弘樹
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2007/06/27
- メディア: 大型本
- 購入: 2人 クリック: 23回
- この商品を含むブログ (28件) を見る