430 likes | 599 Views
Swing Application Program. Event. 사용자가 의도한 어떤 변화가 응용프로그램상에 발생하는 것 예 ) ‘ 윈도우가 열렸다 ’ , ‘ 버튼이 클릭되었다 ’ , ‘ 리스트 상자 안에 아이템이 선택되었다 ’ 이벤트가 감지되면 그 이벤트에 반은하는 형태로 미리 정의한 이벤트처리 메소드를 호출 예 ) ‘ 버튼이 클릭되면 OO 를 실행한다 ’. 이벤트의 구조. 이벤트 소스 이벤트의 발생원이 되는 컴포넌트 예 ) 버튼 , 라벨 , 체크상자 등 이벤트
E N D
Event • 사용자가 의도한 어떤 변화가 응용프로그램상에 발생하는 것 • 예) ‘윈도우가 열렸다’, ‘버튼이 클릭되었다’, ‘리스트 상자 안에 아이템이 선택되었다’ • 이벤트가 감지되면 그 이벤트에 반은하는 형태로 미리 정의한 이벤트처리 메소드를 호출 • 예) ‘버튼이 클릭되면 OO를 실행한다’
이벤트의 구조 • 이벤트 소스 • 이벤트의 발생원이 되는 컴포넌트 • 예) 버튼, 라벨, 체크상자 등 • 이벤트 • 각 이벤트에는 고유한 이름이 정해져 있음 • 예) ActionEvent: 버튼, 체크상자를 클릭시 ItemEvent: 콤보상자, 메뉴 등에서 아이템 선택시 • 이벤트 리스너 • 이벤트 소스로부터의 호출에 의해 이벤트 처리를 대행 • 자기 자신 내부에 미리 정의된 처리를 실행 • 예) ActionListener: 버튼, 체크상자의 클릭이벤트에 반응 • 이벤트처리메소드 • 이벤트가 발생했을 때 실제로 처리하는 내용을 정의함
이벤트 리스너, 처리메소드 • 형식 컴포넌트이름.add이벤트리스너이름(new 이벤트리스너이름() { public void 메소드이름(이벤트이름 ae) { 실제 처리 내용 } }) 예) //btnC가 클릭되었을 때의 이벤트를 정의 btnC.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { myLabel.setText("btnC가 클릭되었습니다"); } });
컴포넌트와 이벤트 • 이벤트 및 리스너의 정보: C:\jdk1.3\docs\api\java\util\class\EventObject.html
Border layout • 영역을 동서남북 및 중앙으로 나눔 • 형식) 컨테이너이름.setLayout(new BorderLayout()); //컴포넌트를 해당 위치에 추가 컨테이너이름.add(컴포넌트이름, BorderLayout.NORTH); • 예) //프레임을 작성하여 레이아웃 설정 JFrame myFrame = new JFrame(“Border Layout"); myFrame.getContentPane().setLayout(new BorderLayout()); //버튼의 인스턴스 btnA를 작성 JButton btnA = new JButton("btnA"); . . . . . . //프레임에 버튼을 추가(BoarderLayout의 북쪽) myFrame.getContentPane().add(btnA, BorderLayout.NORTH); . . . . . .
Grid layout • 영역을 격자모양으로 나눔 • 형식) 컨테이너이름.setLayout(new GridLayout(행수, 열수)); //컴포넌트를 해당 위치에 추가 컨테이너이름.add(컴포넌트이름); • 예) int intCounter; //프레임을 작성하여 레이아웃 설정 JFrame myFrame = new JFrame(“Grid Layout"); myFrame.getContentPane().setLayout(new GridLayout(3, 3)); //프레임에 버튼을 추가 for (intCounter = 0; intCounter<=8; intCounter++) myFrame.getContentPane().add( new JButtons(Integer).toString(intCounter)));
JPanel • JFrame과 같이 버튼이나 라벨등의 컴포넌트를 만들기 위한 컨테이너 • 관련된 컴포넌트를 패널 상에 만들어놓고 패널채로 상위의 프레임등에 추가 • 형식) • 패널이름.add(추가하는 컴포넌트 이름) • 예) myPanel.add(btnA); myPanel.add(btnB); myPanel.add(btnC);
다음 코드를 입력하고 수행하라(1) import javax.swing.*; import java.awt.*; import java.awt.event.*; public class SampleD8L1 { public static void main(String[] args) { //프레임을 작성하여 레이아웃 설정 JFrame myFrame = new JFrame("Click Me Buttons !"); myFrame.getContentPane().setLayout(new BorderLayout()); //패널을 작성하여 레이아웃 설정 JPanel myPanel = new JPanel(); //Grid Layout myPanel.setLayout(new GridLayout(1, 3)); //표시용 라벨 설정 final JLabel myLabel = new JLabel("버튼을 클릭해 주십시오", JLabel.CENTER);
다음 코드를 입력하고 수행하라(2) //btnA를 작성 JButton btnA = new JButton("btnA"); //btnA가 클릭되었을 때의 이벤트를 정의 btnA.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { myLabel.setText("btnA가 클릭되었습니다"); } }); //btnB를 작성 JButton btnB = new JButton("btnB"); //btnB가 클릭되었을 때의 이벤트를 정의 btnB.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { myLabel.setText("btnB가 클릭되었습니다"); } }); //btnC를 작성 JButton btnC = new JButton("btnC"); //btnC가 클릭되었을 때의 이벤트를 정의 btnC.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { myLabel.setText("btnC가 클릭되었습니다"); } });
다음 코드를 입력하고 수행하라(3) //패널에 버튼을 추가 myPanel.add(btnA); myPanel.add(btnB); myPanel.add(btnC); //프레임에 패널을 추가(BoarderLayout의 북쪽) myFrame.getContentPane().add(myPanel, BorderLayout.NORTH); //프레임에 패널을 추가(BoarderLayout의 남은 지역) myFrame.getContentPane().add(myLabel, BorderLayout.CENTER); //프레임(윈도우)이 닫힐 때의 처리를 정의 myFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });
다음 코드를 입력하고 수행하라(4) //Look & Feel의 설정 try { //Windows 스타일의 Look&Feel로 정의 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); //설정을 반영시킨다 SwingUtilities.updateComponentTreeUI(myFrame); //에러 처리 블록 } catch (Exception e) { } //프레임의 크기를 설정하여 표시 myFrame.setSize(250, 100); myFrame.setVisible(true); } }
연습 • 다섯 개의 버튼을 만든다 • 각 버튼의 이름을 btn1 ~ btn5로 하고 각각이 클릭되면 하단의 라벨에 버튼이름이 표시되게 하라
정보은폐(information hiding)/ 캡슐화(encapsulation) • “정보은폐는 시스템을 구성하는 모듈 사이의 의존성을 줄여, 각 모듈을 따로 개발하고, 테스트하고, …의존성을 줄이면 각 모듈을 이해하기도 쉽고 다른 모듈에 영향을 주지 않고 쉽게 수정할 수 있기 때문에 유지보수하기도 훨씬 쉬워진다…전체 시스템이 성공했다는 것을 증명하지 못한 상황이라도 개별 모듈의 성공은 증명할 수 있기 때문이다.”: 교 p91~92 클래스나 클래스 멤버에 대한 접근은 최소화
JRadioButton • 선택/선택해제의 두 가지 상태 표현 • 라디오 버튼 그룹으로 여러 개 중에 하나만 선택할 때 사용 • 형식 • new JRadioButton(“캡션”, 상태) • 캡션: 라디오 버튼 옆에 표시되는 문자열 • 상태 • True –선택된 상태로 표시 • False –선택되지 않은 상태로 표시 • 예) JRadioButton rdoWindows = new JRadioButton ("Windows Style") ; JRadioButton rdoJava = new JRadioButton("Java Style", true) ;
ButtonGroup • 여러 개의 항목 중 하나만을 선택하기 위한 그루핑 • 내부적으로 컴포넌트를 정리하는 일을 하며 • 실제로 폼상에 보여지기 위해서는 패널객체등에 추가하여야 함 • 그룹을 만드는 방법 • 버튼그룹의 인스턴스를 생성 • add 메소드로 그룹에 추가 • 예) ButtonGroup myGroup = new ButtonGroup() ; myGroup.add(rdoWindows) ; myGroup.add(rdoJava) ; myGroup.add(rdoMotif) ; // 패널 객체에 추가 myPanel.add(rdoWindows) ; myPanel.add(rdoJava) ; myPanel.add(rdoMotif) ;
라디오 버튼의 이벤트 처리 • 각 라디오버튼객체의 addActionListner메소드로 액션리스너를 등록하고 그 내부의 메소드에서 처리 • 예) window스타일, 자바스타일, Motif스타일을 선택할 수 있는 라디오버튼을 만들어 놓았을 때 window스타일의 이벤트처리 //Windows 라디오 버튼을 작성하여 클릭 이벤트를 정의 JRadioButton rdoWindows = new JRadioButton ("Windows Style") ; rdoWindows.addActionListener (new ActionListener () { public void actionPerformed(ActionEvent ae) { try { UIManager.setLookAndFeel ("com.sun.java.swing.plaf.windows.WindowsLookAndFeel") ; SwingUtilities.updateComponentTreeUI(myFrame) ; //에러 처리 블록 } catch (Exception e) { } } }) ;
setBorder메소드, BorderFactory클래스 • setBorder메소드 • Border line을 그리고 싶은 객체에 사용 • 형식) • 보더라인을_그릴_객체이름.setBorder(보더객체) • 보더 • 그리고 싶은 보더라인의 종류를 지정 • 예) myPanel.setBorder(BorderFactory.createLineBorder(Color.black)) ; 클래스 메소드 클래스 필드
Color 클래스의 필드의 종류 • black, blue, cyan, darkGray, gray, green, lightGray, magenta, orange, pink, red, white, yellow
다음 코드를 입력하고 수행하라(1) import javax.swing.* ; import java.awt.* ; import java.awt.event.*; public class SampleD8L2 { public static void main(String[] args) { //프레임을 작성하여 레이아웃을 설정 final JFrame myFrame = new JFrame ( "Look & Feel Changer") ; myFrame.getContentPane().setLayout(new GridLayout(3, 1)) ; //샘플 버튼 작성 final JButton myBtn = new JButton("버튼입니다") ; final JLabel myLbl = new JLabel("라벨입니다“, JLabel.CENTER) ; //Windows 라디오 버튼을 작성하여 클릭 이벤트를 정의 JRadioButton rdoWindows = new JRadioButton ("Windows Style") ; rdoWindows.addActionListener (new ActionListener () { public void actionPerformed(ActionEvent ae) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel") ; SwingUtilities.updateComponentTreeUI(myFrame) ; //에러 처리 블록 } catch (Exception e) { } } }) ;
다음 코드를 입력하고 수행하라(2) //Java 라디오 버튼을 작성하여 클릭 이벤트를 정의 JRadioButton rdoJava = new JRadioButton("Java Style", true) ; rdoJava.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { try { UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel") ; SwingUtilities.updateComponentTreeUI (myFrame) ; } catch (Exception e) { } } }) ; //Motif 라디오 버튼을 작성하여 클릭 이벤트를 정의 JRadioButton rdoMotif = new JRadioButton("Motif Style") ; rdoMotif.addActionListener (new ActionListener() { public void actionPerformed(ActionEvent ae) { try { UIManager.setLookAndFeel ( "com.sun.java.swing.plaf.motif.MotifLookAndFeel") ; SwingUtilities.updateComponentTreeUI (myFrame) ; } catch (Exception e) { } } }) ;
다음 코드를 입력하고 수행하라(3) //프레임(윈도우)이 닫힐 때의 처리를 정의 myFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit (0) ; } }) ; //프레임 크기를 설정하여 표시 myFrame.setSize(350, 150) ; myFrame.setVisible(true) ; } } //라디오 버튼을 버튼 그룹에 추가 ButtonGroup myGroup = new ButtonGroup() ; myGroup.add(rdoWindows) ; myGroup.add(rdoJava) ; myGroup.add(rdoMotif) ; //패널 작성 JPanel myPanel = new JPanel() ; //패널에 보더 라인을 긋는다 myPanel.setBorder( BorderFactory.createLineBorder(Color.black)) ; //패널에 레이아웃을 설정 myPanel.setLayout(new FlowLayout()) ; //프레임에 패널을 설정 myPanel.add(rdoWindows) ; myPanel.add(rdoJava) ; myPanel.add(rdoMotif) ; //프레임에 패널을 추가 myFrame.getContentPane().add(myPanel) ; //프레임에 버튼을 추가 myFrame.getContentPane().add(myBtn) ; //프레임에 라벨을 추가 myFrame.getContentPane().add(myLbl) ;
연습문제 • 각 라디오버튼이 클릭되었을 때 Look&Feel의 변환과 동시에 라벨에 스타일이름 Windows, Java, Motif를 표시하라. • 힌트: JLabel클래스의 setText메소드
연습문제 • BorderFactory클래스의 createEmptyBorder메소드를 사용하여 패널 주변에 상하좌우 5 픽셀의 여백을 설정하라. • public static BordercreateEmptyBorder(inttop, intleft, intbottom, intright) • Creates an empty border that takes up space but which does no drawing, specifying the width of the top, left, bottom, and right sides. • Parameters: • top - an integer specifying the width of the top, in pixels • left - an integer specifying the width of the left side, in pixels • bottom - an integer specifying the width of the right side, in pixels • right - an integer specifying the width of the bottom, in pixels
상속을 이용한 클래스 작성 • 형식) class 클래스이름 extends 상속원본클래스이름 { } • 예) JFrame클래스 인스턴스를 생성하여 이용하는 대신 상속을 이용 • public class SampelD8L3 extends JFrame {
super • 상속의 원본이 되는 클래스를 나타내는 식별자 • 예) super(title); //수퍼클래스의 생성자를 호출
this • 자기자신의 인스턴스를 나타내는 키워드 • 같은 클래스 안에 정의된 필드나 메소드를 불러낼 때는 메소드나 필드이름 앞에서 생략 가능 • 예) this.setSize(350, 100) = setSize(350, 100)
Click counter(1) import javax.swing.* ; import java.awt.* ; import java.awt.event.*; //JFrame 클래스를 확장하여 SampleD8L3 클래스를 작성 public class SampleD8L3 extends JFrame { //카운터 저장용 변수 int intCount = 0 ; //SampleD8L3 클래스의 생성자를 정의 public SampleD8L3(String title) { //부모 클래스(JFrame)의 생성자를불러낸다 super(title) ; //카운트 증가 버튼을 작성 JButton myBtn =new JButton("카운트 증가") ; //클리어 버튼을 작성 JButton myClrBtn =new JButton("클리어") ; //수치 표시용 라벨을 작성 final JLabel myLabel = new JLabel(intCount +"회 클릭되었습니다" ,JLabel.CENTER) ; //버튼이 클릭되었을 때의 이벤트를 정의 myBtn.addActionListener (new ActionListener() { public void actionPerformed(ActionEvent ae) { intCount = intCount + 1; myLabel.setText(intCount + " 회 클릭되었습니다") ; } });
Click counter(2) //버튼이 clear되었을 때의 이벤트를 정의 myClrBtn.addActionListener (new ActionListener() { public void actionPerformed(ActionEvent ae) { intCount = 0; myLabel.setText(intCount + " 회 클릭되었습니다") ; } }); //패널을 작성하여 버튼을 만든다 JPanel myPanel = new JPanel() ; myPanel.setLayout(new GridLayout(1, 2)) ; myPanel.add(myBtn) ; myPanel.add(myClrBtn) ; //Panel과 Label을 프레임에 만든다 this.getContentPane().add(myPanel, BorderLayout.NORTH) ; this.getContentPane().add(myLabel, BorderLayout.CENTER) ; //프레임(윈도우)이 닫힐 때의 처리를 정의 this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0) ; } }) ;
Click counter(3) //Look & Feel 설정 try { //Motif 스타일의 Look & Feel로 설정 UIManager.setLookAndFeel ( "com.sun.java.swing.plaf.motif.MotifLookAndFeel") ; //설정을 반영시킨다 SwingUtilities.updateComponentTreeUI(this) ; //에러 처리 블록 } catch (Exception e) { } //프레임의 크기를 정의하여 표시 this.setSize(350, 100) ; this.setVisible(true) ; } //main 메소드의 정의 public static void main(String args[]) { //SampleD8L3 클래스의 새로운 인스턴스 생성 SampleD8L3 myApp = new SampleD8L3("Click Counter") ; } }
불변 클래스(immutable class) • 인스턴스를 생성후 그 내용을 바꿀 수 없는 클래스-각 값에 대해 각각의 객체 • 장점: 간단하여 오류를 야기할 가능성 낮음 • 만드는 규칙 • 객체를 변경하는 메소드 불제공 • 재정의 가능 메소드 불제공 • 고의/실수로 클래스 불변성의 해침을 막기 위해 • 모든 필드를 final로 • 모든 필드를 private로 • 클라이언트가 직접 필드 수정 못하게 • 가변 객체를 참조하는 필드는 배타적 접근 • 클라이언트가 이 객체에 대한 참조를 얻을 수 없게 • 예) 교 p 97
대화상자(1) • 지정한 메시지를 표시 • JDialog 및 JOptionPane클래스 사용 • JDialog클래스 • 부모 윈도우 상에 나타나는 기본형태의윈도우 생성 • JOptionPane클래스 • 아이콘, 버튼 메시지 등을 지정하여 보다 정교한 대화상자 디자인
대화상자(2) • 방법 • JOptionPane클래스의 인스턴스 생성 형식) JOptionPane(“메지지 문자열”, 메시지타입) 예) JOptionPane myOptPane = new JOptionPane(myText.getText(), JOptionPane.INFORMATION_MESSAGE); • 메시지문자열=텍스트 필드에 입력된 문자열 • 메시지타입=‘i’마크가 붙은 대화상자 • JOptionPane클래스의 createDialog메소드를 불러내어 대화상자의 인스턴스를 생성하여 JDialog클래스의 인스턴스로 함 예) JDialog myDialog =myOptPane.createDialog(myContainer, "Dialog Generated !");
Container클래스 • GUI 컴포넌트를 만드는 컨테이너를 나타내는 클래스 • 일반적으로 swing 응용프로그램은 컨테이너를 먼저 작성한 후 필요한 컴포넌트를 끼워넣음 • JFrame클래스는 컨테이너의 역할은 못하므로 프레임에 컴포넌트를 추가할 때마다 getContentPane()메소드를 사용하여 추가 • 컨테이너를 사용할 경우 한 번 contentPane을 획득하면 계속 같은 인스턴스를 지정하게 되므로 컴포넌트를 추가할 때마다 매번 getContentPane()메소드를 사용할 필요 없음 • 예) //프레임에 버튼을 추가 myFrame.getContentPane().add(myBtn) ; //프레임에 라벨을 추가 myFrame.getContentPane().add(myLbl) ; • myContainer = this.getContentPane(); myContainer.add(myBtn); myContainer.add(myLbl);
대화상자(1) import javax.swing.* ; import java.awt.* ; import java.awt.event.*; //JFrame 클래스를 확장하여 SampleD8L4 클래스를 작성 public class SampleD8L4 extends JFrame { //컨테이너 객체 변수를 선언하고, null을 대입 Container myContainer = null; //SampleD8L4 클래스의 생성자를 정의 public SampleD8L4(String title) { //부모 클래스(JFrame)의 생성자를 불러낸다 super(title); //프레임의 컨텐츠페인을 이용하여 컨테이너 객체를 생성 myContainer = this.getContentPane(); //지시 메시지 표시용 라벨을 작성 JLabel myLabel = new JLabel("메시지를 지정하여 [작성] 버튼을 클릭", JLabel.CENTER); //입력용 텍스트 필드 작성 final JTextField myText = new JTextField("여기에 메시지 입력", 20);
대화상자(2) //버튼 작성 JButton myBtn = new JButton("작성 !"); //버튼이 클릭되었을 때의 이벤트를 정의 myBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { //옵션페인 작성 JOptionPane myOptPane= new JOptionPane(myText.getText(), JOptionPane.INFORMATION_MESSAGE); //createDialog 메소드로 대화를 작성하고, 대화상자 객체에 설정 JDialog myDialog = myOptPane.createDialog(myContainer, "Dialog Generated !"); //대화상자를 가시상태로 myDialog.setVisible(true); } }); //Panel 작성(FlowLayout) JPanel myPanel = new JPanel(); myPanel.setLayout(new FlowLayout());
대화상자(3) //텍스트 필드와 버튼을 만든다 myPanel.add(myText); myPanel.add(myBtn); //컨테이너 객체의 레이아웃을 설정(2X1 GridLayout) myContainer.setLayout(new GridLayout(2, 1)); //Label과 Panel를 설정 myContainer.add(myLabel); myContainer.add(myPanel); //프레임(윈도우)이 닫힐 때의 처리를 정의 this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); //Look & Feel 설정 try { //Windows 스타일의 Look & Feel로 설정 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); //설정을 반영시킨다 SwingUtilities.updateComponentTreeUI(this);
대화상자(4) //에러 처리 블록 } catch (Exception e) { } //프레임의 크기를 정의하여 표시 this.setSize(350, 120); this.setVisible(true); } //main 메소드의 정의 public static void main(String s[]) { //SampleD8L4 클래스의 신규 인스턴스 생성 SampleD8L4 myApp = new SampleD8L4("Dialog Generator"); } }
연습문제 • 그리드 레이아웃 형식으로 버튼을 4개 만들고 각 버튼의 이름은 Button1 ~ Button4로 하라. 이 때 해당 버튼을 클릭하면 하단의 라벨에 버튼 이름이 표시되도록 하고 프레임의 크기는 (250, 150)으로 하라.
Interface(1) • 다중 상속 • 둘 이상의 상위 클래스로부터 상속받는 것 • 자바는 다중 상속을 지원 않으므로 인터페이스를 이용하여 다중 상속을 흉내 Class A Class B Interface B’: Class B의 메소드를 abstract로 정의 Class AB: B’로부터 상속받는 메소드를 구현
Interface(2) • 형식 interface 인터페이스이름{ 속성변수 선언 메소드 선언 } • 클래스에서 인터페이스에 정의된 메소드 구현 class AB extends A implements B’ interface { 인터페이스 B’에서 정의된 메소드의 구현 } Interface B’ { 클래스 B의 상수와 메소드 선언 }
public class Manage { public static void main(String args[]) { int tsalary; Salary manager = new Salary(); manager.jobid = 2; manager.jobname = "Manager"; manager.salary = 1000000; tsalary = manager.totalsalary(manager.jobid, manager.salary); System.out.println(manager.jobname+" : "+ tsalary); } } 다음 코드를 입력하라 interface CommBonus{ int comm = 30000; public int commbon(); } interface JobBonus { public int jobbon( int jobid, int jobsal); } interface Bonus extends CommBonus,JobBonus { } class Salary implements Bonus{ int jobid, salary; String jobname; public int commbon() { return comm; } public int jobbon(int jobid, int salary) { return (salary/2)/jobid; } public int totalsalary(int jobid, int salary) { return salary + commbon() +jobbon(jobid, salary); } } CommBonus JobBonus Bonus Salary
연습문제 • 그리드 레이아웃 형식으로 버튼을 3개 만들고 각 버튼의 이름은 myBtn1 ~ myBtn3로 하라. 이 때 해당 버튼을 클릭하면 대화상자에 버튼 이름이 표시되도록 하라. 프레임의 크기는 (350, 150)으로 하라.