質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

3回答

8712閲覧

JavaのSwingを使って電卓を作っていますが詰みました

nasulrj

総合スコア38

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

2クリップ

投稿2015/11/19 12:03

初めて質問します。
Javaを勉強し始めてまだ日が浅いです。
今Javaのswingを使ってGUIな電卓を作っています。
そこでわからないところが出てきたので教えて下さい。
なるべくシンプルなソースコードでお願いしますm(_ _)m

<サンプル電卓>
https://gyazo.com/fdfb8fde31e145ec09dccaa3e4cb5efc

上記の画像のように文字を連結して表示するところまではうまく行ったのですが、
+を押してもこのままだとずっと連結しているので、四則演算記号のボタンを押すと連結を解除するにはどうすればよろしいのでしょうか?

また電卓らしく四則演算もさせたいのですが、1+2の1の値は格納できるのですが、2の値はどのように格納すればいいのか検討がつかないのでこちらも合わせて質問いたします。

なるべく急ぎでよろしくお願いします。

/*電卓画面設計部分*/ //電卓答え表示画面 /*0だけ別のラベルを設置する-1桁目0のとき連結防止*/ lbl_0 = new JLabel("0",JLabel.RIGHT); lbl_0.setPreferredSize(new Dimension(250,50)); lbl_0.setBorder(new LineBorder(Color.BLUE, 2, true)); lbl_0.setFont(new Font("Arial", Font.PLAIN, 28)); //電卓表示画面1段目 lbl_a = new JLabel("",JLabel.RIGHT); lbl_a.setPreferredSize(new Dimension(250,50)); lbl_a.setBorder(new LineBorder(Color.BLUE, 2, true)); lbl_a.setFont(new Font("Arial", Font.PLAIN, 28)); lbl_b = new JLabel("",JLabel.RIGHT); lbl_b.setPreferredSize(new Dimension(250,50)); lbl_b.setBorder(new LineBorder(Color.BLUE, 2, true)); lbl_b.setFont(new Font("Arial", Font.PLAIN, 28)); //Button設計 btn0 = new JButton("0"); btn1 = new JButton("1"); btn2 = new JButton("2"); btn3 = new JButton("3"); btn4 = new JButton("4"); btn5 = new JButton("5"); btn6 = new JButton("6"); btn7 = new JButton("7"); btn8 = new JButton("8"); btn9 = new JButton("9"); btnp = new JButton("+"); btnm = new JButton("―"); btnd = new JButton("÷"); btnk = new JButton("×"); btne = new JButton("="); panel = new JPanel(); panel.setLayout(new GridLayout(5, 4)); panel.add(btn7); panel.add(btn8); panel.add(btn9); panel.add(btn4); panel.add(btn5); panel.add(btn6); panel.add(btn1); panel.add(btn2); panel.add(btn3); panel.add(btn0); panel.add(btnp); panel.add(btnm); panel.add(btnk); panel.add(btnd); panel.add(btne); //ActionListener設置 btn0.addActionListener(this); btn1.addActionListener(this); btn2.addActionListener(this); btn3.addActionListener(this); btn4.addActionListener(this); btn5.addActionListener(this); btn6.addActionListener(this); btn7.addActionListener(this); btn8.addActionListener(this); btn9.addActionListener(this); btnp.addActionListener(this); btnm.addActionListener(this); btnk.addActionListener(this); btnd.addActionListener(this); //各部品をJFrameに設置 this.add(lbl_0,BorderLayout.NORTH); this.add(lbl_q, BorderLayout.CENTER); this.add(panel, BorderLayout.SOUTH); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(250, 350); this.setVisible(true); } public static void main(String[]args){ dentaku app = new dentaku("サンプル電卓"); } public void actionPerformed(ActionEvent ae) { // TODO 自動生成されたメソッド・スタブ JButton source = (JButton)ae.getSource(); StringBuilder temp =new StringBuilder(); //ラベル差し替え lbl_0.setText(""); this.add(lbl_a,BorderLayout.NORTH); //buttonが押された時の処理 if (source == this.btn0){ temp.append("0"); }else if(source == this.btn1){ temp.append("1"); }else if(source == this.btn2){ temp.append("2"); }else if(source == this.btn3){ temp.append("3"); }else if(source == this.btn4){ temp.append("4"); }else if(source == this.btn5){ temp.append("5"); }else if(source == this.btn6){ temp.append("6"); }else if(source == this.btn7){ temp.append("7"); }else if(source == this.btn8){ temp.append("8"); }else if(source == this.btn9){ temp.append("9"); } lbl_a.setText(lbl_a.getText()+temp); if(source == this.btnp || source == this.btnm || source == this.btnk || source == this.btnd){ //1+2の1の部分格納 float before=Float.parseFloat((String)lbl_a.getText()+temp); } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ざっと目を通しただけですが、

最初に気が付いた点から、

まず、UIを作った後で内部のロジックをお考えになったと推測しますが、プログラミングに入る前にデータの流れを考慮して内部ロジックを組み立てられたら良かったと思います。

また、イベントリスナ内で値保持用の変数を宣言されているのが気になります。イベントのたびに初期化されています。値の一時保存先と格納先の区分が逆のように思います。が、提示されたコード何か・・・

強いて言うなら、値を格納先に退避させたあとは、一時保存先の変数はNULLにする。値を格納する際は既に格納されている値と演算処理後に格納する。演算処理は前回押下した演算キーに依存する。つまり四則演算させるには、4つの状態の間を遷移する。

とにかく、ロジックを最初に決めてから、プログラミングされることを提案いたします。

投稿2015/11/19 16:08

blackonyx

総合スコア354

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nasulrj

2015/11/19 22:51

お見苦しい中回答とヒントありがとうございますm(__)m 更に質問で申し訳ありませんが、ロジックというのは、プログラムの設計書みたいなものでしょうか?
blackonyx

2015/11/19 23:49

「流れ(フロー)」といいますか、何をどうして、こうするとかいうやつです。
nasulrj

2015/11/20 03:34

ありがとうございます。 また質問する際は載せるようにします。 ありがとうございましたm(__)m
guest

0

ベストアンサー

個人的に、こういうのはクラスを作ってしまいたいです。

下のように値保持、計算処理を纏めたものです。
(結構適当に書いているので、使う場合はカスタマイズしてください。)

Java

1//電卓用値保持クラス 2public class Calculation { 3 private static String LEFT_NUM = ""; 4 private static String RIGHT_NUM = ""; 5 private static String OPERATOR = ""; 6 7 //文字列を足す処理 8 public static void append(String s){ 9 int temp_int = 0; 10 if(s.equals("=")){ 11 return; // =は対象外 12 } 13 boolean opeFlag = false; 14 try{ 15 temp_int = Integer.parseInt(s); 16 }catch(NumberFormatException e){ 17 //ここに入るのは演算子の場合 18 opeFlag = true; 19 } 20 if(opeFlag){ 21 //演算子の場合 22 OPERATOR = s; //演算子を上書き 23 }else if(OPERATOR.length() == 0){ 24 //左辺の場合 25 LEFT_NUM += s; //数字を連結 26 }else{ 27 //右辺の場合 28 RIGHT_NUM += s; //数字を連結 29 } 30 } 31 32 //計算式の文字列を返却 33 public static String toStr(){ 34 return LEFT_NUM + " " + OPERATOR + " " + RIGHT_NUM; 35 } 36 37 //計算実処理 計算実施後、計算結果を返す 38 public static String calc(){ 39 String workRes = ""; 40 int workLeft = 0; 41 int workRight = 0; 42 try{ 43 if(LEFT_NUM.length() != 0){ 44 workLeft = Integer.parseInt(LEFT_NUM); 45 }else{ 46 return ""; 47 } 48 if(RIGHT_NUM.length() != 0){ 49 workRight = Integer.parseInt(RIGHT_NUM); 50 }else{ 51 return ""; 52 } 53 }catch(NumberFormatException e){ 54 //ここには基本的に入らない 55 return ""; 56 } 57 if(OPERATOR.equals("+")){ 58 workRes = String.valueOf(workLeft + workRight); 59 }else if(OPERATOR.equals("―")){ 60 workRes = String.valueOf(workLeft - workRight); 61 }else if(OPERATOR.equals("×")){ 62 workRes = String.valueOf(workLeft * workRight); 63 }else if(OPERATOR.equals("÷")){ 64 workRes = String.valueOf(workLeft / workRight); 65 }else { 66 return ""; 67 } 68 //変数群の初期化 69 LEFT_NUM = workRes; 70 RIGHT_NUM = ""; 71 OPERATOR = ""; 72 return workRes; 73 } 74}

↑のクラスを追加し、actionPerformedに以下の修正を行うと動くと思います。
・temp.append
→Calculation.append
・lbl_a.setText(lbl_a.getText()+temp);
→lbl_a.setText(Calculation.toStr());
・=ボタンが押された場合の処理を追加
(Calculation.calc()を実行)

なお、static変数、メソッドを使用しているのは、面倒だからです。
本当は普通にインスタンスを生成して使う方がいいです。

投稿2015/11/20 01:21

moredeep

総合スコア1507

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nasulrj

2015/11/20 03:38

ソースコード付きの回答ありがとうございます。 作る際、参考に致します。 そういう考え方もあるのですね。
guest

0

「1+2」で「1」の部分が取得できたなら、「1」と演算子(ここでは「+」)を別の変数に退避させておいて、tempというStringBuilderをクリアして2の部分の文字列を構築いけばできそうですね。

投稿2015/11/19 23:59

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nasulrj

2015/11/20 03:36

回答ありがとうございます。 なるほどシンプルでいい案です。 作る際に参考致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問