JAVA 프로그래밍

문제

네트워크를 바탕으로 리모컨으로 제어되는 TV 프로그램입니다 이를 해결하는 프로그램의 다음 실행상태에 대해 빈칸을 채우세요 

프로그램의 실행순서 및 실행상태

  
①  
 
  
②  
 
1  public static void main( String[] args ) {  

3                               new TVPanel( imagePath ); 

T1b  public TVPanel( final String imgPath ) {

T1e  }
③  
 
2   RemoteControl appliance =  

  
④  
 
5                                new RemoteControlNetwork( appliance, serverIP );

RN2b  public RemoteControlNetwork( RemoteControl appliance, String serverIP ) {

RN21   super( appliance );

R3b  public RemoteControllerPanel( RemoteControl appliance ) {

R3e  }

RN22   connectAsClient( serverIP, appliance.getClass().getSimpleName() );

RN3b  public void connectAsClient( String serverIP, String applianceName ) {

RN32             new Network();

N1b  public Network() { 

N1e  }

RN31   network = 

RN33   network.connectAsClient( serverIP, this );

N3b  public void connectAsClient( String serverIP, Runnable obj ) {

N32             new Socket( serverIP, serverPort ); 

E001 // [클라이언트]에서 접속 요청하면 [서버]에서 네트워크 연결 초기화 
⑤  
 
N31    socket = 

N33    connectInOut( obj ); 

N4b  public void connectInOut( Runnable obj ) {

N41    waitForCounterpart.start();

RN5b  public void run(){ 

RN52                                             network.read() ) 

N5b  public String read() {

N52            in.readLine();

E002 // 네트워크에 상대편 데이터가 도착할 때까지 계속 대기 
                                              
... 

E003 // (수신전용스레드와 별개로) 메인 스레드 N41 이후 실행중 

N4e  }

N3e  }

RN3e  }

RN2e  }

4   RemoteControlNetwork panel = 

6  }

E004 // 이벤트가 발생할 때까지 계속 대기
                                              
... 

E005 // 서버에서 보낸 데이터([RMTC] [리모컨] POWER) 도착
⑥  
 
  
⑦  
 
N51     return 

N5e  }

RN51   for ( String message = null; ( message =

RN53     appliance.clickPower();

T2b  public void clickPower() {

T2e  } 
⑧  
 
RN58   }  

RN52                                             network.read() ) 

N5b  public String read() {

N52            in.readLine();

E002 // 네트워크에 상대편 데이터가 도착할 때까지 계속 대기 
                                              
... 

E006 // 서버에서 보낸 데이터([RMTC] [리모컨] RIGHT) 도착
⑨  
 
N51     return 

N5e  }

RN51   for ( String message = null; ( message =

RN57     appliance.clickRight();

T6b  public void clickRight() {

T6e  }
⑩  
 
RN58   }  

RN52                                             network.read() ) 

N5b  public String read() {

N52            in.readLine();

E002 // 네트워크에 상대편 데이터가 도착할 때까지 계속 대기 
                                              
... 

E007 // 프로그램 종료버튼(우측상단 X) 클릭 
⑪  
 
  
⑫  
 
Wb    public void windowClosing( WindowEvent event ) { 

W1     panel.close();

RN6b  public void close() {

RN61   network.close();

N7b  public void close() {

N7e  }

RN6e  }

We    }

E008 // 메인스레드와 수신전용스레드가 모두 종료하여 프로그램 종료 
⑬  
 

프로그램 코드

E001	// [클라이언트]에서 접속 요청하면 [서버]에서 네트워크 연결 초기화 
E002	// 네트워크에 상대편 데이터가 도착할 때까지 계속 대기	
E003	// (수신전용스레드와 별개로) 메인 스레드 N41 이후 실행중 
E004	// 이벤트가 발생할 때까지 계속 대기
E005	// 서버에서 보낸 데이터([RMTC] [리모컨] POWER) 도착
E006	// 서버에서 보낸 데이터([RMTC] [리모컨] RIGHT) 도착
E007	// 프로그램 종료버튼(우측상단 X) 클릭 
E008	// 메인스레드와 수신전용스레드가 모두 종료하여 프로그램 종료 
		
	import javax.swing.*;
	import java.awt.event.*;
	import remoteControl.*;
	
	public class RemoteControlTV
	{
1		public static void main( String[] args ) { 	
			final String imagePath = "C:\\Users\\user\\Downloads\\JAVA-main\\src\\remoteControl\\image\\";
			String serverIP = "localhost";
2			RemoteControl appliance =  
3			                            new TVPanel( imagePath ); 
4			RemoteControlNetwork panel = 
5			                             new RemoteControlNetwork( appliance, serverIP );
			
			JFrame frame = new JFrame( "TV(클라이언트)" );
			frame.getContentPane().add( (JPanel)appliance );
			frame.addWindowListener( new WindowAdapter() {
Wb				public void windowClosing( WindowEvent event ) { 
W1					panel.close();
We				}
			} );
			frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
			frame.pack();
			frame.setVisible( true );
6		}
	}
	package remoteControl;
	import java.awt.event.ActionEvent;
	import network.Network;
	
	public class RemoteControlNetwork extends RemoteControllerPanel implements Runnable 
	{	
		private Network network;
		private String  id;
		private final String header = "[RMTC] ";
	
RN1b		public RemoteControlNetwork( String imgPath, String serverIP ) {
RN11			super( imgPath );
RN12			connectAsClient( serverIP, this.getClass().getSimpleName() );
RN1e		}
	
RN2b		public RemoteControlNetwork( RemoteControl appliance, String serverIP ) {
RN21			super( appliance );
RN22			connectAsClient( serverIP, appliance.getClass().getSimpleName() );
RN2e		}
	
RN3b		public void connectAsClient( String serverIP, String applianceName ) {
			id = "[" + applianceName +"]";
RN31			network = 
RN32			          new Network();
RN33			network.connectAsClient( serverIP, this );
RN3e		}
	
		@Override
RN4b		public void actionPerformed( ActionEvent event ) {
			String message = "";			                 
			if ( event.getSource() == button[POWER] )  
				message = header + "POWER";
			else if ( event.getSource() == button[UP] ) 
				message = header + "UP";
			else if ( event.getSource() == button[DOWN] ) 
				message = header + "DOWN";
			else if ( event.getSource() == button[LEFT] ) 
				message = header + "LEFT";
			else if ( event.getSource() == button[RIGHT] ) 
				message = header + "RIGHT";
	
RN41			network.write( message );
RN4e		}
	
		@Override
RN5b		public void run(){	
RN51			for ( String message = null; ( message =
RN52			                                          network.read() ) 
			                                                               != null; ) {
				if ( !message.contains( header ) )
					continue;
				else if ( message.contains( "POWER" ) && ( appliance != null ) )
RN53					appliance.clickPower();
				else if ( message.contains( "UP" ) && ( appliance != null ) )		
RN54					appliance.clickUp();
				else if ( message.contains( "DOWN" ) && ( appliance != null ) )
RN55					appliance.clickDown();
				else if ( message.contains( "LEFT" ) && ( appliance != null ) )
RN56					appliance.clickLeft();
				else if ( message.contains( "RIGHT" ) && ( appliance != null ) )
RN57					appliance.clickRight();
RN58			}  
RN5e		}
		
RN6b		public void close() {
			network.write( header + id + " 네트워크 연결 종료" );
RN61			network.close();
RN6e		}
	}

	package network;
	import java.io.*;
	import java.net.*;
	
	public class Network 
	{
		public static final int serverPort = 7700;
		protected ServerSocket serverSocket; 
		protected Socket socket; 
		private BufferedReader in;
		private PrintWriter out; 
		private Thread waitForCounterpart; 
	
N1b		public Network() {	
			serverSocket = null;
			socket = null;
			in = null;
			out = null;
			waitForCounterpart = null;
N1e		}
		
N2b		public void connectAsServer( Runnable obj ) {
			try { 
				serverSocket = new ServerSocket( serverPort ); 
N21				socket = 
N22				         serverSocket.accept();   
N23				connectInOut( obj );  
			} catch ( Exception e ) {
				e.printStackTrace();
			}
N2e		} 
		
N3b		public void connectAsClient( String serverIP, Runnable obj ) {
			try {
N31				socket = 
N32				         new Socket( serverIP, serverPort ); 
N33				connectInOut( obj );	
			} catch ( Exception e ) {
				e.printStackTrace();
			}
N3e		}
	
N4b		public void connectInOut( Runnable obj ) {
			try {
				in = new BufferedReader( new InputStreamReader( socket.getInputStream() ));
				out = new PrintWriter( socket.getOutputStream(), true );
				waitForCounterpart = new Thread( obj );
N41				waitForCounterpart.start();
			} catch ( Exception e ) {
				e.printStackTrace();
			}
N4e		}
		
N5b		public String read() {
			try {
				if ( this.isConnecting() == true )
N51					return 
N52					       in.readLine();
			} catch ( Exception e ) {
				e.printStackTrace();
			}
			
			return null;
N5e		}
		
N6b		public void write( String data ) {
			try {
				if ( this.isConnecting() == true )
N61					out.println( data );
			} catch ( Exception e ) {
				e.printStackTrace();
			}	
N6e		}
	
		public boolean isConnecting() {
			if ( ( socket != null ) 
					&& ( in != null ) 
					&& ( out != null ) 
					&& ( waitForCounterpart != null ) 
					&& ( waitForCounterpart.getState() != Thread.State.TERMINATED ) )   
				return true;
			else 
				return false;
		}
		
N7b		public void close() {
			try {
				if ( waitForCounterpart != null ) {
					waitForCounterpart.interrupt();	  
					waitForCounterpart = null;
				}
				if ( in != null ) {
					in.close();
					in=null;
				}			
				if ( out != null ) {
					out.flush();
					out.close();
					out = null;
				}
				if ( socket != null ) {
					socket.close();
					socket = null;
				}
				if ( serverSocket != null ) {
					serverSocket.close();
					serverSocket = null;
				}
			} catch ( Exception e ) {
				e.printStackTrace();
			}
N7e		}
	}

	package remoteControl;
	import javax.swing.*;
	import java.awt.*;
	import java.awt.event.*;
	
	public class RemoteControllerPanel extends JPanel implements ActionListener 
	{
		protected JButton[] button;	
		public final static int POWER = 0, UP = 1, DOWN = 2, LEFT = 3, RIGHT = 4;
		protected RemoteControl appliance;
	
R1b		public RemoteControllerPanel( String imgPath ) {
			this.appliance = null;
	
			final String[] strButton = { "power.gif", "up.gif", "down.gif", "left.gif", "right.gif" };
			button = new JButton[strButton.length];
			for ( int i = 0; i < strButton.length; i++ ) {
				button[i] = new JButton( new ImageIcon( new ImageIcon( imgPath + strButton[i] ).getImage().getScaledInstance( 30, 30, Image.SCALE_SMOOTH ) ) );
				button[i].addActionListener( this ); 
			}
	
			this.setPreferredSize( new Dimension( 240, 120 ) );		
			this.setLayout( new BorderLayout() );
			this.add( button[POWER], BorderLayout.CENTER );
			this.add( button[UP   ], BorderLayout.NORTH );
			this.add( button[DOWN ], BorderLayout.SOUTH );
			this.add( button[LEFT ], BorderLayout.WEST );
			this.add( button[RIGHT], BorderLayout.EAST );   
R1e		}
	
R2b		public RemoteControllerPanel( String imgPath, RemoteControl appliance ) {
			this( imgPath );		
			this.appliance = appliance;
R2e		}
	
R3b		public RemoteControllerPanel( RemoteControl appliance ) {
			this.appliance = appliance;
R3e		}
	
		@Override
R4b		public void actionPerformed( ActionEvent event ) {
			if ( ( event.getSource() == button[POWER] ) && ( appliance != null ) )
				appliance.clickPower();
			else if ( ( event.getSource() == button[UP] ) && ( appliance != null ) )
				appliance.clickUp();
			else if ( ( event.getSource() == button[DOWN] ) && ( appliance != null ) )
				appliance.clickDown();
			else if ( ( event.getSource() == button[LEFT] ) && ( appliance != null ) )
				appliance.clickLeft();
			else if ( ( event.getSource() == button[RIGHT] ) && ( appliance != null ) )
				appliance.clickRight();
R4e		}	
	}
	package remoteControl;
	import java.awt.*;
	import javax.swing.*;
	
	public class TVPanel extends JPanel implements RemoteControl 
	{
		private boolean power;
		private int channel, volume;
		private ImageIcon[] imgChannel, imgVolume;
		private JLabel lblChannel, lblVolume;
		
T1b		public TVPanel( final String imgPath ) {
			final String[] channelFile = { "EBS.gif", "SBS.gif", "KBS.gif", "MBC.gif", "blank.gif" };	
			imgChannel = new ImageIcon[channelFile.length];
			for ( int i = 0; i < channelFile.length; i++ ) {
				imgChannel[i] = new ImageIcon( new ImageIcon( imgPath + channelFile[i] ).getImage().getScaledInstance( 250, 120, Image.SCALE_SMOOTH ) );
			}
			
			final String[] volumeFile = { "volume0.gif", "volume1.gif", "volume2.gif", "volume3.gif" };	
			imgVolume = new ImageIcon[volumeFile.length];
			for ( int i = 0; i < volumeFile.length; i++ ) {
				imgVolume[i] = new ImageIcon( new ImageIcon( imgPath + volumeFile[i] ).getImage().getScaledInstance( 80, 120, Image.SCALE_SMOOTH ) );
			}
			power = OFF;
			channel = imgChannel.length - 1;
			volume = 0;			
			lblChannel = new JLabel( imgChannel[channel] );
			lblVolume =  new JLabel( imgVolume[volume] );
			add( lblChannel );
			add( lblVolume );
T1e		}
		
		@Override
T2b		public void clickPower() {
			if( power == OFF ) {
				power = ON;
				channel = 0;
				volume = 1;
				lblChannel.setIcon( imgChannel[channel] );
				lblVolume.setIcon( imgVolume[volume] );
			}
			else {
				power = OFF;
				channel = imgChannel.length - 1;
				volume = 0;
				lblChannel.setIcon( imgChannel[channel] );
				lblVolume.setIcon( imgVolume[volume] );
			}
T2e		}	
		
		@Override
		public void clickUp() {				
			if( power == ON ) {
				channel = ( channel + 1 ) % ( imgChannel.length - 1 );
				lblChannel.setIcon( imgChannel[channel] );
			}
		}				
		
		@Override
		public void clickDown() {			
			if( power == ON ) {
				channel = ( channel + ( imgChannel.length - 2 ) ) % ( imgChannel.length - 1 );
				lblChannel.setIcon( imgChannel[channel] );
			}
		}				
		
		@Override
		public void clickLeft() {				
			if( power == ON ) {
				volume = ( volume + ( imgVolume.length - 1 ) ) % imgVolume.length;
				lblVolume.setIcon( imgVolume[volume] );
			}
		}				
		
		@Override
T6b		public void clickRight() {
			if( power == ON ) {
				volume = ( volume + 1 ) % imgVolume.length;
				lblVolume.setIcon( imgVolume[volume] );
			}
T6e		}
	}
	package remoteControl;
	
	public interface RemoteControl
	{
		boolean ON = true, OFF = false;
		void clickPower();
		void clickUp();
		void clickDown();
		void clickLeft();
		void clickRight();
	}