본문 바로가기

JAVA

[Java] 오셀로, 체스 게임 UI 만들기

0. 소개

이 포스터에서는 Java Eclipse의 Swing Component를 이용하여 UI를 만들 예정이다. 

오셀로와 체스는 둘다 판이 8 * 8이므로 UI는 둘 다 공용으로 사용할 수 있다.

 

1. 원리

큰 하나의 패널(JPanel)안에 두 개의 요소를 더할 것이다. 하나는 게임을 조작하는 JToolbar, 나머지 하나는 Board로 체스판 혹은 오셀로판을 안에 넣을 것이다.

 

JToolbar에서는 게임 조작요소 버튼들과, 스코어를 담당한다. 체스판으로 만들경우 적절히 조절해서 컴포넌트를 조정해서 쓰기를 바란다.

 

Board에서는 GridLayout를 이용해 64개의 칸으로 나누고 각 칸을 JPanel의 배열로 각 칸에 넣어주고, 각 JPanel에는 ImageIcon을 통해 체스판 말이나, 오셀로 돌을 둘 수 있다. 필자는 오셀로 돌로 넣었다. 이 JPanel의 배열은 아래 코드에서 JPanelSquare[ ][ ]로 선언했다.

 

2. 코드 작성하면서 어려웠던 점

결론적으로 말하면 이 UI를 만드는 건 쉽다. 하지만 만약에 버튼을 클릭했을 때 조작하려고 하면 클릭된 부분이 어떤 row의 어떤 column인지 알아내야 하는데, 클릭된 부분의 곳을 알아내 줄 변수를 설정하는게 어려웠다. 무작정 64개의 GridLayout에 JPanel만 집어넣으면 Ui는 그럴듯해 보이지만, 예를 들어 (3,4) 부분을 조작하려고 하면 변수를 꺼내서 조작하기 쉽지 않기에 이 코드의 핵심인 JPanelSquare[ ] [ ] 클래스를 선언하고 JPanel를 상속받아 JPanel처럼 사용한다.

 

마지막으로 사용자가 선언한 클래스를 Component처럼 이용하는 거기에 중간중간 오버라이드로 메소드를 맞게 설정해줘야 한다. 예를 들어 다음 사진을 보면 Component의 add 메소드를 오버라이드 해서 변수에 맞게 설정해준 것이다.

아래 사진은 JPanelSquare[ ] [ ] 클래스에서 찾을 수 있다.

 

(이런 조작을 할 수 있는 글을 못 찾아서, 찾는데 시간이 거의 하루 걸렸던 거 같다. 이 글이 여러분에게 도움이 되었기를 바랍니다.)

그림1. add 메소드 오버라이드

 

 

3. 코드

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;

public class OthelloUi extends JPanel {
	
	JLayeredPane layeredPane;
	JPanel board;
	JPanel controlPanel;
	JToolBar tool;
	JPanel gui;
	
	JButton restartButton;
	JButton endButton;
	JButton giveUpButton;
	JButton skipTurnButton;
	
	JLabel imgLabel;
	
	JPanelSquare[][] squarePanel = new JPanelSquare[8][8];
	
	public OthelloUi() throws IOException {	

		Dimension guiSize = new Dimension(600,600);
		Dimension size = new Dimension(600,600);
		
		gui = new JPanel(new BorderLayout());
		gui.setSize(guiSize);

		//Toolbar 달기
		tool = new JToolBar();
		
		restartButton = new JButton("Game ReStart");
		endButton = new JButton("Game End");
		giveUpButton = new JButton("Game GiveUp");
		skipTurnButton = new JButton("Skip turn");	
		
		tool.add(restartButton);
		tool.addSeparator();
		tool.add(endButton);
		tool.addSeparator();
		tool.add(giveUpButton);
		tool.addSeparator();
		tool.add(skipTurnButton);

		
		gui.add(tool, BorderLayout.NORTH);

		//JFrame에 LayeredPane 넣기
		layeredPane = new JLayeredPane();
		layeredPane.setPreferredSize(size);
		gui.add(layeredPane);
		
		//LayeredPane에 board 넣기
		board = new JPanel();
		board.setLayout(new GridLayout(8,8));
		board.setPreferredSize(size);
		board.setBounds(0, 0, size.width, size.height);
		layeredPane.add(board,JLayeredPane.DEFAULT_LAYER);
		
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				squarePanel[i][j] = new JPanelSquare(i, j, "Empty");
				squarePanel[i][j].setLayout(new BorderLayout());
				squarePanel[i][j].setBackground((i + j) % 2 == 0 ? Color.lightGray : Color.white);
				ImageIcon icon = new ImageIcon(new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB));
				imgLabel = new JLabel(icon, SwingConstants.CENTER);

				squarePanel[i][j].add(imgLabel);
				board.add(squarePanel[i][j]);
			}
		} // for
	}
	
	public Dimension setPreferredSize() {
		return new Dimension(700,600);
	}
	
	
	private static void createAndShowGUI() throws IOException {
		// Create and set up the window.
		
		JFrame frame = new JFrame();
		OthelloUi othelloUi = new OthelloUi();
		frame.add(othelloUi.gui);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setTitle("오델로 게임");
		frame.setResizable(false);
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}

	public static void main(String[] args) {
		// Schedule a job for the event-dispatching thread:
		// creating and showing this application's GUI.
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					createAndShowGUI();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}
}

class JPanelSquare extends JPanel{
	
	int column;
	int row;
	String state;
	JLabel piece = null;
		
	public JPanelSquare(int row, int column, String state) {
		this.column = column;
		this.row = row;
		this.state = state;
	}	
	
	public int getColumn() {
		return column;
	}
	
	public int getRow() {
		return row;
	}
	
	@Override
	public Component add(Component c) {
		piece = (JLabel) c;
		return super.add(c);
	}
	
    @Override
    public void remove(Component comp) {
        piece = null;
        super.remove(comp);
    }

	public JLabel getPiece() {
		return piece;
	}
	
	public void setPiece() {
		
	}
	
	public void setState(String state) {
		this.state = state;
	}
	
	public String getState() {
		return state;
	}
		
} //JPanelSquare Class

 

 

 

4. 사진

그림2. 오셀로, 체스판 UI