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

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

ただいまの
回答率

88.19%

java GUI 電卓 四則演算ボタン アクション追加

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,727

3d2y

score 4

前提・実現したいこと

java初心者も初心者です。
電卓を作っています。
ボタンにまとめてアクションを追加できなかったので、ボタン一つ一つにアクションを追加したいと思っています。
それぞれの四則演算ボタンを押したら計算できるようにしたいのですが、どのサイトを調べてもまとめたやり方しか載っていないのでできません。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.*;
import java.awt.event.*;

public class calculator extends JFrame{
private static final long serialVersionUID = 1L;
public static void main(String[] args){
calculator frame = new calculator();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 350, 300);
frame.setTitle("Calculator");
frame.setVisible(true);    

}

calculator(){

JTextField result = new JTextField(""); 
add(result, BorderLayout.NORTH);

JButton button1 = new JButton("1");
JButton button2 = new JButton("2");
JButton button3 = new JButton("3");
JButton button4 = new JButton("4");
JButton button5 = new JButton("5");
JButton button6 = new JButton("6");
JButton button7 = new JButton("7");
JButton button8 = new JButton("8");
JButton button9 = new JButton("9");
JButton button10 = new JButton("0");
JButton button11 = new JButton("+");
JButton button12 = new JButton("-");
JButton button13 = new JButton("=");
JButton button14 = new JButton("×");
JButton button15 = new JButton("00");
JButton button16 = new JButton("000");
JButton button17 = new JButton("C");

button1.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("1");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button2.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("2");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button3.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("3");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button4.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("4");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button5.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("5");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button6.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("6");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button7.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("7");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button8.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("8");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button9.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("9");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button10.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("0");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button15.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("00");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

button16.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String keyNumber = this.getText(); 
appendResult("000");
}
private String getText() {
// TODO 自動生成されたメソッド・スタブ
return null;
}
public void appendResult(String c) {
boolean afterCalc = false;
if (!afterCalc)
result.setText(result.getText() + c); 
else {
result.setText(c);
afterCalc = false;
}
}
}
);

JPanel keyPanel = new JPanel();
keyPanel.setLayout(new GridLayout(4, 4));
add(keyPanel, BorderLayout.CENTER);

keyPanel.add(button7);
keyPanel.add(button8);
keyPanel.add(button9);
keyPanel.add(button11);
keyPanel.add(button4);
keyPanel.add(button5);
keyPanel.add(button6);
keyPanel.add(button12);
keyPanel.add(button1);
keyPanel.add(button2);
keyPanel.add(button3);
keyPanel.add(button14);
keyPanel.add(button10);
keyPanel.add(button15);
keyPanel.add(button16);
keyPanel.add(button13);

add (button17, BorderLayout.SOUTH);
button17.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
double stackedValue = 0.0; 
boolean isStacked = false; 
boolean afterCalc = false;
result.setText("");
}
}
);
this.setVisible(true);

}
}

試したこと

まとめたやり方のコードの一部を切り取ってはるなどして見ましたが、無理でした。

eclipseで起動しています。

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 3d2y

    2019/11/13 10:26

    サイト上では「数字を入力するボタン」と「演算子ボタン」を区別し、「演算子ボタン」については
    /* 演算子ボタンを定義 */
    public class CalcButton extends JButton implements ActionListener {
    private static final long serialVersionUID = 1L;

    public CalcButton(String op) {
    super(op);
    this.addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
    if (isStacked) { //以前に演算子ボタンが押されたのなら計算結果を出す
    double resultValue = (Double.valueOf(result.getText()))
    .doubleValue();
    if (currentOp.equals("+")) //演算子に応じて計算する
    stackedValue += resultValue;
    else if (currentOp.equals("-"))
    stackedValue -= resultValue;
    else if (currentOp.equals("×"))
    stackedValue *= resultValue;
    else if (currentOp.equals("÷"))
    stackedValue /= resultValue;
    result.setText(String.valueOf(stackedValue)); //計算結果をテキストフィールドに設定
    }
    currentOp = this.getText(); //ボタン名から押されたボタンの演算子を取り出す
    stackedValue = (Double.valueOf(result.getText())).doubleValue();
    afterCalc = true;
    if (currentOp.equals("="))
    isStacked = false;
    else
    isStacked = true;
    }
    }
    と、まとめて演算を行うようにプログラムされていると思います。
    しかし、私はボタンをすべてバラバラに作ってしまったため、それができません。なので、「+ボタン」、すなわち私のコード上では「button11」に加算の機能を与えたいのです。

    キャンセル

  • jimbe

    2019/11/13 11:34

    なるほど, まとめたやり方は分かりました.
    それで, バラバラに作ったものを「まとめたやり方」に直すのではなく, バラバラの状態で同じ機能を実現したいということですね.
    ところで, CalcButton の ActionListener 部分は, 良く見ると単体のクラスに抜き出せます. ActionListener 部分を抜き出せば CalcButton は JButton で済むようになります. そのような形でも宜しいですか?

    キャンセル

  • 3d2y

    2019/11/13 11:38

    その通りです。
    それで、加算・減算・乗算ができるようになるのなら願ってもないことです。
    よろしくお願いします。

    キャンセル

回答 2

0

すぐ目についた点をお知らせします。

演算記号のイベントリスナーが未定義なので計算する機能がコーディングされていないように見えます。

また今ある数字入力のイベントリスナーの if 文は、直前に判定用の変数である afterCalc に固定で false を設定しているので else 側の処理が動くことはありません。

四則演算としながら割り算用のボタンが無いですね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/13 11:21

    ご指摘ありがとうございます。
    演算記号のイベントリスナーの作り方がわからないのです…
    +が押下されたら今テキストフィールドに入っている数字を記憶し、その後に入力された数字と加算を行うという仕組みを作りたいのです。
    割り算は少数が現れる可能性があるので今回は意図的に省きました。

    キャンセル

0

オリジナルの CalcButton はフィールドを持たないため, ActionListener を
抜き出します.
getText() は JButton のメソッドですので, ActionEvent 経由で取得します.

  public class CalcActionListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      if (isStacked) { //以前に演算子ボタンが押されたのなら計算結果を出す
        double resultValue = (Double.valueOf(result.getText()))
            .doubleValue();
        if (currentOp.equals("+")) //演算子に応じて計算する
          stackedValue += resultValue;
        else if (currentOp.equals("-"))
          stackedValue -= resultValue;
        else if (currentOp.equals("×"))
          stackedValue *= resultValue;
        else if (currentOp.equals("÷"))
          stackedValue /= resultValue;
        result.setText(String.valueOf(stackedValue)); //計算結果をテキストフィールドに設定
      }
      //currentOp = this.getText(); //ボタン名から押されたボタンの演算子を取り出す
      currentOp = ((JButton)e.getSource()).getText();
      stackedValue = (Double.valueOf(result.getText())).doubleValue();
      afterCalc = true;
      if (currentOp.equals("="))
        isStacked = false;
      else
        isStacked = true;
    }
  }

このインスタンスを各演算子ボタンに addActionListener します.

  ActionListener calcActionListener = new CalcActionListener();
  button11.addActionListener(calcActionListener);
  button12.addActionListener(calcActionListener);
  button13.addActionListener(calcActionListener);
  button14.addActionListener(calcActionListener);

なお, やたらと並んでいる数字ボタン(オリジナルの NumberButton )も, 同様にできます.
恐らく ActionListener を抜き出す際に JButton.getText が使えなくなって全部個別に並べることになったものと思います.

  public class NumberActionListener implements ActionListener {
    public void actionPerformed(ActionEvent evt) {
      //String keyNumber = this.getText();
      String keyNumber = ((JButton)evt.getSource()).getText(); //ボタンの名前を取り出す
      appendResult(keyNumber); //ボタンの名前をテキストフィールドにつなげる
    }
    /* テキストフィールドに引数の文字列をつなげる */
    public void appendResult(String c) {
      if (!afterCalc) //演算子ボタンを押した直後でないなら
        result.setText(result.getText() + c); //押したボタンの名前をつなげる
      else {
        result.setText(c); //押したボタンの文字列だけを設定する(いったんクリアしたかに見える)
        afterCalc = false;
      }
    }
  }
  ActionListener numberActionListener = new NumberActionListener ();
  button1.addActionListener(numberActionListener);
  button2.addActionListener(numberActionListener);
  button3.addActionListener(numberActionListener);
  button4.addActionListener(numberActionListener);
  (以下略)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/14 10:48

    これは後の部分に挿入したらいいんですか。

    キャンセル

  • 2019/11/14 10:50

    これはどの部分に挿入したらいいんですか。

    キャンセル

  • 2019/11/14 11:48

    リスナは, オリジナルのボタンクラスから取り出して修正しました.
    どちらも DentakuFrame でのフィールドにアクセスしていますので, calculator クラスの構造に合わせて修正・配置してくださいって結構です.

    キャンセル

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

  • ただいまの回答率 88.19%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る