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

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

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

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

2回答

291閲覧

JavaEclipse setTextが上手くいかない

nonfi

総合スコア0

Java

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

0クリップ

投稿2024/12/23 09:09

編集2024/12/30 14:43

実現したいこと

・numActionでは、1~9のボタンのどれかを押したとき、選択されているテキストフィールドに出力したい(135とおしたら135で出力)
・PmActionでテキストフィールドに入力された数字の符号を入れ替え、またテキストフィールドに出力したい

前提

JavaEclipseで電卓のプログラムを作っています。
二点上手くいかない部分がありますが原因は共通していると思われます。

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

まず、numActionでは、123というように、順番通りに数字を押すと上手くテキストフィールドに表示されますが、157や81などバラバラに押すとテキストフィールドが勝手に空にされてしまいます。
PmActionでは、+/-ボタンを押すと、テキストフィールドに何も表示されなくなります。printlnしてみるとしっかり符号が逆になっているのでテキストフィールドに出力する部分に問題があると考えられます。
空白にしない限りエラーコードは出ません。

該当のソースコード

lang

1 2public class Calculator extends JFrame { 3 4 JTextField input,input2,way, answer; 5 JButton plus, minus, multiple, divide, result, clear, pm, percent, del, few, num, zero; 6 double num1, num2; 7 // String operator = ""; 8 JTextField currentFocusField; // フォーカスされているフィールドを追跡する変数 9 10 public static void main(String[] args) { 11 JFrame w = new Calculator("Calculator"); 12 w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 13 w.setSize(350, 400); 14 w.setVisible(true); 15 } 16 17 public Calculator(String title) { 18 super(title); 19 JPanel pane = (JPanel) getContentPane(); 20 pane.setLayout(new BorderLayout()); 21 22 JPanel tfpanel=new JPanel(); 23 tfpanel.setLayout(new GridLayout(1,2)); 24 input = new JTextField(5); 25 input.setBorder(new TitledBorder("数1")); 26 input.setDocument(new NumericDocument()); 27 input.addFocusListener(new FocusAdapter() { 28 @Override 29 public void focusGained(FocusEvent e) { 30 currentFocusField = input; // inputがフォーカスされた時 31 } 32 }); 33 tfpanel.add(input); 34 way = new JTextField(1); 35 way.setBorder(new TitledBorder("計算方法")); 36 way.setDocument(new NumericDocument2()); 37 tfpanel.add(way); 38 input2 = new JTextField(5); 39 input2.setBorder(new TitledBorder("数2")); 40 input2.setDocument(new NumericDocument()); 41 input2.addFocusListener(new FocusAdapter() { 42 @Override 43 public void focusGained(FocusEvent e) { 44 currentFocusField = input2; // input2がフォーカスされた時 45 } 46 }); 47 tfpanel.add(input2); 48 49 pane.add(tfpanel, BorderLayout.NORTH);//数式を入力するフィールドの設置 50 51 answer = new JTextField(5); 52 answer.setBorder(new TitledBorder("結果")); 53 pane.add(answer, BorderLayout.SOUTH);//計算結果を表示するフィールドの設置 54 55 JPanel leftpanel = new JPanel(); 56 leftpanel.setLayout(new GridLayout(5, 3)); 57 leftpanel.setPreferredSize(new Dimension(270, 400)); 58 59 clear = new JButton(new ClearAction()); 60 leftpanel.add(clear);//クリアボタン 61 62 pm = new JButton(new PmAction()); 63 leftpanel.add(pm);//+-切り替えボタン 64 65 percent = new JButton(new PercentAction()); 66 leftpanel.add(percent);//%表示切り替えボタン 67 68 for (int i = 1; i <= 9; i++) { 69 num = new JButton(new numAction(Integer.toString(i))); 70 leftpanel.add(num); 71 }//1~9の番号ボタン 72 73 del = new JButton(new DelAction()); 74 leftpanel.add(del);//削除ボタン 75 76 zero=new JButton(new ZeroAction()); 77 leftpanel.add(zero); 78 79 pane.add(leftpanel, BorderLayout.CENTER); 80 81 JPanel rightpanel = new JPanel(); 82 rightpanel.setLayout(new GridLayout(5, 1)); 83 84 plus = new JButton(new PlusAction()); 85 rightpanel.add(plus); 86 minus = new JButton(new MinusAction()); 87 rightpanel.add(minus); 88 multiple = new JButton(new MultipleAction()); 89 rightpanel.add(multiple); 90 divide = new JButton(new DivideAction()); 91 rightpanel.add(divide); 92 result = new JButton(new ResultAction()); 93 rightpanel.add(result); 94 95 pane.add(rightpanel, BorderLayout.EAST); 96 input.requestFocus(); // ここでinputに初期フォーカスを設定 97 } 98 99 // Arithmetic Operations 100 class PlusAction extends AbstractAction { 101 PlusAction() { 102 putValue(Action.NAME, "+"); 103 putValue( Action.SHORT_DESCRIPTION, ""); 104 } 105 public void actionPerformed(ActionEvent e) { 106 way.setText("+"); 107 } 108 } 109 110 class MinusAction extends AbstractAction { 111 MinusAction() { 112 putValue(Action.NAME, "-"); 113 } 114 public void actionPerformed(ActionEvent e) { 115 way.setText("-"); 116 } 117 } 118 119 class MultipleAction extends AbstractAction { 120 MultipleAction() { 121 putValue(Action.NAME, "*"); 122 } 123 public void actionPerformed(ActionEvent e) { 124 way.setText("*"); 125 } 126 } 127 128 class DivideAction extends AbstractAction { 129 DivideAction() { 130 putValue(Action.NAME, "/"); 131 } 132 public void actionPerformed(ActionEvent e) { 133 way.setText("/"); 134 } 135 } 136 137 class ResultAction extends AbstractAction { 138 ResultAction() { 139 putValue(Action.NAME, "="); 140 } 141 public void actionPerformed(ActionEvent e) { 142 143 } 144 } 145 146 // Clear button 147 class ClearAction extends AbstractAction { 148 ClearAction() { 149 putValue(Action.NAME, "AC"); 150 } 151 public void actionPerformed(ActionEvent e) { 152 } 153 } 154 155 // Delete last character button 156 class DelAction extends AbstractAction { 157 DelAction() { 158 putValue(Action.NAME, "Del"); 159 } 160 public void actionPerformed(ActionEvent e) { 161 162 } 163 } 164 165 // Plus/Minus action button 166 class PmAction extends AbstractAction { 167 PmAction() { 168 putValue(Action.NAME, "+/-"); 169 } 170 public void actionPerformed(ActionEvent e) { 171 double num = Double.parseDouble(input.getText()); 172 if (currentFocusField == input) { 173 if(input!=null) { 174 String text=input.getText(); 175 num=Double.parseDouble(text); 176 num=-num; 177 String change=String.valueOf(num); 178 input.setText(change); 179 180 } 181 182 } else if (currentFocusField==input2) { 183 if(input2!=null) { 184 String text=input2.getText(); 185 num=Double.parseDouble(text); 186 input2.setText(String.valueOf(-num)); 187 } 188 else { 189 input2.setText(""); 190 } 191 } 192 } 193 } 194 195 class PercentAction extends AbstractAction { 196 double num=0; 197 PercentAction() { 198 putValue(Action.NAME, "%"); 199 } 200 public void actionPerformed(ActionEvent e) { 201 } 202 } 203 204 class numAction extends AbstractAction { 205 String number; 206 numAction(String number) { 207 this.number = number; 208 putValue(Action.NAME, number); 209 } 210 public void actionPerformed(ActionEvent e) { 211 String inputnum=input.getText(); 212 String input2num=input2.getText(); 213 if (currentFocusField == input) { 214 input.setText(inputnum + number); 215 } else if (currentFocusField==input2) { 216 input2.setText(input2num+number); 217 System.out.println(input2num+number); 218 } 219 } 220 } 221 class ZeroAction extends AbstractAction{ 222 ZeroAction() { 223 putValue(Action.NAME, "0"); 224 } 225 public void actionPerformed(ActionEvent e) { 226 } 227 } 228 229 class NumericDocument extends PlainDocument { 230 String validValues = "0123456789.+-%"; 231 232 public void insertString(int offset, String str, AttributeSet a) { 233 if (validValues.indexOf(str) == -1) { 234 return; 235 } 236 try { 237 super.insertString(offset, str, a); 238 } catch (BadLocationException e) { 239 System.out.println(e); 240 } 241 } 242 } 243 244 class NumericDocument2 extends PlainDocument { 245 String validValues = "+-*/%"; 246 247 public void insertString(int offset, String str, AttributeSet a) { 248 if( validValues.indexOf( str ) == -1 ){ 249 return; 250 } 251 try{ 252 super.insertString( offset, str, a ); 253 } 254 catch( BadLocationException e ) { 255 System.out.println( e ); 256 } 257 } 258 259 } 260 261 class NumericDocument3 extends PlainDocument { 262 String validValues = "0123456789.+-"; 263 264 public void insertString(int offset, String str, AttributeSet a) { 265 if( validValues.indexOf( str ) == -1 ){ 266 return; 267 } 268 try{ 269 super.insertString( offset, str, a ); 270 } 271 catch( BadLocationException e ) { 272 System.out.println( e ); 273 } 274 } 275 276 } 277} 278

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

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

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

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

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

jimbe

2024/12/23 11:44 編集

コードは「コードのマークダウン」(ファイル毎に ``` だけの行で前後を囲む) を用いてください。普通の文章の中に書くと一部の記号がマークダウンと解釈されて消えてしまったりします。 また出来れば、一部抜粋のようなコードでは無く状況が再現できる実行可能な状態のコードをご提示ください。
dodox86

2024/12/24 02:14

既にコメントいただいていることへの対応はするとして: > JavaEclipse setTextが上手くいかない ... > まず、numActionでは、123というように、順番通りに数字を押すと上手くテキストフィールドに表示されますが、157や81などバラバラに押すとテキストフィールドが勝手に空にされてしまいます。 せっかくEclipseを使っているのですから、まずはご自身でもデバッグしませんか。
nonfi

2024/12/29 15:28

プログラミングを始めたばかりでまだよくわからないこと、慣れていないことがあり申し訳ございません。 、、、lang-java import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.TitledBorder; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.PlainDocument; public class Calculator extends JFrame { JTextField input,input2,way, answer; JButton plus, minus, multiple, divide, result, clear, pm, percent, del, few, num, zero; double num1, num2; // String operator = ""; JTextField currentFocusField; // フォーカスされているフィールドを追跡する変数 public static void main(String[] args) { JFrame w = new Calculator("Calculator"); w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); w.setSize(350, 400); w.setVisible(true); } public Calculator(String title) { super(title); JPanel pane = (JPanel) getContentPane(); pane.setLayout(new BorderLayout()); JPanel tfpanel=new JPanel(); tfpanel.setLayout(new GridLayout(1,2)); input = new JTextField(5); input.setBorder(new TitledBorder("数1")); input.setDocument(new NumericDocument()); input.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { currentFocusField = input; // inputがフォーカスされた時 } }); tfpanel.add(input); way = new JTextField(1); way.setBorder(new TitledBorder("計算方法")); way.setDocument(new NumericDocument2()); tfpanel.add(way); input2 = new JTextField(5); input2.setBorder(new TitledBorder("数2")); input2.setDocument(new NumericDocument()); input2.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { currentFocusField = input2; // input2がフォーカスされた時 } }); tfpanel.add(input2); pane.add(tfpanel, BorderLayout.NORTH);//数式を入力するフィールドの設置 answer = new JTextField(5); answer.setBorder(new TitledBorder("結果")); pane.add(answer, BorderLayout.SOUTH);//計算結果を表示するフィールドの設置 JPanel leftpanel = new JPanel(); leftpanel.setLayout(new GridLayout(5, 3)); leftpanel.setPreferredSize(new Dimension(270, 400)); clear = new JButton(new ClearAction()); leftpanel.add(clear);//クリアボタン pm = new JButton(new PmAction()); leftpanel.add(pm);//+-切り替えボタン percent = new JButton(new PercentAction()); leftpanel.add(percent);//%表示切り替えボタン for (int i = 1; i <= 9; i++) { num = new JButton(new numAction(Integer.toString(i))); leftpanel.add(num); }//1~9の番号ボタン del = new JButton(new DelAction()); leftpanel.add(del);//削除ボタン zero=new JButton(new ZeroAction()); leftpanel.add(zero); pane.add(leftpanel, BorderLayout.CENTER); JPanel rightpanel = new JPanel(); rightpanel.setLayout(new GridLayout(5, 1)); plus = new JButton(new PlusAction()); rightpanel.add(plus); minus = new JButton(new MinusAction()); rightpanel.add(minus); multiple = new JButton(new MultipleAction()); rightpanel.add(multiple); divide = new JButton(new DivideAction()); rightpanel.add(divide); result = new JButton(new ResultAction()); rightpanel.add(result); pane.add(rightpanel, BorderLayout.EAST); input.requestFocus(); // ここでinputに初期フォーカスを設定 } // Arithmetic Operations class PlusAction extends AbstractAction { PlusAction() { putValue(Action.NAME, "+"); putValue( Action.SHORT_DESCRIPTION, ""); } public void actionPerformed(ActionEvent e) { way.setText("+"); } } class MinusAction extends AbstractAction { MinusAction() { putValue(Action.NAME, "-"); } public void actionPerformed(ActionEvent e) { way.setText("-"); } } class MultipleAction extends AbstractAction { MultipleAction() { putValue(Action.NAME, "*"); } public void actionPerformed(ActionEvent e) { way.setText("*"); } } class DivideAction extends AbstractAction { DivideAction() { putValue(Action.NAME, "/"); } public void actionPerformed(ActionEvent e) { way.setText("/"); } } class ResultAction extends AbstractAction { ResultAction() { putValue(Action.NAME, "="); } public void actionPerformed(ActionEvent e) { String fourway=way.getText(); int ans=0; if(fourway.equals("+")) { ans = Integer.parseInt( input.getText() ) + Integer.parseInt( input2.getText() ); } if(fourway.equals("-")) { ans = Integer.parseInt( input.getText() ) - Integer.parseInt( input2.getText() ); } if(fourway.equals("*")) { ans = Integer.parseInt( input.getText() ) * Integer.parseInt( input2.getText() ); } if(fourway.equals("/")) { ans = Integer.parseInt( input.getText() ) / Integer.parseInt( input2.getText() ); } answer.setText( String.valueOf( ans ) ); } } // Clear button class ClearAction extends AbstractAction { ClearAction() { putValue(Action.NAME, "AC"); } public void actionPerformed(ActionEvent e) { input.setText(""); // Clear input answer.setText(""); // Clear result } } // Delete last character button class DelAction extends AbstractAction { DelAction() { putValue(Action.NAME, "Del"); } public void actionPerformed(ActionEvent e) { String text = input.getText(); String text2 = input2.getText(); if (currentFocusField == input) { if (text.length() > 0) { input.setText(text.substring(0, text.length() - 1)); } else if (currentFocusField == input2) { if (text2.length() > 0) { input2.setText(text2.substring(0, text2.length() - 1)); } } } } } // Plus/Minus action button class PmAction extends AbstractAction { PmAction() { putValue(Action.NAME, "+/-"); } public void actionPerformed(ActionEvent e) { double num = Double.parseDouble(input.getText()); if (currentFocusField == input) { if(input!=null) { String text=input.getText(); num=Double.parseDouble(text); num=-num; String change=String.valueOf(num); input.setText(change); } } else if (currentFocusField==input2) { if(input2!=null) { String text=input2.getText(); num=Double.parseDouble(text); input2.setText(String.valueOf(-num)); } else { input2.setText(""); } } } } class PercentAction extends AbstractAction { double num=0; PercentAction() { putValue(Action.NAME, "%"); } public void actionPerformed(ActionEvent e) { way.setText("%"); if (currentFocusField == input) { num=Double.parseDouble(input.getText()); } else if (currentFocusField==input2) { num=Double.parseDouble(input2.getText()); } answer.setText(String.valueOf( num/100 )); } } class numAction extends AbstractAction { String number; numAction(String number) { this.number = number; putValue(Action.NAME, number); } public void actionPerformed(ActionEvent e) { String inputnum=input.getText(); String input2num=input2.getText(); if (currentFocusField == input) { input.setText(inputnum + number); } else if (currentFocusField==input2) { input2.setText(input2num+number); System.out.println(input2num+number); } } } class ZeroAction extends AbstractAction{ ZeroAction() { putValue(Action.NAME, "0"); } public void actionPerformed(ActionEvent e) { if (currentFocusField == input) { input.setText(input.getText() + "0"); } else if (currentFocusField==input2) { input2.setText(input2.getText() + "0"); } } } class NumericDocument extends PlainDocument { String validValues = "0123456789.+-%"; public void insertString(int offset, String str, AttributeSet a) { if (validValues.indexOf(str) == -1) { return; } try { super.insertString(offset, str, a); } catch (BadLocationException e) { System.out.println(e); } } }
nonfi

2024/12/29 15:30

class NumericDocument2 extends PlainDocument { String validValues = "+-*/%"; public void insertString(int offset, String str, AttributeSet a) { if( validValues.indexOf( str ) == -1 ){ return; } try{ super.insertString( offset, str, a ); } catch( BadLocationException e ) { System.out.println( e ); } } } class NumericDocument3 extends PlainDocument { String validValues = "0123456789.+-"; public void insertString(int offset, String str, AttributeSet a) { if( validValues.indexOf( str ) == -1 ){ return; } try{ super.insertString( offset, str, a ); } catch( BadLocationException e ) { System.out.println( e ); } } } } 、、、 分かれてしまいすみません。 デバッグとはどうやってやるのかも分からず、もし可能であれば教えていただきたいです。 お手数おかけしますが、皆様よろしくお願いいたします。
jimbe

2024/12/29 15:32 編集

コメント欄にはマークダウンは使えません。 コードや質問の情報等は質問を編集で追加・変更等を行ってください。 なお、コードのマークダウンは「、、、」では無く「```」(キーボードの@キーの上の段)です。
nonfi

2024/12/30 14:44

ご丁寧にありがとうございます。字数制限の都合上いくつかクラスの中身を削りました。
guest

回答2

0

まず、numActionでは、123というように、順番通りに数字を押すと上手くテキストフィールドに表示されますが、157や81などバラバラに押すとテキストフィールドが勝手に空にされてしまいます。

NumericDocumentがおかしいです。
insertStringstrには今入力した1文字ではなく、入力されたすべての文字が入ってきます。
そのため連番でないとindexOfがfalseになり、insertStringされません(空になってしまいます)
1文字ずつvalidValuesと比較するか、正規表現で判定してください。

java

1class NumericDocument extends PlainDocument { 2 String validValues = "0123456789.+-%"; 3 4 public void insertString(int offset, String str, AttributeSet a) throws BadLocationException { 5 for (char c : str.toCharArray()) { // 1文字ずつ比較の場合 6 if (validValues.indexOf(c) == -1) { 7 return; 8 } 9 } 10 super.insertString(offset, str, a); 11 } 12} 13 14class NumericDocument2 extends PlainDocument { 15 Pattern p = Pattern.compile("[+\\-*/%]*"); // []の中の - はエスケープが必要 16 17 public void insertString(int offset, String str, AttributeSet a) throws BadLocationException { 18 if (p.matcher(str).matches()) { // 正規表現で判定の場合 19 super.insertString(offset, str, a); 20 } 21 } 22}

訳のわからない動作に遭遇した場合は、できるだけシンプルな状態に戻ってください(「連番じゃないと入力できない」なんて意味不明すぎますよね?^^;

当初コードにはNumericDocumentはありませんでした。
つまり的はずれなところを探していたということになります。

setDocumentが影響するなんて思いもしなかった」ということであっても、外してみる(コメント化してみる)というのは重要です。
無関係なら(自分が数字以外入れないように注意すれば)何の問題ないはずです。

(本題には不要なコードを)削る方法で原因がわからない場合は、JTextFieldJButton1個から徐々に増やしていくような逆の手法も有効です。

java

1import javax.swing.*; 2import javax.swing.border.TitledBorder; 3import javax.swing.text.*; 4import java.awt.*; 5import java.awt.event.*; 6import java.util.regex.Pattern; 7 8public class Calculator extends JFrame { 9 public static void main(String[] args) { 10 new Calculator().setVisible(true); 11 } 12 13 private final JTextField input; 14 private final JTextField input2; 15 private final JTextField way; 16 private final JTextField answer; 17 private JTextField currentFocusField; 18 19 public Calculator() { 20 super("Calculator"); 21 setDefaultCloseOperation(EXIT_ON_CLOSE); 22 setSize(350, 400); 23 setLocationRelativeTo(null); 24 25 var tfPanel = new JPanel(new GridLayout(1, 3)); 26 27 input = new JTextField(5); 28 input.setBorder(new TitledBorder("数1")); 29 input.setDocument(new NumericDocument()); 30 input.addFocusListener(new FocusAdapter() { 31 @Override public void focusGained(FocusEvent e) { 32 currentFocusField = input; 33 } 34 }); 35 tfPanel.add(input); 36 37 way = new JTextField(1); 38 way.setBorder(new TitledBorder("計算方法")); 39 way.setDocument(new NumericDocument2()); 40 tfPanel.add(way); 41 42 input2 = new JTextField(5); 43 input2.setBorder(new TitledBorder("数2")); 44 input2.setDocument(new NumericDocument()); 45 input2.addFocusListener(new FocusAdapter() { 46 @Override public void focusGained(FocusEvent e) { 47 currentFocusField = input2; 48 } 49 }); 50 tfPanel.add(input2); 51 add(tfPanel, BorderLayout.NORTH); 52 53 54 answer = new JTextField(5); 55 answer.setBorder(new TitledBorder("結果")); 56 add(answer, BorderLayout.SOUTH); 57 58 59 var leftPanel = new JPanel(new GridLayout(5, 3)); 60 leftPanel.setPreferredSize(new Dimension(270, 400)); 61 62 leftPanel.add(new JButton(new ClearAction())); 63 leftPanel.add(new JButton(new PmAction())); 64 leftPanel.add(new JButton(new PercentAction())); 65 for (var i = 1; i <= 9; i++) { 66 leftPanel.add(new JButton(new NumAction(Integer.toString(i)))); 67 } 68 leftPanel.add(new JButton(new DelAction())); 69 leftPanel.add(new JButton(new NumAction("0"))); 70 add(leftPanel, BorderLayout.CENTER); 71 72 73 var rightPanel = new JPanel(new GridLayout(5, 1)); 74 rightPanel.add(new JButton(new CalcAction("+"))); 75 rightPanel.add(new JButton(new CalcAction("-"))); 76 rightPanel.add(new JButton(new CalcAction("*"))); 77 rightPanel.add(new JButton(new CalcAction("/"))); 78 rightPanel.add(new JButton(new ResultAction())); 79 add(rightPanel, BorderLayout.EAST); 80 81 input.requestFocus(); 82 } 83 84 class ClearAction extends AbstractAction { 85 ClearAction() { 86 super("AC"); 87 } 88 89 public void actionPerformed(ActionEvent e) { 90 input.setText(""); 91 input2.setText(""); 92 way.setText(""); 93 answer.setText(""); 94 } 95 } 96 97 class PmAction extends AbstractAction { 98 PmAction() { 99 super("+/-"); 100 } 101 102 public void actionPerformed(ActionEvent e) { 103 var num = Integer.parseInt(currentFocusField.getText()); 104 currentFocusField.setText(String.valueOf(-num)); 105 } 106 } 107 108 class PercentAction extends AbstractAction { 109 PercentAction() { 110 super("%"); 111 } 112 113 public void actionPerformed(ActionEvent e) { 114 way.setText("%"); 115 var num = Integer.parseInt(currentFocusField.getText()); 116 answer.setText(String.valueOf(num / 100d)); 117 } 118 } 119 120 class NumAction extends AbstractAction { 121 NumAction(String name) { 122 super(name); 123 } 124 125 public void actionPerformed(ActionEvent e) { 126 currentFocusField.setText(currentFocusField.getText() + getValue(Action.NAME)); 127 } 128 } 129 130 class DelAction extends AbstractAction { 131 DelAction() { 132 super("Del"); 133 } 134 135 public void actionPerformed(ActionEvent e) { 136 var text = currentFocusField.getText(); 137 if (!text.isEmpty()) { 138 currentFocusField.setText(text.substring(0, text.length() - 1)); 139 } 140 } 141 } 142 143 class CalcAction extends AbstractAction { 144 CalcAction(String name) { 145 super(name); 146 } 147 148 public void actionPerformed(ActionEvent e) { 149 way.setText(getValue(Action.NAME).toString()); 150 } 151 } 152 153 class ResultAction extends AbstractAction { 154 ResultAction() { 155 super("="); 156 } 157 158 public void actionPerformed(ActionEvent e) { 159 var ans = switch (way.getText()) { 160 case "+" -> Integer.parseInt(input.getText()) + Integer.parseInt(input2.getText()); 161 case "-" -> Integer.parseInt(input.getText()) - Integer.parseInt(input2.getText()); 162 case "*" -> Integer.parseInt(input.getText()) * Integer.parseInt(input2.getText()); 163 case "/" -> Integer.parseInt(input.getText()) / Integer.parseInt(input2.getText()); 164 default -> 0; 165 }; 166 answer.setText(String.valueOf(ans)); 167 } 168 } 169 170 static class NumericDocument extends PlainDocument { 171 private final String validValues = "0123456789.+-%"; 172 173 public void insertString(int offset, String str, AttributeSet a) throws BadLocationException { 174 for (var c : str.toCharArray()) { 175 if (validValues.indexOf(c) == -1) { 176 return; 177 } 178 } 179 super.insertString(offset, str, a); 180 } 181 } 182 183 static class NumericDocument2 extends PlainDocument { 184 private final Pattern p = Pattern.compile("[+\\-*/%]*"); 185 186 public void insertString(int offset, String str, AttributeSet a) throws BadLocationException { 187 if (p.matcher(str).matches()) { 188 super.insertString(offset, str, a); 189 } 190 } 191 } 192 193// こうして共通化してもok 194//input.setDocument(new RegexDocument("[0123456789.+\\-%]*")); 195//way.setDocument(new NumericDocument2("[+\\-*/%]*")); 196//input2.setDocument(new RegexDocument("[0123456789.+\\-%]*")); 197 198// static class RegexDocument extends PlainDocument { 199// private final Pattern p; 200// public RegexDocument(String regex) { 201// p = Pattern.compile(regex); 202// } 203// 204// public void insertString(int offset, String str, AttributeSet a) throws BadLocationException { 205// if (p.matcher(str).matches()) { 206// super.insertString(offset, str, a); 207// } 208// } 209// } 210}

投稿2024/12/30 23:33

TN8001

総合スコア9903

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

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

0

まず、numActionでは、123というように、順番通りに数字を押すと上手くテキストフィールドに表示されますが、157や81などバラバラに押すとテキストフィールドが勝手に空にされてしまいます。

怪しいのは input に設定している NumericDocument です。
insertString メソッドの先頭に
System.out.println("insertString: offset="+offset+",str="+str);
という一文を入れて実行し、 '1235' と入力してみた時のコンソールへの出力を見ます。

insertString: offset=0,str=1 insertString: offset=0,str=12 insertString: offset=0,str=123 insertString: offset=0,str=1235

insertString メソッドでは

if (validValues.indexOf(str) == -1) { return; }

としており、 validValues は "0123456789.+-%" ですので最後の 1235 は if が成立し return してしまいます。
恐らく insertString の str には一文字ずつ入ってくるつもりでこのようなコードを書かれたのでしょうが、そうでは無かったためのバグと思われます。ちゃんと動作を確認してください。

プラスマイナスを変更した時の setText でも NumericDocument は反応しますので、原因は同じです。


insertString メソッドの str に(1文字ずつで無く)全文字列が入ってくるのは、(NumAction で) JTextField に対して setText しているからです。
ご存じの通り setText は既存の文字列を消して指定した文字列にするというものですので、 JTextField は AbstractDocument#remove 等で既存を全て消してから PlainDocument#insertString で新たな文字列を設定しようとします。しかし insertString を override して super.insertString せずに return してしまうと remove の効果だけが残り、「勝手に空にされ」た状態になるのです。
なおこの動作は setText に因るものですので、 JTextField に直接キーボードから順次入力した場合は insertString の str は1文字ずつになります。

全く関係ありませんが、 ボタンの処理を Action で書くのは本件ではほぼ意味がありませんので ActionListener でコンストラクタ内に書いたほうがコードは短くなると思います。
Action は、ある機能を実行する方法がメニューにあったりツールバーに(ボタンで)あったりコンテキストメニューにあったりする場合に 1 つの定義を流用することで、表示の統一や Enable/Disable を簡単にする為に用います。

以下は各ボタンの ActionListener で処理を行い、また input を editable=false とした上で KeyListener でボタン操作に変換します。数字以外のキーも( '%' 以外)テキトウに割り振りました。

java

1import java.awt.*; 2import java.awt.event.*; 3import java.text.DecimalFormat; 4import java.util.HashMap; 5import java.util.Map; 6 7import javax.swing.*; 8 9public class Calculator extends JFrame { 10 public static void main(String[] args) { 11 new Calculator().setVisible(true); 12 } 13 //キー入力をボタン操作に変換 14 private static class InputKeyAdapter extends KeyAdapter { 15 private Map<Character,JButton> charMap = new HashMap<>(); 16 private Map<Integer,JButton> codeMap = new HashMap<>(); 17 18 void put(JButton button, char c) { 19 charMap.put(c, button); 20 } 21 void put(JButton button, int code) { 22 codeMap.put(code, button); 23 } 24 @Override 25 public void keyTyped(KeyEvent e) { 26 doClick(charMap.get(e.getKeyChar())); 27 } 28 @Override 29 public void keyReleased(KeyEvent e) { 30 doClick(codeMap.get(e.getKeyCode())); 31 } 32 private void doClick(JButton button) { 33 if(button != null) button.doClick(); 34 } 35 }; 36 37 private JTextField input1, input2, input, way, answer; 38 private InputKeyAdapter keyAdapter = new InputKeyAdapter(); 39 40 private Calculator() { 41 super("Calculator"); 42 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 43 44 //生成 45 input1 = createInput("数1"); 46 way = createTitledField("計算方法", 3); 47 input2 = createInput("数2"); 48 answer = createTitledField("結果", 5); 49 50 ActionListener numActionListener = v -> { //lamda 式によりコード短縮 51 String num = ((JButton)v.getSource()).getText(); 52 String text = input.getText(); 53 input.setText((text.equals("0")?"":text) + num); 54 }; 55 JButton[] numButtons = new JButton[10]; 56 for(int i=0; i<10; i++) numButtons[i] = createButton(""+i, numActionListener); 57 58 JButton dotButton = createButton(".", v -> { 59 String text = input.getText(); 60 if(!text.contains(".")) input.setText(text + "."); 61 }); 62 63 JButton acButton = createButton("AC", v -> { 64 input1.setText("0"); 65 way.setText(""); 66 input2.setText("0"); 67 answer.setText(""); 68 }, KeyEvent.VK_ESCAPE); 69 70 JButton delButton = createButton("Del", v -> { 71 String text = input.getText(); 72 if(text.length() > (text.startsWith("-")?2:1)) { 73 input.setText(text.substring(0, text.length()-1)); 74 } else { 75 input.setText("0"); 76 } 77 }, KeyEvent.VK_DELETE, KeyEvent.VK_BACK_SPACE); 78 79 JButton pmButton = createButton("+/-", v -> { 80 String text = input.getText(); 81 if(text.startsWith("-")) { 82 input.setText(text.substring(1)); 83 } else if(!text.equals("0")) { 84 input.setText("-" + text); 85 } 86 }, KeyEvent.VK_SHIFT); 87 88 JButton percentButton = createButton("%", v -> { 89 way.setText("%"); 90 setAnswer(Double.parseDouble(input.getText()) / 100); 91 }); 92 93 JButton addButton = createButton('+', BinaryOperation.ADD); 94 JButton subButton = createButton('-', BinaryOperation.SUB); 95 JButton mulButton = createButton('*', BinaryOperation.MUL); 96 JButton divButton = createButton('/', BinaryOperation.DIV); 97 98 JButton eqButton = createButton("=", v -> { 99 double a = Double.parseDouble(input1.getText()); 100 double b = Double.parseDouble(input2.getText()); 101 BinaryOperation op = BinaryOperation.of(way.getText()); 102 setAnswer(op == null ? 0 : op.calc(a,b)); 103 }, KeyEvent.VK_ENTER); 104 105 //配置 106 JPanel northPanel = new JPanel(new GridBagLayout()); 107 GridBagConstraints gbc = new GridBagConstraints(); 108 gbc.gridy = 0; 109 gbc.fill = GridBagConstraints.HORIZONTAL; 110 gbc.weightx = 1; 111 northPanel.add(input1, gbc);//左側で伸縮 112 gbc.weightx = 0; 113 northPanel.add(way, gbc);//中央固定サイズ 114 gbc.weightx = 1; 115 northPanel.add(input2, gbc); //右側で伸縮 116 add(northPanel, BorderLayout.NORTH); 117 118 add(answer, BorderLayout.SOUTH); 119 120 JPanel centerPanel = createGridPanel(5,3, acButton,pmButton,percentButton,delButton,numButtons[0],dotButton); 121 for(int i : new int[]{3,2,1, 6,5,4, 9,8,7}) centerPanel.add(numButtons[i], 3); //インデックス固定の為, 逆順で挿入 122 centerPanel.setPreferredSize(new Dimension(270, 300)); 123 add(centerPanel, BorderLayout.CENTER); 124 125 add(createGridPanel(5,1,addButton,subButton,mulButton,divButton,eqButton), BorderLayout.EAST); 126 127 pack(); 128 setMinimumSize(getSize()); 129 setLocationRelativeTo(null); //画面中央へ 130 131 //初期化 132 acButton.doClick(); 133 input1.requestFocus(); 134 } 135 136 private static JPanel createGridPanel(int rows, int cols, Component... components) { 137 JPanel panel = new JPanel(new GridLayout(rows, cols)); 138 for(Component c : components) panel.add(c); 139 return panel; 140 } 141 142 private static JTextField createTitledField(String title, int columns) { 143 JTextField textField = new JTextField(columns); 144 textField.setEditable(false); 145 textField.setFocusable(false); 146 textField.setFont(textField.getFont().deriveFont(30f)); 147 textField.setBorder(BorderFactory.createTitledBorder(title)); 148 return textField; 149 } 150 151 private JTextField createInput(String title) { 152 JTextField textField = createTitledField(title, 5); 153 textField.setFocusable(true); 154 textField.addKeyListener(keyAdapter); 155 textField.addFocusListener(new FocusAdapter() { 156 @Override 157 public void focusGained(FocusEvent e) { 158 if(input != null) input.setBackground(way.getBackground()); 159 input = textField; 160 input.setBackground(Color.WHITE); 161 } 162 }); 163 return textField; 164 } 165 166 private JButton createButton(String text, ActionListener l, int... keyCodes) { 167 return createButton(text, text.length()==1?text.charAt(0):0, l, keyCodes); 168 } 169 private JButton createButton(char keyChar, BinaryOperation op) { 170 return createButton(op.text, keyChar, v -> way.setText(op.text)); 171 } 172 private JButton createButton(String text, char keyChar, ActionListener l, int... keyCodes) { 173 JButton button = new JButton(text); 174 button.setFocusable(false); 175 button.setFont(button.getFont().deriveFont(20f)); 176 button.addActionListener(l); 177 if(keyChar != 0) keyAdapter.put(button, keyChar); 178 for(int keyCode : keyCodes) keyAdapter.put(button, keyCode); 179 return button; 180 } 181 182 private final DecimalFormat ANSWER_FORMAT = new DecimalFormat("0.######"); 183 public void setAnswer(Double v) { 184 answer.setText(ANSWER_FORMAT.format(v)); 185 } 186 187 //2項演算 188 private enum BinaryOperation { 189 ADD("+") { @Override double calc(double a, double b) { return a+b; } }, 190 SUB("-") { @Override double calc(double a, double b) { return a-b; } }, 191 MUL("×") { @Override double calc(double a, double b) { return a*b; } }, 192 DIV("÷") { @Override double calc(double a, double b) { return a/b; } }; 193 194 static BinaryOperation of(String text) { 195 for(BinaryOperation op : values()) if(op.text.equals(text)) return op; 196 return null; 197 } 198 199 final String text; 200 BinaryOperation(String text) { 201 this.text = text; 202 } 203 abstract double calc(double a, double b); 204 } 205}

投稿2024/12/29 15:56

編集2025/01/05 10:25
jimbe

総合スコア13230

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.34%

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

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

質問する

関連した質問