9장 다형성 Lab 9-2
목차 색상 선택자 움직이는 원 색칠하기 슬라이더 속도 조절
움직이는 원 색칠하기 CirclePanel을 수정한다. 버튼을 눌렀을 때 원의 색이 바뀌도록 한다. 버튼을 만들고, 적절한 label을 붙인다. ColorListener 클래스를 추가한다. 버튼을 눌렀을 때, 원의 색을 바꾸고 repaint한다. 각 버튼마다 리스너를 추가하고, 버튼과 리스너를 연결한다. 색상 버튼을 위한 패널을 만들어 버튼을 붙인다. 색상 패널을 주 패널의 북쪽에 붙인다.
움직이는 원 색칠하기(Cont.) “Choose Color” 버튼을 추가한다. 다른 색상 버튼의 가운데 둔다. 이 버튼은 JColorChooser를 부른다. 버튼을 눌렀을 때 선택한 색이 원의 색이 된다. ColorListener를 사용한다. 사용자가 색상을 선택하고자 할 때, null을 전달한다. actionPerformed()에서 color가 null일 때 JColorChooser를 호출한다. JColorChooser는 showDialog()를 호출한다. 파라미터 3개 : 다이얼로그 상자에 대한 부모 컴포넌트 다이얼로그 상자 프레임의 제목 초기 색상
움직이는 원 색칠하기(Cont.) //************************************************************************* // MoveCircle.java // GUI를 보여주기 위해 CirclePanel을 사용한다. import java.awt.*; import javax.swing.*; public class MoveCircle { //-------------------------------------------------------------------- // GUI frame을 구성한다. public static void main(String[] args) JFrame frame = new JFrame("MoveCircle"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setPreferredSize(new Dimension(400,300)); frame.getContentPane().add(new CirclePanel(400,300)); frame.pack(); frame.setVisible(true); }
움직이는 원 색칠하기(Cont.) //************************************************************************* // CirclePanel.java // 원을 이동하는 버튼과 원을 포함하는 패널. import java.awt.event.*; import java.awt.*; import javax.swing.*; public class CirclePanel extends JPanel { private final int CIRCLE_SIZE = 50; private int x, y; private Color c; //-------------------------------------------------------------------- // 원, 원을 이동하는 버튼을 구성. public CirclePanel(int width, int height) x = (width/2) - (CIRCLE_SIZE/2); y = (height/2) - (CIRCLE_SIZE/2); c = Color.green; this.setLayout(new BorderLayout());
움직이는 원 색칠하기(Cont.) JButton left = new JButton("Left"); JButton right = new JButton("Right"); JButton up = new JButton("Up"); JButton down = new JButton("Down"); left.addActionListener(new MoveListener(-20,0)); right.addActionListener(new MoveListener(20,0)); up.addActionListener(new MoveListener(0,-20)); down.addActionListener(new MoveListener(0,20)); JPanel buttonPanel = new JPanel(); buttonPanel.add(left); buttonPanel.add(right); buttonPanel.add(up); buttonPanel.add(down); this.add(buttonPanel, "South"); }
움직이는 원 색칠하기(Cont.) //-------------------------------------------------------------------- // 패널에 원을 그린다. public void paintComponent(Graphics page) { super.paintComponent(page); page.setColor(c); page.fillOval(x, y, CIRCLE_SIZE, CIRCLE_SIZE); } // 원을 이동하는 버튼에 대한 감청자를 표현한다. private class MoveListener implements ActionListener private int dx; private int dy;
움직이는 원 색칠하기(Cont.) //---------------------------------------------------------------- // 이동할 원의 위치를 매개변수로 받는다. public MoveListener(int dx, int dy) { this.dx = dx; this.dy = dy; } // x, y 좌표를 바꾼다. public void actionPerformed(ActionEvent e) x += dx; y += dy; repaint();
속도 조절 Jslider 객체를 구성한다. Jslider 선언 초기화한다. 큰 눈금 표시는 40, 작은 눈금 표시는 10. Horizontal 값 : 0 – 200 초기값 : 30 큰 눈금 표시는 40, 작은 눈금 표시는 10. setPaintTicks(true), setPaintLabels(true) setAlignmentX(Component.LEFT_ALIGNMENT)
속도 조절(Cont.) SliderListener를 수정한다. 슬라이더의 label을 추가한다. stateChanged()를 완성한다. 슬라이더의 값을 결정하고, 그 값으로 타이머 delay를 결정한다. 타이머 delay는 타이머 클래스의 메소드 setDelay(int delay)를 사용한다. Jslider 객체에 리스너를 추가한다. 슬라이더의 label을 추가한다. “Timer Delay”, 왼쪽 정렬
속도 조절(Cont.) Jpanel객체를 생성한다. 원이 패널 아래쪽으로 사라지는 문제점을 해결해본다. Label과 슬라이더를 붙인다. 주 패널의 남쪽에 붙인다. 원이 패널 아래쪽으로 사라지는 문제점을 해결해본다. actionPerformed()에 slidePanelHt(int형)을 선언한다. getSize()를 이용하여 패널의 높이를 위의 변수에 저장한다. 예) 패널의 이름이 slidePanel일 때 slidePanelHt = slidePanel.getSize().height;
속도 조절(Cont.) – SpeedControl.java //************************************************************************* // SpeedControl.java // 슬라이더로 공의 속도를 조절하는 제어 패널을 표현한다. import java.awt.event.*; import java.awt.*; import javax.swing.*; public class SpeedControl { //-------------------------------------------------------------------- // 프레임을 구성한다. public static void main(String[] args) JFrame frame = new JFrame("Bouncing Balls"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new SpeedControlPanel()); frame.pack(); frame.setVisible(true); }
속도 조절(Cont.) – SpeedControlPanel.java //************************************************************************* // SpeedControlPanel.java // // 튀는 공을 표현하기 위한 패널. import java.awt.event.*; import java.awt.*; import javax.swing.*; import javax.swing.event.*; public class SpeedControlPanel extends JPanel { private final int WIDTH = 600; private final int HEIGHT = 400; private final int BALL_SIZE = 50; private Circle bouncingBall; private Timer timer; private int moveX, moveY;
속도 조절(Cont.) – SpeedControlPanel.java //-------------------------------------------------------------------- // 타이머를 표함한 패널을 구성. public SpeedControlPanel() { timer = new Timer(30, new ReboundListener()); this.setLayout(new BorderLayout()); bouncingBall = new Circle(BALL_SIZE); moveX = moveY = 5; // 슬라이더 객체를 구성한다. setPreferredSize(new Dimension(WIDTH, HEIGHT)); setBackground(Color.black); timer.start(); }
속도 조절(Cont.) – SpeedControlPanel.java //-------------------------------------------------------------------- // 공을 그린다. public void paintComponent(Graphics page) { super.paintComponent(page); bouncingBall.draw(page); } //************************************************************************* // 타이머의 감청자. public class ReboundListener implements ActionListener // 튀는 공의 위치를 업데이트한다. public void actionPerformed(ActionEvent action) bouncingBall.move(moveX, moveY);
속도 조절(Cont.) – SpeedControlPanel.java int x = bouncingBall.getX(); int y = bouncingBall.getY(); if (x < 0 || x >= WIDTH - BALL_SIZE) moveX = moveX * -1; repaint(); } //************************************************************************* // 슬라이더 감청자. private class SlideListener implements ChangeListener { //-------------------------------------------------------------------- // 슬라이더가 변경되었을 때 호출. public void stateChanged(ChangeEvent event)
속도 조절(Cont.) – CirclePanel.java //************************************************************************* // CirclePanel.java // // 원을 이동하는 버튼과 원을 포함하는 패널. import java.awt.event.*; import java.awt.*; import javax.swing.*; public class CirclePanel extends JPanel { private final int CIRCLE_SIZE = 50; private int x, y; private Color c; //-------------------------------------------------------------------- // 원, 원을 이동하는 버튼을 구성. public CirclePanel(int width, int height) x = (width/2) - (CIRCLE_SIZE/2); y = (height/2) - (CIRCLE_SIZE/2);
속도 조절(Cont.) – CirclePanel.java c = Color.green; this.setLayout(new BorderLayout()); JButton left = new JButton("Left"); JButton right = new JButton("Right"); JButton up = new JButton("Up"); JButton down = new JButton("Down"); left.addActionListener(new MoveListener(-20,0)); right.addActionListener(new MoveListener(20,0)); up.addActionListener(new MoveListener(0,-20)); down.addActionListener(new MoveListener(0,20)); JPanel buttonPanel = new JPanel(); buttonPanel.add(left); buttonPanel.add(right); buttonPanel.add(up); buttonPanel.add(down); this.add(buttonPanel, "South"); }
속도 조절(Cont.) – CirclePanel.java //-------------------------------------------------------------------- // 패널에 원을 그린다. public void paintComponent(Graphics page) { super.paintComponent(page); page.setColor(c); page.fillOval(x, y, CIRCLE_SIZE, CIRCLE_SIZE); } // 원을 이동하는 버튼에 대한 감청자를 표현한다. private class MoveListener implements ActionListener private int dx; private int dy;
속도 조절(Cont.) – CirclePanel.java //---------------------------------------------------------------- // 이동할 원의 위치를 매개변수로 받는다. public MoveListener(int dx, int dy) { this.dx = dx; this.dy = dy; } // x, y 좌표를 바꾼다. public void actionPerformed(ActionEvent e) x += dx; y += dy; repaint();
속도 조절(Cont.) – Circle.java //************************************************************************* // Circle.java // // 원을 표현 import java.awt.*; import java.util.Random; public class Circle { private int x, y; private int radius; private Color color; static Random generator = new Random();
속도 조절(Cont.) – Circle.java //-------------------------------------------------------------------- // 무작위로 원을 생성한다. // 반지름 : 25 - 74 // 색상 : RGB 0 - 16777215(24 비트) // x 좌표 : 왼쪽 위모서리 0 - 599 // y 좌표 : 왼쪽 위모서리 0 - 399 public Circle() { radius = Math.abs(generator.nextInt())%50 + 25; color = new Color(Math.abs(generator.nextInt())%16777216); x = Math.abs(generator.nextInt())%600; y = Math.abs(generator.nextInt())%400; }
속도 조절(Cont.) – Circle.java //-------------------------------------------------------------------- // 주어진 크기로 원 생성. public Circle(int size) { radius = Math.abs(size/2); color = new Color(Math.abs(generator.nextInt())%16777216); x = Math.abs(generator.nextInt())%600; y = Math.abs(generator.nextInt())%400; } // 원을 그린다. public void draw(Graphics page) page.setColor(color); page.fillOval(x, y, radius*2, radius*2);
속도 조절(Cont.) – Circle.java // 원의 위치를 옮긴다. public void move(int over, int down) { x = x + over; y = y + down; } // x좌표를 반환한다. public int getX() return x; // y좌표를 반환한다. public int getY() return y;