68996


以下のプログラムで、質問があります。  
boolean型の配列を6個用意して、それぞれのボタンが押されている時（イベント時）は、ある1つの要素だけをtrueにして、それ以外をfalseにするプログラムを書きました。しかし、実行すると、ある通貨を選択して計算した後に、他の通貨を選択しても最初に選択した通貨から変わらないので、falseの命令が効いていない可能性があります。  
このように複数のboolean型変数を使う場合、配列はどのように組んで、true,falseを設定すればいいでしょうか？（コメントアウトしている部分は無視でお願いします）

[code]

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class Rate2 extends JFrame {
      int n;
      JMenuBar mbar = new JMenuBar();
      JTextField f0 = new JTextField("");
      JButton b0 = new JButton("実行");
     
      JLabel l1 = new JLabel("Input a number and press the button.");
      JMenu menu1 = new JMenu("Foreign Currency→to JPY"); 
      JMenu menu2=new JMenu("JPY to→Foreign Currency");
      JMenuItem item01 = new JMenuItem("USD to JPY");
      JMenuItem item02 = new JMenuItem("CNY to JPY");
      JMenuItem item03= new JMenuItem("Euro to JPY");
      JMenuItem item04 = new JMenuItem("JPY to USD");
      JMenuItem item05 = new JMenuItem("JPY to CNY");
      JMenuItem item06= new JMenuItem("JPY to Euro");
    
      boolean a=false;
     // boolean b=false;boolean c=false;boolean d;boolean e;boolean f;
      boolean[]t=new boolean[6];
     
      
    
      public Rate2() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        setTitle("Please select Currency");
        setLayout(null);
        
        
        add(f0); f0.setBounds(100, 50, 50, 30);
        add(b0);b0.setBounds(150,50,50,30);
        mbar.add(menu1);mbar.add(menu2);setJMenuBar(mbar);
        menu1.add(item01);menu1.add(item02);menu1.add(item03);
        menu2.add(item04);menu2.add(item05);menu2.add(item06);
       
        add(l1);l1.setBounds(50,140,300,100);
        //pack(); 
        setSize(600, 400);
       
       
    
        item01.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
           
           t[0]=true;t[1-5]=false;
           //b=c=d=e=f=false;
           
        }
    });
    
        
    
        item02.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            
            t[1]=true;t[0]=t[2-5]=false;
            //a=c=d=e=f=false;
            
          }
        });
    
        item03.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            
            t[2]=true;t[0-1]=t[3-5]=false;
           // a=false;b=!c;d=false;e=false;f=false;
            
          }
        });
    
        item04.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            
            t[3]=true;t[0-2]=t[4-5]=false;
            //a=false;b=!d;c=false;e=false;f=false;
            
          }
        });
    
        item05.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            
            
            t[4]=true;t[0-3]=t[5]=false;
            //a=false;b=false;c=false;d=false;f=false;
            
          }
        });
    
        item06.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            
            t[5]=true;t[0-4]=false;
           // a=false;b=false;c=false;d=false;e=false;
            
          }
        });
        
        b0.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
            if(t[0]){Double n=Double.parseDouble(f0.getText());
            
                Dollar d1=new Dollar(n);
               Double d2=d1.Ex();
                l1.setText(n+"USDは"+d2+"円");}
            else if(t[1]){Double n=Double.parseDouble(f0.getText());
                //l1.C1(n);
                Other c1=new Other(n);
                Double c2=c1.Ex2();
                
                l1.setText(n+"人民元は"+c2+"円");}
    
            else if(t[2]){Double n=Double.parseDouble(f0.getText());
                  
                  Other c3=new Other(n);
                  Double c4=c3.Ex3();
                  
                  l1.setText(n+"ユーロは"+c4+"円");}
    
           else if(t[3]){Double n=Double.parseDouble(f0.getText());
                    
                    Other c4=new Other(n);
                    Double c5=c4.Ex4();
                    
                    l1.setText(n+"円は"+c5+"ドル");}
    
           else if(t[4]){Double n=Double.parseDouble(f0.getText());
                      
                      Other c5=new Other(n);
                      Double c6=c5.Ex5();
                      
                      l1.setText(n+"円は"+c6+"人民元");}
    
            else if(t[5]){Double n=Double.parseDouble(f0.getText());
                      
                        Other c6=new Other(n);
                        Double c7=c6.Ex6();
                        
                        l1.setText(n+"円は"+c7+"ユーロ");}
    
                  
            
            else{return;} 
                
        
            }
          });
    
          
    }
    
    
     public static void main(String[] args) throws Exception {
        new Rate2().setVisible(true);
        
      }
    
    
      
      
      static class Dollar{
       int d=106;
      // int c=15;
       Double dl;Double n;
    
       public Dollar(Double n){
         this.n=n;
    
       }
    
       public Double Ex(){
        return dl=d*n;
       }
    
      }
    
      static class Other {
         Double cn;
         int c=15;
         int d=123;
         double e=0.0094;
         double f=0.0667;
         double g=0.0081;
         Double n;
         public Other(Double n){
           this.n=n;
         }
         
         public Double Ex2(){
          return cn=c*n;
          
         }
    
         public Double Ex3(){
           return cn=d*n;
         }
    
         public Double Ex4(){
          return cn=e*n;
        }
    
        public Double Ex5(){
          return cn=f*n;
        }
    
        public Double Ex6(){
          return cn=g*n;
        }
    
      }
    }
    
[/code]


CC BY-SA 4.0
2020-07-26T07:37:27.787
68980
2020-07-27T13:53:32.523
2020-07-26T09:25:39.437
15413
39688
question
java
boolean型の配列について（ユーザーインターフェース）

[code]

    t[0]=true;t[1-5]=false;
    
[/code]

上記のコードで、

[code]

    t[0]=True;
    t[1]=False;
    t[2]=False;
    t[3]=False;
    t[4]=False;
    t[5]=False;
    
[/code]

が行われると思っていらっしゃるのでしょうが、javaに、そのような文法はありません。(Pythonのスライスへの代入と混同されていませんか？）

1-5=4ですから、

t[0]=true;t[1-5]=false;

では、

[code]

    t[0]=True;
    t[4]=False;
    
[/code]

が実行されるだけです。


CC BY-SA 4.0
2020-07-26T10:29:42.443
68983
2020-07-26T10:29:42.443
217
68980
answer


質問するときは環境に関する情報を詳しく記述しましょう。

  * [技術系メーリングリストで質問するときのパターン・ランゲージ](https://www.hyuki.com/writing/techask.html)

ひとまずJava 8以降の環境だと仮定します。

[`JMenuItem`](https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JMenuItem.html)の代わりに[`JCheckBoxMenuItem`](https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JCheckBoxMenuItem.html)を使い、スーパークラス[`AbstractButton`](https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/AbstractButton.html)で用意されている`setSelected()`メソッドと`isSelected()`メソッドを使えば、`boolean`配列を別に用意する必要はなくなると思います。  
（SwingでMVCやMVVMのようなことをしたいのであれば話は別ですが）

さらにこのオブジェクト自体を配列に入れてしまい、ループ処理するようにしたほうが簡潔です。

また、通貨計算では、ほとんどの10進数を正確に表現できない浮動小数点数は使わず、[`BigDecimal`](https://docs.oracle.com/javase/jp/8/docs/api/java/math/BigDecimal.html)を使ったほうがよいです。  
浮動小数点数で`BigDecimal`を初期化すると誤差が出るので、以下のコード例では`double`型のリテラルは使わず、あえて文字列型のリテラルを使って初期化しています。

ちなみにJavaの[`Double`](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Double.html)型は`double`型のプリミティブラッパークラスであり、別物です。  
（オブジェクト型ではないプリミティブ型`double`をオブジェクトとして扱いたいときにのみ使います）

可読性やメンテナンス性の観点から、変数名やメソッド名には、1,
2文字の短い名前や省略した名前ではなく、ある程度長くて意味のある名前を付けるようにするべきです。1文字の変数名は基本的にforループのカウンターや例外処理のブロックでのみ使うようにします。また、Javaではユーザー定義の型名は大文字で始めますが、メソッド名は小文字で始める慣習となっています。

[code]

    ...
    import java.math.BigDecimal;
    
    public class Rate2 extends JFrame {
        private static final int ONE_WAY_CURRENCY_CONVERT_MENU_ITEM_COUNT = 3;
        private static final int TWO_WAY_CURRENCY_CONVERT_MENU_ITEM_COUNT = ONE_WAY_CURRENCY_CONVERT_MENU_ITEM_COUNT * 2;
    
        private static final String[][] currencyConvertUnitNamePairs = {
            { "USD", "JPY" },
            { "CNY", "JPY" },
            { "EUR", "JPY" },
            { "JPY", "USD" },
            { "JPY", "CNY" },
            { "JPY", "EUR" },
        };
    
        private static final BigDecimal rateFromUsdToJpy = new BigDecimal("106");
        private static final BigDecimal rateFromCnyToJpy = new BigDecimal("15");
        private static final BigDecimal rateFromEurToJpy = new BigDecimal("123");
        private static final BigDecimal rateFromJpyToUsd = new BigDecimal("0.0094");
        private static final BigDecimal rateFromJpyToCny = new BigDecimal("0.0667");
        private static final BigDecimal rateFromJpyToEur = new BigDecimal("0.0081");
    
        private static final BigDecimal[] currencyConvertRates = {
            rateFromUsdToJpy,
            rateFromCnyToJpy,
            rateFromEurToJpy,
            rateFromJpyToUsd,
            rateFromJpyToCny,
            rateFromJpyToEur,
        };
    
        private final JCheckBoxMenuItem[] currencyConvertMenuItems = new JCheckBoxMenuItem[TWO_WAY_CURRENCY_CONVERT_MENU_ITEM_COUNT];
    
        private void selectOneOfCurrencyConvertMenuItems(int index) {
            for (int i = 0; i < TWO_WAY_CURRENCY_CONVERT_MENU_ITEM_COUNT; ++i) {
                final boolean selected = i == index;
                this.currencyConvertMenuItems[i].setSelected(selected);
            }
        }
    
        private void displayConvertedCurrencyBasedOnSelectedRate() {
            for (int i = 0; i < TWO_WAY_CURRENCY_CONVERT_MENU_ITEM_COUNT; ++i) {
                if (this.currencyConvertMenuItems[i].isSelected()) {
                    try {
                        final String inputString = this.f0.getText();
                        final BigDecimal inputValue = new BigDecimal(inputString);
                        final BigDecimal resultValue = inputValue.multiply(currencyConvertRates[i]);
                        final String resultString = resultValue.setScale(2, BigDecimal.ROUND_HALF_EVEN).toPlainString();
                        this.l1.setText(inputString + "[" + currencyConvertUnitNamePairs[i][0] + "]"
                            + " = " + resultString + "[" + currencyConvertUnitNamePairs[i][1] + "]");
                    } catch (final Exception e) {
                        this.l1.setText("Error");
                    }
                    break;
                }
            }
        }
    
    ...
    
        public Rate2() {
    ...
            for (int i = 0; i < TWO_WAY_CURRENCY_CONVERT_MENU_ITEM_COUNT; ++i) {
                final String label = currencyConvertUnitNamePairs[i][0] + " to " + currencyConvertUnitNamePairs[i][1];
                this.currencyConvertMenuItems[i] = new JCheckBoxMenuItem(label);
    
                final int index = i;
                this.currencyConvertMenuItems[i].addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent event) {
                        selectOneOfCurrencyConvertMenuItems(index);
                    }
                });
            }
    
            for (int i = 0; i < ONE_WAY_CURRENCY_CONVERT_MENU_ITEM_COUNT; ++i) {
                this.menu1.add(this.currencyConvertMenuItems[i]);
                this.menu2.add(this.currencyConvertMenuItems[i + ONE_WAY_CURRENCY_CONVERT_MENU_ITEM_COUNT]);
            }
    
            this.b0.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    displayConvertedCurrencyBasedOnSelectedRate();
                }
            });
        }
    }
    
[/code]


CC BY-SA 4.0
2020-07-26T11:09:35.967
68985
2020-07-26T15:11:12.737
2020-07-26T15:11:12.737
15413
15413
68980
answer


都度全ての変数に設定し直すのが煩雑、というのであれば、そのような処理を行うメソッドを定義して、そのメソッドを呼び出すようにすれば済みます。

[code]

    public class Rate2 extends JFrame {
      // ...
    
      // 対応する配列要素をtrueに、それ以外をfalseにするメソッドを定義
      private void setSelected(int menuNum) {
        for (int i = 0; i < 6; i++) {
          t[i] = false;
        }
        t[menuNum] = true;
      }
    
      public Rate2() {
        // ...
    
        item01.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {       
           // t[0]=true;t[1-5]=false;
           setSelected(0);
        }
    });
    
        item02.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            // t[1]=true;t[0]=t[2-5]=false;
            setSelected(1);
          }
        });
    
        item03.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            // t[2]=true;t[0-1]=t[3-5]=false;
            setSelected(2);
          }
        });
    
        item04.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            // t[3]=true;t[0-2]=t[4-5]=false;
            setSelected(3);
          }
        });
    
        item05.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            // t[4]=true;t[0-3]=t[5]=false;
            setSelected(4);
          }
        });
    
        item06.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            // t[5]=true;t[0-4]=false;
            setSelected(5);
          }
        });
    
        // ...    
    }
    
[/code]

* * *

追記

> privateとはどういう意味でしょうか？

[こちら](https://ja.stackoverflow.com/a/68978/2808)に記載したものと同じく、メソッドに対するアクセス修飾子です。

意味としては、これも先の回答に[付記したリンク先](https://docs.oracle.com/cd/E82638_01/jjdev/Java-
overview.html#GUID-C1756D87-6CAD-4C87-A498-E7C996077D9A)に説明があります:

>
> public、private、protectedおよびデフォルト・アクセス修飾子では、アプリケーションのフィールドの範囲が定義されます。Java言語仕様(JLS)では、すべてのフィールドに対するデータの可視性規則が定義されます。可視性規則では、これらのフィールド内のデータにどのような場合にアクセスできるかが定義されます。

>
> フィールドと同様に、メソッドは、public、private、protectedまたはデフォルト・アクセスとして宣言できます。この宣言では、メソッドをコールできる範囲が定義されます。

`private` で修飾されたメソッドは、他のクラスから呼び出すことができない、と理解しておいて基本的には問題ないです(注)。

注:  
より正確には、Java言語仕様の[6.6.1. Determining
Accessibility](https://docs.oracle.com/javase/specs/jls/se11/html/jls-6.html#jls-6.6.1)で説明されています。  
日本語では、こちらで解説されていました:

  * [スーパークラスのprivateフィールドにアクセス - yohhoyの日記](https://yohhoy.hatenadiary.jp/entry/20161216/p1)


CC BY-SA 4.0
2020-07-26T22:51:18.880
68996
2020-07-27T13:53:32.523
2020-07-27T13:53:32.523
2808
2808
68980
answer