자바로 PC방 프로그램만들기

8초식. [뷰]관리화면에 좌석 여러개 띄우기

자 이제 메인화면에 좌석을 넣어줘보도록 합시다.

우선 Framemanage 클래스에 다음과 같은 필드를 넣어주도록 합시다.

int posXpanSeat,posYpanSeat;
PanSeat[] pan = new PanSeat[50];

좌석의 X, Y 좌표정수와 좌석을 넣어줄 50개의 배열입니다.

그리고 생성자 안에 다음과 같이 좌석을 넣어줘보도록 하겠습니다.(소스의 일부분)

// 좌석 패널 시작 시작점 165 129
JPanel seat50 = new JPanel();
seat50.setLayout(null);
seat50.setOpaque(false);
seat50.setBounds(165, 109, 1368, 686);
for (int seat = 0; seat < 50; seat++) {
    pan[seat] = new PanSeat(seat);
	if (seat % 10 == 0 && seat != 0) {
		posXpanSeat = 0;
		posYpanSeat += 140;
	}
	pan[seat].setBounds(posXpanSeat, posYpanSeat, 99, 99);
	posXpanSeat += 135;
	seat50.add(pan[seat]);
}

	
add(setJLayered(backGround, myStarPanel, imgClock, clockMessage, seat50));

소스에 대해 잠시 얘기를하자면 

seat50.다음에 설정자로 레이아웃을 Null로 잡아주며 투명처리와 위치를 정해주고,

그 다음에 seat50안에 들어갈 좌석들을 for문으로 돌려서 잡아주게 됩니다. 좌석번호가 0으로 떨어지게 되면

Y좌표를 늘려나가면서 위치를 지정해주는 것을 보실 수가 있습니다. ㅌ

다음과 같은 화면을 보실 수가 있으실 것입니다. 

자 지금 이대로 화면에 넣었는데 뭔가 심심하죠...
그러므로 쓰레드를 넣어서 저 좌석들이 랜덤으로 나타나게 해줘야 합니다.. 어떻게 해야 할까요?!

 

일단 쓰레드를 돌려가면서 랜덤으로  (rand) 시간차이를 줘가면서 (Thread.sleep) add 해보면 될 것같다는 생각이 듭니다. 조금 구현해볼까요?

 

랜덤으로 좌석 나타나게 하기

음 먼저 내부클래스로 쓰레드를 만들어주도록 하겠습니다.
이것을 ManageFrame밑에 내부클래스로 넣어주도록 하겠습니다. 

// 좌석 쇼 쓰레드
class SeatThread extends Thread {
    @Override
	public void run() {
		Set<Integer> randomNumbers = new LinkedHashSet<Integer>();
		for (; randomNumbers.size() < 50;) {
			int x = (int) ((Math.random() * 50));
			randomNumbers.add(x);
		}
		int tmp = 0;
		try {
			for (Integer s : randomNumbers) {
				tmp++;
				if (tmp > 30)
					Thread.sleep(5*s);
				if (tmp == 50) {
					Thread.sleep(1000);
					System.out.println("50번째");
				}
				seat50.add(pan[s]);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

쓰레드를 돌리는 방법에는 두가지가 있었는데 한가지는 Runnable 인터페이스를 구현하는 방법이었고 두번째는 쓰레드 클래스를 상속하는 방법이었습니다.  여기선 쓰레드클래스를 상속하는 방법을 쓰는데요.

랜덤으로 띄우게 하기위해서 먼저 랜덤숫자를 MathRandom을 이용해서 만들어내고 그것을 LinkedHashSet에 넣어줍니다. LinkedHashSet은 중복을 허용하지 않고, 입력순서대로 출력하게 해주는 Set입니다.

첫번째 For문에서 숫자를 입력해서 해쉬셋에 넣어주고, 두번째 try문을 감싸진 for문에서는 seat50 패널에 좌석패널을 넣어주는 역할을 합니다.  

생성자 안에 있던 JPanel seat50 = new JPanel(); 를 클래스를 생성자를 벗어나 필드로 넣어주시고
seat50에 하나하나 addㅐ

// seat50.add(pan[seat]); 
new SeatThread().start(); //이 문장은  좌석 하나하나 만드는 for문이 끝나고 실행시켜주셔야 합니다. 
이런 식으로 쓰레드를 켜면서 실행시켜주면 되겠습니다.
 
하지만 막상 실행시키면 에러가 나면서 화면이 안뜹니다.
예..;; 에러메시지를 살펴보니.. 새로 필드로 위치를 옮긴 JPanel seat50 이 리플렉션에서 걸려서 안되는 것이죠.
seat50의 정보를 Setting 클래스에 넣어주도록 하겠습니다.
 
Setting 클래스에 이거 한줄을 넣어주시고
public static Rectangle seat50 = new Rectangle(165, 109, 1368, 686);
FrameManage에서는 이 세줄을 안 적어줘도 되게 됩니다^^
 
seat50.setLayout(null);
seat50.setOpaque(false);
seat50.setBounds(165, 109, 1368, 686);
 
그러면 다음과 같은 화면이 나오게 됩니다~
그러면 다음 시간에는 밑에 관리자 버튼들을 넣어보도록 하겠습니다. 감사합니다. 
하단에 소스코드 여기까지 한것 완성 첨부합니다.
package view;

import java.awt.Component;
import java.awt.Rectangle;
import java.lang.reflect.Field;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

import view.panel.ClockMessage;
import view.panel.ImgClock;
import view.panel.MyStarPanel;
import view.panel.PanImgload;
import asset.Setting;

@SuppressWarnings("serial")
public class FrameManage extends JFrame {

    public JLayeredPane layeredPane = new JLayeredPane();
	// JPanels
	private PanImgload backGround = new PanImgload("img/mainHud_back.png");
	private MyStarPanel myStarPanel = new MyStarPanel();
	private ImgClock imgClock = new ImgClock();
	private ClockMessage clockMessage = new ClockMessage();

	int posXpanSeat, posYpanSeat;
	PanSeat[] pan = new PanSeat[50];
	JPanel seat50 = new JPanel();

	public FrameManage() {
		// Configure this Frame
		setLayout(null);
		setVisible(true);
		setTitle("ManageView");
		setSize(Setting.bDimen);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocation(Setting.locationX, Setting.locationY);

		// 좌석 패널 시작 시작점 165 129

		//seat50.setLayout(null);
		//seat50.setOpaque(false);
		//seat50.setBounds(165, 109, 1368, 686);
		for (int seat = 0; seat < 50; seat++) {
			pan[seat] = new PanSeat(seat);
			if (seat % 10 == 0 && seat != 0) {
				posXpanSeat = 0;
				posYpanSeat += 140;
			}
			pan[seat].setBounds(posXpanSeat, posYpanSeat, 99, 99);
			posXpanSeat += 135;
			// seat50.add(pan[seat]);
			
		}
		new SeatThread().start();;
		add(setJLayered(backGround, myStarPanel, imgClock, clockMessage, seat50));
		add(layeredPane);
	}

	public static void main(String[] args) throws Exception {
		FrameManage manageView = new FrameManage();
		manageView.setRectangles(FrameManage.class, manageView, Setting.class, Setting.getInstance());

	}

	// Setting inner Methods
	private JComponent setJLayered(Component... components) {
		int i = 0;
		for (Component component : components)
			layeredPane.add(component, new Integer(i++));
		return layeredPane;
	}

	// Reflection Practice
	public void setRectangles(Class<?> clazz, Object instance, Class<?> targetClass, Object target) throws Exception {
		Object tempObject = null;
		for (Field field : clazz.getDeclaredFields()) {
			if ((tempObject = field.get(instance)) instanceof JComponent) {
				((JComponent) tempObject).setBounds((Rectangle) targetClass.getDeclaredField(field.getName()).get(target));
				((JComponent) tempObject).setOpaque(false);
				((JComponent) tempObject).setLayout(null);
			}
			if (tempObject instanceof Runnable)
				new Thread((Runnable) tempObject).start();
		}
	}

	// TODO 계속 들어감
	
	// 좌석 쇼 쓰레드
	class SeatThread extends Thread {
		@Override
		public void run() {
			Set<Integer> randomNumbers = new LinkedHashSet<Integer>();
			for (; randomNumbers.size() < 50;) {
				int x = (int) ((Math.random() * 50));
				randomNumbers.add(x);
			}
			int tmp = 0;
			try {
				for (Integer s : randomNumbers) {
					tmp++;
					if (tmp > 30)
						Thread.sleep(5*s);
					if (tmp == 50) {
						Thread.sleep(1000);
						System.out.println("50번째");
					}
					seat50.add(pan[s]);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

 

 
 

댓글

댓글 본문
graphittie 자세히 보기