LoginSignup
4
0

More than 1 year has passed since last update.

Java Swing レイアウトで遊ぶ

Posted at

BorderLayout

BorderLayoutは画面を5つの領域(NORTH,WEST,SOUTH,EAST,CENTER)に分けて自動でコンポーネントの大きさを変えて配置してくれるレイアウトマネージャー。
公式ドキュメントはこちら。
https://docs.oracle.com/javase/jp/8/docs/api/java/awt/BorderLayout.html
とりあえず試してみる。

フレームサイズ(400,600)の場合

 setBounds(100,100,400,600);
		 setLocationRelativeTo(null);
		 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		 JButton N_Btn = new JButton("北");
		 JButton W_Btn = new JButton("西");
		 JButton S_Btn = new JButton("南");
		 JButton E_Btn = new JButton("東");
		 JButton C_Btn = new JButton("中");
		 
		 Container c = getContentPane();
		 c.setLayout(new BorderLayout());
		 c.add(N_Btn, BorderLayout.NORTH);
		 c.add(W_Btn, BorderLayout.WEST);
		 c.add(S_Btn, BorderLayout.SOUTH);
		 c.add(E_Btn, BorderLayout.EAST);
		 c.add(C_Btn, BorderLayout.CENTER);

image.png

フレームサイズ(400,300)の場合

上記コードのsetBoundsの引数を(100,100,400,300)に変えただけ。
image.png

スクショで伝わるかどうか分からないけど、ボタンの大きさが変わっていることが分かる。自動でサイズを調整してくれる便利なレイアウト。パネルや他のレイアウトマネージャーと組み合わせることもできるので、遊びつつ後ほど試そうと思う。

FlowLayout

これは左から順番に配置してくれるレイアウトマネージャー。画面に収まらなくなったら自動で下の行へいく。他のマネージャーと違う点は、自動のサイズ調整を行わないこと。

コード(ボタンのサイズを指定しなかった場合)

 setBounds(100,100,400,600);
		 setLocationRelativeTo(null);
		 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		 
		 JButton btn1 = new JButton("1");
		 JButton btn2 = new JButton("2");
		 JButton btn3 = new JButton("3");
		 JButton btn4 = new JButton("4");
		 JButton btn5 = new JButton("5");
		 JButton btn6 = new JButton("6");
		 JButton btn7 = new JButton("7");
		 JButton[] btn = {btn1, btn2, btn3, btn4, btn5, btn6, btn7};
		 
		 Container c = getContentPane();
		 c.setLayout(new FlowLayout());
		 for(int i=0; i<btn.length; i++) {
			 c.add(btn[i]);
		 }

実行結果

image.png

1~7までのボタンが左から右に一列に表示されている。

次はボタンの大きさ色々変えてみる。
ボタン1は(50,50), ボタン4は(50,100), ボタン5は(100,50)にsetPrefferedSizeメソッドを使い変更してみた。これ以外のボタンはサイズは変更していない。

実行結果

image.png
1,4,5のボタンのサイズが変わっていること、横一列では入らなくなったのでボタン7が二段目の中央に移動していることが分かる。どうもコンポーネントの配置は中央揃えのよう。

左揃えにできないものかと思って、コードの一番下のコンテナに追加している部分を

 c.add(btn[i],FlowLayout.LEFT);

と書き換えるとこんな結果になった。(ちなみにボタンサイズは(75,75))
image.png
右から左に順番に配置されており、後から加えたコンポーネントの方が上段に来ている。それに上段に4つ。。。予想していた動きと違ってびっくり!

自分がやりたかった左揃えはこんな書き方で実現できた。

 Container c = getContentPane();
		 FlowLayout layout = new FlowLayout();
		 layout.setAlignment(FlowLayout.LEFT);
		 c.setLayout(layout);
		 for(int i=0; i<btn.length; i++) {
			 c.add(btn[i]);
		 }

image.png

これはsetAlignmentメソッドを使ってそろえ方の設定をした。
addメソッドの引数に渡すやり方と挙動が違った理由は今のところはわからなかったけれど、こういう動きになるんだな~というのはなんとなく理解できた。左詰めのFlowLayoutはiPhoneのホームのアイコンの並びと同じような動きみたいだ。

CardLayout

CardLayoutは、例えばJPanelに複数のコンポーネントを重ねて載せることができ、指定したコンポーネントが表示されるよう切り替えられるようにするもの。画面切り替えにも使える。

思いつきでじゃんけんゲームを作ってみた。

コード

public class study extends JFrame implements ActionListener{
	JLabel myHand;
	JPanel card1;
	JPanel card2;
	JPanel card3;
	JPanel cardPanel;
	CardLayout layout;
	public static void main(String[] args) {
		study frame = new study();
		frame.setVisible(true);
	}
	
	study() {
		 setBounds(100,100,600,400);
		 setLocationRelativeTo(null);
		 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		 
		 JPanel enemy = new JPanel();
		 JLabel enemyName = new JLabel("相手");
		 
		card1 = new JPanel();
		JLabel rock = new JLabel("グー");
		card1.add(rock);
		
		card2 = new JPanel();
		JLabel scissors = new JLabel("チョキ");
		card2.add(scissors);
		
		card3 = new JPanel();
		JLabel paper = new JLabel("パー");
		card3.add(paper);
		 
		 layout = new CardLayout();
		
		 cardPanel = new JPanel();
		 cardPanel.setLayout(layout);
		 
		 cardPanel.add(card1, "Rock");
		 cardPanel.add(card2, "Scissors");
		 cardPanel.add(card3, "Paper");
		 
		 enemy.add(enemyName);
		 enemy.add(cardPanel);
		 
		 JButton rockBtn = new JButton("グー");
		 rockBtn.addActionListener(this);
		 rockBtn.setActionCommand("Rock");
		 
		 JButton scissorsBtn = new JButton("チョキ");
		 scissorsBtn.addActionListener(this);
		 scissorsBtn.setActionCommand("Scissors");
		 
		 JButton paperBtn = new JButton("パー");
		 paperBtn.addActionListener(this);
		 paperBtn.setActionCommand("Paper");
		 
		 JPanel btnPanel = new JPanel();
		 btnPanel.add(rockBtn);
		 btnPanel.add(scissorsBtn);
		 btnPanel.add(paperBtn);
		 
		 JPanel myHandPanel = new JPanel();
		 JLabel yourName = new JLabel("あなた");
		 myHand = new JLabel();
		 
		 myHandPanel.add(myHand);
		 myHandPanel.add(yourName);
		 
		 JLabel vs = new JLabel("VS");
		 
		 JPanel mainPanel = new JPanel();
		 mainPanel.add(enemy);
		 mainPanel.add(vs);
		 mainPanel.add(myHandPanel);
		 
		 Container c = getContentPane();
		c.add(mainPanel,BorderLayout.CENTER);
		c.add(btnPanel,BorderLayout.SOUTH);
		
	}
	
	public void actionPerformed(ActionEvent e) {
		String cmd = e.getActionCommand();
		
		if(cmd.equals("Rock")) {
			Janken();
			myHand.setText("グー");
		}else if(cmd.equals("Scissors")) {
			Janken();
			myHand.setText("チョキ");
		}else if(cmd.equals("Paper")) {
			Janken();
			myHand.setText("パー");
		}
	}
	
	public void Janken() {
		Random random = new Random();
		int num = random.nextInt(3) + 1;
		
		if(num == 1) {
			layout.show(cardPanel, "Rock");
		}else if(num == 2) {
			layout.show(cardPanel, "Scissors");
		}else if(num == 3) {
			layout.show(cardPanel, "Paper");
		}
	}
}

実行結果

ランダム要素があるので複数枚はる。
1枚目 グーボタン押した
image.png
2枚目 チョキボタン押した
image.png

ちょっと説明

画面下部のグーチョキパーボタンを押すことで、自分が出す手を選ぶことができ、この処理と同時に相手の出す手もランダムに決定される。
これ勝敗判定をつけるとしたらどう書けばいいんだろう?全パターン書き連ねるのかな?暇なときにでも調べて試してみる。

このコードでCardLayoutを使ってるのは相手の手が表示される部分。わざわざこのレイアウトを採用するメリットはなさげだけど、思いついちゃったので作ってみた。CardLayoutじゃなくても作れそう。

たぶんこのレイアウトマネージャーは複数のコンポーネントを載せたJPanelなど
の表示非表示を切り替えるために使うべきなんだろう。

終わり

他にもレイアウトマネージャーはあるけど、一旦おしまい。次はGridLayoutを使ってなんちゃってビンゴゲームを作れないか試してみる。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0