ㅇ 이클립스에서 콘솔창으로 출력을 하면 한글이 깨질 때가 있다.

ㅇ 인코딩 설정이 제대로 되지 않았기 때문인데,

ㅇ 이를 고치려면 다음과 같이 하면 된다.

- 콘솔창 출력에서 한글이 깨지면 아래와 같이 나온다. 



- 프로젝트를 선택하고,
- 오른쪽 마우스버튼을 클릭하고
- Run As / Run Configuration을 클릭




- 새로운 창 (Run configurations)이 열리면,
- 맨 오른쪽 탭 (Common)을 선택하고,
- Encoding 부분을 보면 한글과 맞지 않는 인코딩형식이 설정되어 있는 것을 볼 수 있다.




- 보통 한글은 UTF-8 인코딩으로 설정한다.




- 설정 완료후 출력을 확인하면,
- 아래와 같이 한글이 제대로 출력된 것을 볼 수 있다.




반응형
LIST


클라이언트 소스코드

client_src.zip



서버소스코드

server_src.zip


반응형
LIST

'Java프로그래밍 > 예제문제' 카테고리의 다른 글

Network pingpong server and client  (0) 2016.05.24
network pingpong serer  (1) 2016.05.17
network pingpong client  (1) 2016.05.17
네트워킹 예제  (1) 2016.05.13
혼자 탁구 소스코드  (0) 2016.04.29

Source code of Server side


server.zip



Source code of Client side



client.zip


How to execute:

1. start server first by selecting Test.java and right-clicking "Run As" Java Application

2. start client by selecting Test.java and right-clicking "Run As " Java Application



반응형
LIST

'Java프로그래밍 > 예제문제' 카테고리의 다른 글

네트워크 핑퐁 업데이트 소스코드  (0) 2016.05.31
network pingpong serer  (1) 2016.05.17
network pingpong client  (1) 2016.05.17
네트워킹 예제  (1) 2016.05.13
혼자 탁구 소스코드  (0) 2016.04.29

src.zip


반응형
LIST

'Java프로그래밍 > 예제문제' 카테고리의 다른 글

네트워크 핑퐁 업데이트 소스코드  (0) 2016.05.31
Network pingpong server and client  (0) 2016.05.24
network pingpong client  (1) 2016.05.17
네트워킹 예제  (1) 2016.05.13
혼자 탁구 소스코드  (0) 2016.04.29

src.zip


반응형
LIST

'Java프로그래밍 > 예제문제' 카테고리의 다른 글

Network pingpong server and client  (0) 2016.05.24
network pingpong serer  (1) 2016.05.17
네트워킹 예제  (1) 2016.05.13
혼자 탁구 소스코드  (0) 2016.04.29
당구프로그램 예제  (0) 2016.04.15

Server.java



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package univ.inu.embedded;

import java.net.*;
import java.io.*;

public class Server 
{

	public Server()
	{
		
		try 
		{
			ServerSocket ss = new ServerSocket(9000);
			while (true)
			{
				Socket s = ss.accept();
				
				(new ServerThread(s)).start();
			}
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		
		
	}
	
	
	public static void main(String[] args) 
	{
		new Server();
	}

}



ServerThread.java



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package univ.inu.embedded;

import java.net.*;
import java.io.*;

public class ServerThread extends Thread 
{

	Socket s = null;
	
	public ServerThread()
	{
		
	}
	public ServerThread(Socket _s)
	{
		s = _s;
	}
	public void run()
	{

		try 
		{
			BufferedReader br =
			new BufferedReader(new InputStreamReader(s.getInputStream()));
			BufferedWriter bw =
			new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
			
			while (true)
			{
				bw.write("I am server. Do you hear me?\n");
				bw.flush();
			
				String s = br.readLine();
				System.out.println("Server received :: "+s);
				
				Thread.sleep(10000);
				
			}

		} catch (IOException | InterruptedException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
}



Client.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package univ.inu.embedded;

import java.net.*;
import java.io.*;

public class Client 
{
	
	public Client()
	{
		
		Socket s;
		try 
		{
			s = new Socket("127.0.0.1", 9000);
			BufferedReader br = 
			new BufferedReader(new InputStreamReader(s.getInputStream()));
					
			BufferedWriter bw =
			new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

			while (true)
			{
				String str = br.readLine();
				System.out.println("Client received:: "+str);
						
				bw.write("this is client.\n");
				bw.flush();
				}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	

	public static void main(String[] args) 
	{

		new Client();
		
	}

}
반응형
LIST

'Java프로그래밍 > 예제문제' 카테고리의 다른 글

network pingpong serer  (1) 2016.05.17
network pingpong client  (1) 2016.05.17
혼자 탁구 소스코드  (0) 2016.04.29
당구프로그램 예제  (0) 2016.04.15
Timer : TmerLogic and Test program  (0) 2016.04.08
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package univ.inu.embedded;

public class PoolballThread extends Thread 
{
	private PoolballPanel pp = null;
	private boolean stopped = false;

	public PoolballThread(PoolballPanel _pp)
	{
		pp = _pp;
	}
	
	public void stopUpdate()
	{
		stopped = true;
	}
	
	public void restartUpdate()
	{
		stopped = false;
	}
	
	public void stopAndGo()
	{
		if (stopped == false)
		{
			this.stopUpdate();
		}
		else
		{
			this.restartUpdate();
			synchronized(pp)
			{
				pp.notifyAll();
			}
		}
	}
	
	public void run()
	{
		while (true)
		{
			while (stopped == false)
			{
				pp.repaint();
				try {
					Thread.sleep(25);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			synchronized(pp)
			{	
				try {
					pp.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
		
	}
	
	
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package univ.inu.embedded;

import javax.swing.JFrame;

public class GameFrame extends JFrame 
{
	public GameFrame()
	{
		this.setSize(PoolballPanel.WIDTH, PoolballPanel.HEIGHT);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		PoolballPanel pp = new PoolballPanel();
		this.add(pp);
		this.setVisible(true);
	}
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package univ.inu.embedded;

public class Test 
{

	public static void main(String[] args) 
	{
		GameFrame gf = new GameFrame();
	}

}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package univ.inu.embedded;

import java.awt.*;
import java.awt.Graphics;
import java.awt.event.KeyEvent;

public class Racquet 
{
	int x;
	int y;
	int xspeed = 0;
	Color color;
	static int WIDTH = 300;
	static int HEIGHT = 20;

	public Rectangle getDimension()
	{
		return new Rectangle(x,y-3,WIDTH, 3);
	}
	
	public void resetSpeed(KeyEvent e)
	{
		if (e.getKeyCode() == KeyEvent.VK_LEFT ||
			e.getKeyCode() == KeyEvent.VK_RIGHT)
		{	
			xspeed = 0;
		}
	}
	public void setSpeed(KeyEvent e)
	{
		if (e.getKeyCode() == KeyEvent.VK_LEFT)
		{
			xspeed = -10;
		}
		else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
		{
			xspeed = 10;
		}
	}
	
	public void move()
	{
		if ((x+xspeed) >= 0 && 
			(x+xspeed) < (PoolballPanel.WIDTH - WIDTH))
		{
			x = x + xspeed;
		}
	}
	
	public void draw(Graphics g)
	{
		g.setColor(this.color);
		g.fillRect(x, y, WIDTH, HEIGHT);
	}
	
	public Racquet()
	{
		
	}
	
	public Racquet(int _x, int _y, Color _color)
	{
		x = _x;
		y = _y;
		color = _color;
	}
	
	
	
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package univ.inu.embedded;

public class PoolballThread extends Thread 
{
	private PoolballPanel pp = null;
	private boolean stopped = false;

	public PoolballThread(PoolballPanel _pp)
	{
		pp = _pp;
	}
	
	public void stopUpdate()
	{
		stopped = true;
	}
	
	public void restartUpdate()
	{
		stopped = false;
	}
	
	public void stopAndGo()
	{
		if (stopped == false)
		{
			this.stopUpdate();
		}
		else
		{
			this.restartUpdate();
			synchronized(pp)
			{
				pp.notifyAll();
			}
		}
	}
	
	public void run()
	{
		while (true)
		{
			while (stopped == false)
			{
				pp.repaint();
				try {
					Thread.sleep(25);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			synchronized(pp)
			{	
				try {
					pp.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
		
	}
	
	
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package univ.inu.embedded;

import java.awt.*;

public class Ball 
{
	private boolean noMoreUpdate = false;
	private boolean visible = true;
	private int x = 100;
	private int y = 100;
	private int size = 30;
	private int xSpeed = 5;
	private int ySpeed = 5;
	private Color myColor = Color.YELLOW;
	private Racquet racquet = null;
	
	public void setVisible(boolean _visible)
	{
		visible = _visible;
	}
	
	public boolean getVisible()
	{
		return visible;
	}
	
	public Ball()
	{
		
	}
	public Ball(int _x, int _y, int _size, 
			int _xSpeed, int _ySpeed, 
			Color _myColor, Racquet _racquet)
	{
		x = _x;
		y = _y;
		size = _size;
		xSpeed = _xSpeed;
		ySpeed = _ySpeed;
		myColor = _myColor;
		racquet = _racquet;
	}
	
	public void update()
	{
		if (noMoreUpdate == true)
		{
			return;
		}
		x = x + xSpeed;
		if (x > PoolballPanel.WIDTH || x < 0)
		{
			xSpeed = -xSpeed;
			//setVisible(false);
		}
		
		y = y + ySpeed;
		
		if (y > PoolballPanel.HEIGHT)
		{
			noMoreUpdate = true;
			visible = false;
		}
		else if (y < 0)
		{
			ySpeed = -ySpeed;
			//setVisible(false);
		}
		
		Rectangle myDimension = new Rectangle(x,y,size,size);
		if (myDimension.intersects(racquet.getDimension()) == true)
		{
			ySpeed = -ySpeed;
		}
		
	}
	
	public void draw (Graphics g)
	{
		if (getVisible() == true)
		{
			g.setColor(myColor);
			g.fillOval(x, y, size, size);
		}
	}
}


반응형
LIST

'Java프로그래밍 > 예제문제' 카테고리의 다른 글

network pingpong client  (1) 2016.05.17
네트워킹 예제  (1) 2016.05.13
당구프로그램 예제  (0) 2016.04.15
Timer : TmerLogic and Test program  (0) 2016.04.08
Timer Source Code: TimerUI  (0) 2016.04.08
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package univ.inu.embedded;

import java.awt.*;

public class Ball 
{
	private int x = 100;
	private int y = 100;
	private int size = 30;
	private int xSpeed = 5;
	private int ySpeed = 5;
	private Color myColor = Color.YELLOW;
	
	public Ball()
	{
		
	}
	public Ball(int _x, int _y, int _size, 
			int _xSpeed, int _ySpeed, Color _myColor)
	{
		x = _x;
		y = _y;
		size = _size;
		xSpeed = _xSpeed;
		ySpeed = _ySpeed;
		myColor = _myColor;
	}
	
	public void update()
	{
		x = x + xSpeed;
		if (x > PoolballPanel.WIDTH || x < 0)
		{
			xSpeed = -xSpeed;
		}
		
		y = y + ySpeed;
		if (y > PoolballPanel.HEIGHT || y < 0)
		{
			ySpeed = -ySpeed;
		}
	}
	
	public void draw (Graphics g)
	{
		g.setColor(myColor);
		g.fillOval(x, y, size, size);
	}
	
	
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package univ.inu.embedded;

import java.awt.*;
import javax.swing.*;
import java.util.Random;

public class PoolballPanel extends JPanel 
{

	public static int WIDTH = 600;
	public static int HEIGHT = 400;
	private Ball[] ball = null;

	
	public PoolballPanel()
	{
		ball = new Ball[10];
		Random r = new Random();
		for (int i = 0; i < 10; i++)
		{
			ball[i] = new Ball(r.nextInt(WIDTH),
					r.nextInt(HEIGHT),
					30,
					5*(r.nextBoolean() ? 1 : -1), 
					5*(r.nextBoolean() ? 1: -1), 
					Color.yellow);
		}
		
		this.setBackground(Color.RED);
		PoolballThread pt = new PoolballThread(this);
		pt.start();
		
	}
	
	@Override
	protected void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		for (int i = 0; i < 10; i++)
		{
			ball[i].update();
		}
		for (int i = 0; i < 10; i++)
		{
			ball[i].draw(g);
		}
	}
	
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package univ.inu.embedded;

public class PoolballThread extends Thread 
{
	private PoolballPanel pp = null;

	public PoolballThread(PoolballPanel _pp)
	{
		pp = _pp;
	}
	
	public void run()
	{
		
		while (true)
		{
			pp.repaint();
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package univ.inu.embedded;

import javax.swing.JFrame;

public class GameFrame extends JFrame 
{
	public GameFrame()
	{
		this.setSize(PoolballPanel.WIDTH, PoolballPanel.HEIGHT);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		PoolballPanel pp = new PoolballPanel();
		this.add(pp);
		this.setVisible(true);
	}
}
package univ.inu.embedded; public class Test { public static void main(String[] args) { GameFrame gf = new GameFrame(); } }
반응형
LIST

'Java프로그래밍 > 예제문제' 카테고리의 다른 글

네트워킹 예제  (1) 2016.05.13
혼자 탁구 소스코드  (0) 2016.04.29
Timer : TmerLogic and Test program  (0) 2016.04.08
Timer Source Code: TimerUI  (0) 2016.04.08
계산기 만들기 숙제  (0) 2016.03.25
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package univ.embedded.timer;

import javax.swing.*;

public class TimerLogic extends Thread 
{
	private JLabel timeLabel = null;
	private TimerUI tui = null;
	
	public TimerLogic()
	{
		
	}
	
	public TimerLogic(JLabel _timeLabel)
	{
		timeLabel = _timeLabel;
	}
	
	public TimerLogic(JLabel _timeLabel, TimerUI _tui)
	{
		timeLabel = _timeLabel;
		tui = _tui;
	}
	
	
	public void run()
	{
		for (int i = 10; i >= 0; i--)
		{
			timeLabel.setText(""+i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		tui.activateButton();
		
	}
	

}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import univ.embedded.timer.*;

public class MyTest {

	public static void main(String[] argv)
	{
		TimerUI tu = new TimerUI();
	}
	
}
반응형
LIST
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package univ.embedded.timer;

import java.awt.Color;
import java.awt.event.*;

import javax.swing.*;

public class TimerUI extends JFrame 
implements ActionListener
{
	JLabel timeLabel = null;
	JButton startButton = null;

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		//TimerLogic lc = new TimerLogic(timeLabel);
		//lc.start();
		startButton.setText("NO TOUCH");
		startButton.setEnabled(false);
		
		(new TimerLogic(timeLabel, this)).start();
	}
	
	public void activateButton()
	{
		startButton.setText("Start");
		startButton.setEnabled(true);
	}
	
	public TimerUI()
	{
		setSize(300, 200);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("10 Sec. Timer");
		
		timeLabel = new JLabel("10");
		startButton = new JButton("Start");
		startButton.addActionListener(this);
		
		setLayout(null);
		timeLabel.setSize(100, 60);
		startButton.setSize(100, 60);
		
		timeLabel.setLocation(50, 20);
		startButton.setLocation(50, 100);
		
		add(timeLabel);
		add(startButton);
		
		
		setVisible(true);
	}

	
}
반응형
LIST

계산기 만들기

두 개 숫자의 +, -를 계산하여 출력하는 계산기를 작성하시오.

클래스 CalculatorLogic을 완성하여,

다음과 같은 계산이 동작하도록 하시오.


1 + 1 = 2

1 + 11 = 12

11 + 1 = 12

1 - 1 = 0

1 - 11 = -10

11 - 1 = 10


숫자: 1자리 이상, 10자리까지 처리가 가능해야 함.

연산: +와 -만 처리

CLEAR를 누르면 0으로 초기화하고 0만 표시


입력순서에 맞는 않을 경우, 무시


제출물: 돌아가는 소스코드 시연


소스코드 1.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class CalculatorLogic 
{

	boolean firstNum;
	boolean opSymbol;
	boolean secondNum;
	
	int first;
	int second;
	String op;
	
	public String addSymbol(String s)
	{
		if (s.equalsIgnoreCase("+") == true)
		{
			op = s;
			return "";
		}
		else if (s.equalsIgnoreCase("-") == true)
		{
			op = s;
			return "";
		}
		else if (s.equalsIgnoreCase("=") == true)
		{
			if (op.equalsIgnoreCase("+"))
			{
				return first+second+"";
			}
			else if (op.equalsIgnoreCase("-"))
			{
				return first-second+"";
			}
		}
		else
		{
			return "---";
		}
		return "";

	}
	
	public CalculatorLogic()
	{
		firstNum = false;
		opSymbol = false;
		secondNum = false;
		first = 0;
		second = 0;
		op = "";
	}
	
}


소스코드 2.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import java.awt.*;

import javax.swing.*;

import java.awt.event.*;

public class CalculatorExterior extends JFrame
implements ActionListener
{
	CalculatorLogic cl;
	JPanel mainPanel;
	JPanel bottomPanel;
	JButton[] buttons;
	JTextField resultField;
	String[] buttonLabels = {"0","1","2","3","4",
	                     	 "5", "6", "7", "8", "9",
	                     	 "+", "-", "=", "CLEAR", ""};
	
	private void buildGUI()
	{
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(600, 600);
		setTitle("Calculator");
		
		mainPanel = new JPanel();
		bottomPanel = new JPanel();
		this.setLayout(new GridLayout(2,1));
			
		this.add(mainPanel);
		this.add(bottomPanel);
		
		mainPanel.setLayout(new GridLayout(0,5));
		for (int i = 0; i < 15; i++)
		{
			buttons[i] = new JButton(buttonLabels[i]);
			buttons[i].addActionListener(this);
			
			mainPanel.add(buttons[i]);
		}
		bottomPanel.setLayout(new GridLayout(0,1));
		resultField = new JTextField(40);
		bottomPanel.add(resultField);
		
		setVisible(true);
	}
	
	public CalculatorExterior()
	{
		cl = new CalculatorLogic();
		buttons = new JButton[15];
		buildGUI();
	}

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		JButton btn = (JButton)e.getSource();
		//System.out.println("Button pushed "+btn.getText());
		if (btn == buttons[13]) // clear button
		{
			resultField.setText("0");
		}
		else
		{
			String result = cl.addSymbol(btn.getText());
			resultField.setText(result);
		}
	}

}


소스코드 3.

1
2
3
4
5
6
7
8
9
public class Test {

	public static void main(String[] args) {
		
		CalculatorExterior ce = new CalculatorExterior();

	}

}


반응형
LIST



Ragged 배열(Array)


Ragged의 의미

'너덜너덜해진', 

'옷이 누더기가 된',

'해진' 이라는 뜻을 갖는다.



그래서, ragged flag라고 하는 것은

위의 그림처럼 끝이 다 해진 깃발을 말한다.


Ragged 배열(array)의 의미

2차원 배열을 생각해 보면,

각 행마다 열의 개수가 모두 똑같다.

Ragged array는 각 행마다 열의 개수가 다른 배열을 의미한다.


아래 그림을 보자.

왼쪽에는 일반 2차원배열이 있다.

3개의 행으로 이루어져 있고, 각 행마다 모두 3개씩의 열을 갖는다.

반면에,

오른쪽을 보면 2차원 배열이긴 한데, 모양새가 예사롭지 않다.

우선 3개의 행이 있으되,

0번 행은 2개의 열,

1번 행은 3개의 열,

2번 행은 4개의 열을 갖는다.

이런 것을 ragged array라고 한다.



Ragged 배열의 생성


Ragged 배열은 각 행마다 열의 개수가 다르기 때문에,

일반적인 이차원 배열처럼 만들 수는 없다.

대신, 각 행마다 필요한 열의 개수만큼 만들어 넣어야 한다.

예를 들어, 위의 그림에 나온 ragged 배열을 만드는 프로그램은 아래와 같다.



line 8

행의 개수만 3으로 정해졌기 때문에, 열의 개수는 공백으로 둔 채 2차원 배열을 만든다.

line 10

0번 행에는 2개의 공간을 만들기 위해 크기 2인 일차원 배열을 만들어 넣는다.

line 11, 12

1번 행과 2번 행에 각각 크기 3과 4인 일차원 배열을 만들어 넣는다.

line 14-16

만들어지 공간에 값을 넣어본다.


3차원 Ragged 배열


3차원 ragged의 경우에는 머리 속에 금방 떠올리기가 쉽진않다.

우선 아래 프로그램은 ragged 배열을 만드는 예를 보여준다.

line 8

전체 3개의 그룹이 있고, 그룹 안을 어떻게 나누어 쓸 것인가는 그룹별로 결정할 것이므로 나머지는 공백으로 둔다.

line 10-12

그룹안에 서브그룹을 만드는 것이다. 이것은 2차원 배열로 한다. 0번 그룹은 2개의 서브그룹을 만들고, 각 서브그룹마다 공간의 개수가 다르므로 공백으로 둔다.

line 14-22

가장 안쪽에 실제 데이터를 저장하는 공간을 만드는 것이다.


위의 코드 수행에 따른 ragged배열 생성을

그림으로 그려보면 다음과 같다.

실제 데이터가 저장되는 공간은 굵은 점으로 표시하였다. 


반응형
LIST



자동차들이 서로 다른 속도로 움직이면서, 차간 거리 유지, 교차로에서 섰다 가기 등을 하는 영상입니다.

소스코드는 여기에, 


car.zip








반응형
LIST



Java thread를 재미있게 학습하기 위해 GUI를 갖는 예제 프로그램을 만들어 보았습니다.

아주 초보적인 시뮬레이션 프로그램입니다. 자동차들이 움직이는 것을 구현해 보았습니다.

먼저 아래 동영상을 시청해 보세요.



화면에 3개의 사각형이 나타나, 움직이는 것을 볼 수 있습니다. 

너무 억지스럽긴 하지만 사각형들을 자동차라고 합시다.

빨간색, 노란색, 파란색의 자동차를 상상합시다.


파란색 자동차는 위에서 아래 방향으로 움직이고, 빨간색과 노란색은 좌에서 우로 이동합니다.

그리고 각 자동차는 움직이는 속도가 다릅니다. 

빨강 자동차는 속도가 가장 빠르니 스포츠카로 상상하고,

노랑 자동차가 제일 느리니, 유치원 통학버스쯤 되겠지요. 


위 프로그램은 Java언어로 구현하였고, thread를 사용하였습니다.

자세한 소스코드 설명은 아래 나옵니다.

2개의 클래스를 만들었는데, Road 클래스와 CarThread 클래스 입니다.


Road 클래스는 화면과 자동차들을 표시해주는 GUI 클래스입니다.


CarThread 클래스는 자동차의 움직임을 제어하는 클래스입니다. 

동영상 데모에서 3대의 자동차를 나타내기 위해, 3개의 CarThread 객체를 이용합니다.

특히, CarThread 클래스는 Thread를 상속받아 만들었습니다. 

각 자동차를 별도의 독립된 thread로 제어하기 위해서 입니다.


이제 Road 클래스부터 소스코드를 설명해 보겠습니다. 

우선 전체 소스코드는 아래와 아래와 같습니다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package univ.inu.embedded;

import java.awt.Color;

import javax.swing.*;

public class Road extends JFrame 
{

	private void launchCar(int x, int y, Color c, boolean horizontal, int interval)
	{
		JButton b = new JButton();
		b.setBackground(c);
		b.setSize(10, 10);
		b.setLocation(x, y);
		this.add(b);
		
		(new CarThread(b, horizontal, interval)).start();
	}
	
	public Road()
	{
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Road Environment");
		this.setSize(600, 400);
		this.setLayout(null);
		
		launchCar(20, 100, Color.red, true, 10);
		launchCar(50, 200, Color.YELLOW, true, 60);
		launchCar(300, 20, Color.blue, false, 20);	
		
		this.setVisible(true);
	}
}


 라인 7

public class Road extends JFrame 

{

 GUI를 표시해야 하니 Swing의 JFrame을 상속받아 Road클래스를 만듭니다.


 라인 21~26

public Road()
	{
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Road Environment");
		this.setSize(600, 400);
		this.setLayout(null);

화면에 창을 생성하기 전에 크기 등을 설정하는 코드입니다. 

라인 26에서 Layout Manager를 null로 설정합니다. Layout manager를 사용하지 않는다는 의미입니다. 이렇게 되면 우리가 원하는 위치에 자동차를 배치시킬 수 있습니다.  


 라인 28~32

		launchCar(20, 100, Color.red, true, 10);
		launchCar(50, 200, Color.YELLOW, true, 60);
		launchCar(300, 20, Color.blue, false, 20);	
		
	

 메소드 launchCar를 호출하여 자동차를 생성합니다. 자동차가 3대이니 3번 호출합니다. 

각 인수는 다음과 같습니다.

처음 2개의 숫자는 자동차가 생성되는 최초의 (x,y)좌표입니다. 

세번째 인수는 자동차의 색을 나타냅니다.

네번째 인수는 뭘까요? 빨강과 노랑 자동차는 true이고, 파랑 자동차만 false입니다. 힌트드립니다. 파랑 자동차만 위에서 아래로 움직였지요? true는 자동차가 좌에서 우로 움직임을 나타냅니다. false는 위에서 아래로.

마지막 인수는 또 뭘까요? 빨강 자동차의 숫자가 가장 작습니다. 이건 자동차가 움직이는 시간간격입니다. 간격이 작을수록 빨리 움직입니다. 



 라인 10 ~ 19

	private void launchCar(int x, int y, Color c, boolean horizontal, int interval)
	{
		JButton b = new JButton();
		b.setBackground(c);
		b.setSize(10, 10);
		b.setLocation(x, y);
		this.add(b);
		
		(new CarThread(b, horizontal, interval)).start();
	}


 메소드 launchCar를 살펴봅시다.


자동차를 나타내는 JButton객체를 생성하여 객체변수 b에 저장합니다.

b.setBackground( )로 색깔도 지정하구요,

자동차 크기는 10x10 픽셀로 b.setSize( )를 이용하여 설정합니다.

b.setLocation ( )으로 자동차의 초기 위치를 설정합니다.


this.add(b)는 화면에 버튼을 표시합니다.


마지막에는 이 버튼 (자동차)를 움직일 CarThread를 만들고, 실행시킵니다.

CarThread에 대해서는 아래에서 아주 자세히 설명합니다.



이제 CarThread 클래스 소스코드를 설명해 보겠습니다. 

우선 전체 소스코드는 아래와 아래와 같습니다.

다시 한 번 강조하지만 CarThread의 1개 객체는 자동차 1대를 의미합니다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package univ.inu.embedded;

import javax.swing.*;

public class CarThread extends Thread 
{
	JButton b = null;
	int x;
	int y;
	boolean horizontal = true;
	int interval;
	
	public CarThread(JButton _b, boolean _horizontal, int _interval)
	{
		horizontal = _horizontal;
		b = _b;
		interval = _interval;
	}
	
	private void moveLocation(int _x, int _y)
	{
		b.setLocation(_x,_y);
	}
	
	private void removeCar()
	{
		b.setVisible(false);
		
	}
	
	public void run()
	{
		x = b.getLocation().x;
		y = b.getLocation().y;
		
		while (x < 590 && y < 390)
		{
			if (horizontal == true)
			{	
				x = x+1;
			}
			else
			{
				y = y+1;
			}
			
			SwingUtilities.invokeLater(new Runnable()
			{
				public void run()
				{
					moveLocation(x, y);
				}
			});
			try {
				Thread.sleep(interval);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		SwingUtilities.invokeLater(new Runnable()
		{
			public void run()
			{
				removeCar();			
			}
		});
	}
}



 라인 5

public class CarThread extends Thread


 이 클래스는 Thread를 상속받아 만들어집니다.



 라인 7 ~ 11

	JButton b = null;
	int x;
	int y;
	boolean horizontal = true;
	int interval;


클래스의 변수들을 설명하겠습니다.

우선 자동차는 버튼으로 화면에 표시합니다. 이를 위해 JButton 형의 변수 b가 필요합니다.

x, y 변수는 당연히 자동차의 위치좌표를 나타내는 거구요.

boolean 변수 horizontal은 자동차가 움직이는 방향을 나타냅니다. Horizontal의 의미는 "수평"이니 이것이 true이면 좌에서 우로 움직이는 겁니다. false면 위에서 아래로.

int변수 interval은 자동차가 움직이는 시간간격을 나타냅니다. 값이 작을수록 빠르게 움직입니다.



 라인 13 ~ 18

	public CarThread(JButton _b, boolean _horizontal, int _interval)
	{
		horizontal = _horizontal;
		b = _b;
		interval = _interval;
	}


생성자입니다. 특별한 것은 없습니다.

이 객체가 제어를 담당할 버튼 _b를 인수로 받아, 이것을 내부변수 b에 저장합니다.

보통 메소드의 인수 앞에는 '_' (underscore라고 읽습니다.)를 붙이면, 객체 변수와 쉽게 구분이 가능합니다.



 라인 20 ~ 23

private void moveLocation(int _x, int _y)

	{
		b.setLocation(_x,_y);
	}


버튼의 위치를 바꾸는 메소드로, 자동차가 움직이는 것처럼 보이게 합니다.

인수 _x와 _y로 위치를 설정합니다.

이 메소드는 JButton의 setLocation 메소드를 호출합니다.



라인 25 ~ 29 

private void removeCar() { b.setVisible(false); }


자동차를 지우는 메소드입니다. 변수 b는 JButton객체이므로 setVisible(false)를 호출하여 자동차를 화면에서 지웁니다.   



 라인 31 ~ 34

	public void run()
	{
		x = b.getLocation().x;
		y = b.getLocation().y;


Thread가 처리해야 하는 일을 나타내는 run( ) 메소드입니다.

우선 자동차의 현재 좌표를 알아냅니다.



 라인 36 ~ 45

		while (x < 590 && y < 390)
		{
			if (horizontal == true)
			{	
				x = x+1;
			}
			else
			{
				y = y+1;
			}


 자동차가 화면 안의 적정한 영역에 있을 동안에만 thread가 동작해야 합니다.

그래서 x 좌표와 y 좌표의 최대 영역을 while 문으로 지정했습니다.

화면크기가 가로 600, 세로 400이기 때문에, 그것들보다는 약간 작게 지정했습니다.


자동차가 가로로 움직이는 경우, 아닌 경우로 나누어 해당 좌표를 1 픽셀씩 갱신합니다.



 라인 47 ~ 58

			SwingUtilities.invokeLater(new Runnable()
			{
				public void run()
				{
					moveLocation(x, y);
				}
			});
			try {
				Thread.sleep(interval);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}


 이 부분은 상당히 중요합니다.


순서로 보자면 자동차를 새로운 좌표로 옮겨야 합니다. 

그런데, Java에서는 JButton같은 GUI요소들을 갱신할 때는 일반 thread가 할 수 없습니다.

대신 event thread라는 특별한 thread에게 부탁해야 합니다.

다행인 것은 event thread는 이미 생성되어 있기 때문에 따로 만들거나 할 필요는 없습니다.


요약하자면, CarThread가 JButton의 새로운 위치를 계산할 순 있지만, 그 위치에 버튼을 옮겨 그리는 것은

CarThread에게는 금지된 일입니다. 대신 event thread에게 부탁해야 됩니다.


어떻게 부탁하냐면,

라인 47 ~ 53 처럼 하면 됩니다. 길고 복잡해 보인다구요? 걱정하지 마세요.

핵심은 라인 51. 거기에 내가 부탁하고자 하는 일을 써 넣으면 됩니다.

여기서 부탁한 일은 메소드 moveLocation ( ) 입니다. 위에서 설명했지요. 버튼을 새로운 위치에 그리는 일이라구요.


라인 54 ~ 58은 잠시 쉬어가는 시간을 나타냅니다. 그래야 자동차가 움직이는 것처럼 보이니까요.

이 간격을 조절해서 자동차가 움직이는 속도를 다양하게 할 수 있습니다.

 



 라인 60 ~ 66

		SwingUtilities.invokeLater(new Runnable()
		{
			public void run()
			{
				removeCar();			
			}
		});


 이 부분은while 문 종료 후에 실행됩니다. 즉 자동차가 화면 영역을 벗어날 때 입니다.

메소드 removeCar ( )를 호출하는데, event thread에게 부탁해서 처리합니다.

JButton을 화면에서 사라지게 하는 것도 GUI에 관련된 일이기 때문입니다.











반응형
LIST

여러 thread가 동시에 동일 코드부분을 실행할 때, 이 들 간의 순서를 결정하기 위한 syncrhonized에 대해 설명합니다. 

반응형
LIST

Thread간의 실행 순서를 조절할 수 있는 Wait와 Notify에 대해서 설명합니다.



반응형
LIST


Thread를 정지시키고, 다시 실행시키는 방법에 대해서 설명합니다.



반응형
LIST

실행중인 Thread를 정지시키는 방법에 대해서 설명합니다.



반응형
LIST

Thread를 이용하여 timer를 구현하는 방법에 대해 설명합니다.



반응형
LIST

Timer를 구현하는 방법에 대해서 설명합니다.



반응형
LIST


Thread 클래스를 이용하여 multi-threading을 구현하는 방법에 대해서 설명합니다.




반응형
LIST


Java언어가 제공하는 multi threading 개념에 대해서 설명합니다.




반응형
LIST
이미지를 읽어들여서 화면에 표시하는 소스코드입니다.
BufferedImage 클래스와 WritableRaster 클래스를 이용합니다.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package univ.inu.embedded.imgeditor;

import java.awt.*;
import java.awt.image.*;
import java.io.*;

import javax.imageio.*;
import javax.swing.*;

public class ImageFrame extends JFrame {

	private int width = 0;
	private int height = 0;
	private BufferedImage img = null;
	private MyImgPanel imgPanel = null;
	
	private class MyImgPanel extends JComponent
	{
		
		public void paint(Graphics g)
		{
			Graphics2D g2 = (Graphics2D)g;
			g2.drawImage(img, 0, 0, null);
		}
	}
	
	private void loadImage(String fname)
	{
		try {
			img = ImageIO.read(new File(fname));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		WritableRaster wr = img.getRaster();
		
		int[] pixelValue = new int[3];
		
		for (int i = 0; i < img.getWidth(); i++)
		{
			for (int j = 0; j < img.getHeight(); j++)
			{
				wr.getPixel(i, j, pixelValue);
				int v = (pixelValue[0]+pixelValue[1]+pixelValue[2])/3;
				
				if (v > 127)
				{
					v = 255;
				}
				else
				{
					v = 0;
				}
				
				pixelValue[0] = v;
				pixelValue[1] = v;
				pixelValue[2] = v;
				wr.setPixel(i, j, pixelValue);
			}
		}

	}
	
	public ImageFrame ()
	{
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		loadImage("dog.jpg");
		width = img.getWidth();
		height = img.getHeight();
		
		imgPanel = new MyImgPanel();
		imgPanel.setSize(width, height);
		
		this.add(imgPanel);
		this.setSize(width+10, height+10);
		this.setVisible(true);
		
	}
	
	public static void main(String argv[])
	{
		new ImageFrame();
	}

}


반응형
LIST

Event 처리 프로그래밍을 쉽게 도와주는 Adapter 클래스에 대해서 설명합니다.



반응형
LIST

Button 컴포넌트에서 발생하는 이벤트 처리에 대해서 설명합니다.



반응형
LIST

Event 처리에 사용되는 listener interface에 대해서 설명합니다.



반응형
LIST

Event 클래스에 대해서 설명합니다.



반응형
LIST

Event based 프로그래밍을 할 때의 유의점에 대해서 설명합니다.



반응형
LIST

Event based programming에서 사용되는 용어에 대해서 설명합니다.



반응형
LIST

Event based programming에 대해 설명합니다.



반응형
LIST

+ Recent posts