swing等を用いて生成した画面内において、ボタンを押した時に生成した画面内に文字列を表示させようとしたところ、エラーが出てしまいネットにも同内容の参考になるプログラムが見当たらなかったため、質問しました。  
「string」と書かれたボタンを押すとJLabelによって生成された文字列が画面内に表示させることを目的としたプログラムです。

```

    import javax.swing.*;
    import java.awt.*;      
    import java.awt.event.*;       
    /*
    program:for makeing Button & String in window
    */
    public class Test{
        public static void main(String[] args) {
            JFrame f = new Edit();
            f.setVisible(true);
        }
    }
    
    class Edit extends JFrame implements ActionListener {
        Edit(){
            super("testwindow");                
            setBounds(200, 200,300, 300);     
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            JPanel p=new JPanel();                     
            JButton button1=new JButton("string");
    
            button1.addActionListener(this);
            button1.setActionCommand("button1");
            p.add(button1);                             
    
            Container contentPane=getContentPane();                          
            contentPane.add(p,BorderLayout.SOUTH);                            
        }
        public void actionPerformed(ActionEvent e) {
            String cmd =e.getActionCommand();
            if(cmd.equals("button1")){
                JLabel label=new JLabel("push Button");
                this.contentPane.add(label,BorderLayout.NORTH);
            }
        }
    }
    
```
CC BY-SA 4.0
2020-02-12T14:45:27.077
63006
2020-02-12T15:57:26.900
2020-02-12T15:10:29.450
19110
37816
question
java
ボタンを押した時に生成画面内に文字列を表示させるには
なるべく少ない変更で動くようにしたコードを最後に添付します。  
1番大きいポイントとしては、

```

    public void actionPerformed(ActionEvent e) {
        String cmd =e.getActionCommand();
        if(cmd.equals("button1")){
            JLabel label=new JLabel("push Button");
            this.contentPane.add(label,BorderLayout.NORTH);
        }
    }
    
```

この部分がボタンがクリックされたときに実行される処理ですが、上のコードだと毎回ラベルコンポーネントを生成して追加しようとしています。  
そうではなく、何も文字を表示していないラベルコンポーネントを最初に1回だけ追加しておいて、ボタンが押されたらラベルのテキストを設定する(更新する)、というような処理が正しいです。

2つめのポイントとしては、

```

    contentPane.add(p,BorderLayout.SOUTH); 
    
```

のように、引数(ここでは`BorderLayout.SOUTH`)で東西南北での位置指定を行えるのは[いくつかの種類があるレイアウトマネージャ](https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html)のうち、
`BorderLayout` だけです。

したがって、後ろに添付したコードのように

```

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());
    
```

レイアウトマネージャを設定してやる必要があります。

Swingのチュートリアルとしては[公式](https://docs.oracle.com/javase/tutorial/uiswing/)のものが体系的/網羅的にまとまっていて良いのです…が、残念ながら英語のみです。  
ただ、動くコードサンプルが多く付随していますので、コードをコピペして動かしてみるだけでも理解できることがあるかと思います。

```

    public class Test {
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                JFrame f = new Edit();
                f.setVisible(true);
            });
        }
    }
    
    class Edit extends JFrame implements ActionListener {
    
        JLabel label = new JLabel();
    
        Edit() {
            super("testwindow");
            setBounds(200, 200, 300, 300);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            JPanel p = new JPanel();
            JButton button1 = new JButton("string");
    
            button1.addActionListener(this);
            button1.setActionCommand("button1");
            p.add(button1);
    
            Container contentPane = getContentPane();
            contentPane.setLayout(new BorderLayout());
            contentPane.add(p, BorderLayout.SOUTH);
    
            contentPane.add(label, BorderLayout.NORTH);
        }
    
        public void actionPerformed(ActionEvent e) {
            String cmd = e.getActionCommand();
            if (cmd.equals("button1")) {
                label.setText("push Button");
            }
        }
    }
    
```
CC BY-SA 4.0
2020-02-12T15:57:26.900
63008
2020-02-12T15:57:26.900
2808
63006
answer