12 장. GUI 학습목표 GUI 이벤트, 이벤트리스너와이벤트소스그림그리기내부클래스
창 Jframe 의모양 (Metal L&F) Jframe 의모양 (Aqua L&F)
창을만드는방법 1. 프레임 (JFrame) 만들기 JFrame frame = new JFrame(); 2. 위젯만들기 JButton button = new JButton( click me ); 3. 위젯을프레임에추가 frame.getcontentpane().add(button); 4. 화면에표시 frame.setsize(300, 300); frame.setvisible(true);
버튼 import javax.swing.*; public class SimpleGui1 { public static void main(string[] args) { JFrame frame = new JFrame(); JButton button = new JButton( click me ); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.getcontentpane().add(button); frame.setsize(300, 300); frame.setvisible(true);
이벤트 사용자가클릭했을때호출할메소드 public void changeit() { button.settext( I ve been clicked! ); 그메소드를언제실행시켜야할지알아내는방법 코드 Button 객체
리스너인터페이스 이벤트소스 (event source) 사용자의행동을이벤트로바꿔주는객체 java.awt.event 패키지 리스너 (listener) 인터페이스 리스너와이벤트소스를연결해주는다리역할을함 필요한이벤트유형에맞는리스너인터페이스를구현하면그이벤트를받아올수있습니다. ActionListener actionperformed(actionevent ev) ItemListener itemstatechanged(itemevent ev) KeyListener KeyPressed(KeyEvent ev) KeyReleased(KeyEvent ev) KeyTyped(KeyEvent ev)
리스너와소스 button.addactionlistener(this) actionperformed(theevent) Event 객체
ActionEvent를받는방법 1. ActionListener 인터페이스구현 2. 버튼에등록 3. 이벤트처리메소드구현 import javax.swing.*; import java.awt.event.*; public class SimpleGui1B implements ActionListener { JButton button; public static void main(string[] args) { SimpleGui1B = new SimpleGui1B(); gui.go(); public void go() { JFrame frame = new JFrame(); button = new JButton( click me ); button.addactionlistener(this); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.getcontentpane().add(button); frame.setsize(300, 300); frame.setvisible(true); public void actionperformed(actionevent ev) { button.settext( I ve been clicked! );
이벤트소스인지알아내는방법 API 문서를찾아보면됩니다. add 로시작하고 Listener 로끝나는이름을가지고리스너인터페이스인자를받아들이는메소드가있는지찾아보면됩니다. addkeylistener(keylistener k) addactionlistener(actionlistener a)
GUI에요소를추가하는방법 1. 프레임에위젯을집어넣는방법 frame.getcontentpane().add(mybutton); 2. 위젯에 2D 그래픽을그리는방법 graphics.filloval(70, 70, 100, 100); 3. 위젯에그림파일을집어넣는방법 graphics.drawimage(mypic, 10, 10, this);
그림을그리기위한위젯 JPanel 의하위클래스를만들고 paintcomponent() 라는메소드를오버라이드 paintcomponent() 메소드 시스템에서위젯을화면에표시하기위해호출하는메소드 그래픽관련코드는대부분여기에집어넣습니다. JVM 에서화면을갱신할때마다호출됩니다. 사용자가직접호출하는일은절대없습니다. 대신 repaint() 메소드를호출하면화면이갱신되면서이메소드가실행됩니다.
paintcomponent() import java.awt.*; import javax.swing.*; class MyDrawPanel extends JPanel { public void paintcomponent(graphics g) { g.setcolor(color.orange); g.fillrect(20, 50, 100, 100);
paintcomponent() JPEG 파일표시 public void paintcomponent(graphics g) { Image image = new ImageIcon( catzilla.jpg ).getimage(); g.drawimage(image, 3, 4, this); 그리기 public void paintcomponent(graphics g) { g.fillrect(0, 0, this.getwidth(), this.getheight()); int red = (int) (Math.random() * 255); int green = (int) (Math.random() * 255); int blue = (int) (Math.random() * 255); Color randomcolor = new Color(red, green, blue); g.setcolor(randomcolor); g.filloval(70, 70, 100, 100);
Graphics2D public void paintcomponent(graphics g) { g 매개변수는사실 Graphics2D 객체를참조함 Animal a = new Dog(); a.bark(); Dog d = (Dog) a; d.bark(); Graphics2D g2d = (Graphics2D) g;
이벤트를받아서그림을고쳐그리는방법
GUI 레이아웃 한프레임에두개이상의위젯을넣는방법 frame.getcontentpane().add(button); frame.getcontentpane().add(borderlayout.center, button); 북쪽 (NORTH) 서쪽 (WEST) 중앙 (CENTER) 동쪽 (EAST) 남쪽 (SOUTH)
버튼이두개있으면? 북쪽 (NORTH) 서쪽 (WEST) 중앙 (CENTER) 동쪽 (EAST) 남쪽 (SOUTH)
여러개의이벤트를처리하는방법 1. actionperformed() 메소드를두개구현 class MyGui implements ActionListener { public void actionperformed(actionevent ev) { frame.repaint(); public void actionperformed(actionevent ev) { label.setlabel( That hurt! );
여러개의이벤트를처리하는방법 2. 똑같은리스너를두버튼에모두등록 class MyGui implements ActionListener { public void go() { colorbutton = new JButton(); labelbutton = new JButton(); colorbutton.addactionlistener(this); labelbutton.addactionlistener(this); public void actionperformed(actionevnet ev) { if (event.getsource() == colorbutton) { frame.repaint(); else { label.setlabel( That hurt! );
여러개의이벤트를처리하는방법 3. 각버튼마다별도의 ActionListener 클래스제작 class MyGui { JFrame frame; JLabel label; void gui() { class ColorButtonListener implements ActionListener { public void actionperformed(actionevent ev) { frame.repaint(); class LabelButtonListener implements ActionListener { public void actionperformed(actionevent ev) { label.setlabel( That hurt! );
내부클래스 내부클래스 (inner class) 외부클래스에있는것을마음대로사용할수있음 class MyOuterClass { private int x; class MyInnerClass { void go() { x = 42;
내부클래스와외부클래스인스턴스 1. 외부클래스인스턴스를만듭니다. MyOuter 객체 2. 외부클래스의인스턴스를이용하여내부클래스의인스턴스를만듭니다. MyInner 객체 int x 3. 외부객체와내부객체는각별한사이가됩니다. 외부객체 String s 내부객체
내부클래스의인스턴스 일반클래스의인스턴스를만들때와똑같은식으로하면됩니다. class MyOuter { private int x; MyInner inner = new MyInner(); public void dostuff() { inner.go(); class MyInner { void go() { x = 42;
애니메이션 1. 특정좌표에객체를그림 g.filloval(20, 50, 100, 100); 2. 다른좌표에객체를서로그림 g.filloval(25, 55, 100, 100); 3. 좌표를바꿔가면서위의단계반복
애니메이션 class MyDrawPanel extends JPanel { public void paintcomponent(graphics g) { g.setcolor(color.orange); g.filloval(x, y, 100, 100); x, y 좌표는어디에서바꿀까? repaint() 는어디에서호출할까? 그림패널을내부클래스로 paintcomponent 에서순환문을쓰지않고
뮤직비디오 (?)
GUI와무관한이벤트 미디이벤트를받아서처리해야함 미디이벤트 (NOTE ON 이벤트 ) 를직접받아쓸수없음 ControllerEvent 라는이벤트를사용 첫번째박자 NOTE ON, ControllerEvent 두번째박자 NOTE OFF 세번째박자 NOTE ON, ControllerEvent 네번째박자 NOTE OFF
메시지를쉽게만드는방법 1. 메시지인스턴스만들기 ShortMessage first = new ShortMessage(); 2. SetMessage() 를호출하여지시사항전달 first.setmessage(192, 1, instrument, 0); 3. 메시지에대한 MidiEvent 인스턴스만들기 MidiEvent noteon = new MidiEvent(first, 1); 4. 이벤트를트랙에추가 track.add(noteon); ShortMessage a = new ShortMessage(); a.setmessage(144, 1, 44, 100); MidiEvent noteon = new MidiEvent(a, 1); track.add(noteon);
메시지 / 이벤트를만들기위한메소드 public static MidiEvent makeevent(int comd, int chan, int one, int two, int tick) { MidiEvent event = null; try { ShortMessage a = new ShortMessage(); a.setmessage(comd, chan, one, two); event = new MidiEvent(a, tick); catch(exception ex) { return event;
숙제 본문을꼼꼼하게읽어봅시다. 코드를전부입력해서실행시켜보고조금씩고쳐봅시다. 장중간및맨끝에나와있는모든연습문제를자기힘으로해결해봅시다. API 문서에서이장에나와있는클래스및메소드에대한내용을직접찾아봅시다.