passion and relax

[JAVA] 12. 그래픽 이야기 (GUI, 이벤트 처리, 내부 클래스에 대한 소개) 본문

프로그래밍

[JAVA] 12. 그래픽 이야기 (GUI, 이벤트 처리, 내부 클래스에 대한 소개)

Grab Java 2024. 5. 28. 10:04

JFrame > Component == Widget == Swing 패키지의 구성요소

JFrame
. 화면 위의 창(window)을 나타내는 객체
. JFrame == 창 (window)
Component
. 창에 넣을 수 있는 swing 구성 요소
. javax.swing 패키지에 있다.
. JButton, JRadioButton, JCheckBox, JLabel, JList, JScrollPane, JSlider, JTextArea, JTextField,
    JTable 등등..
. 이들의 이벤트는 java.awt.event 패키지에 아래 처럼 들어있다.
    MouseEvent, KeyEvent, WindowEvent, ActionEvent, ...


버튼 예제 (하나의 이벤트 처리)

public class SimpleGui1B implements ActionListener {
   
    JFrame frame;
    JButton button;
 

    public static void main(String[] args) {
        SimpleGui1B gui = new SimpleGui1B();
        gui.go();
    }
   
    public void go() {
        frame = new JFrame();
        button = new JButton("click me");
        button.addActionListener(this);
        frame.getContentPane().add(button);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 300);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        button.setText("I've been clicked!");
    }
}

그림 그리기 위젯

paintComponent(Graphics g)를 만들어만 놓으면 된다. 호출은 시스템에서 알아서 한다.
java.awt.Graphics는 Graphics2D의 상위클래스로 Graphics2D로 캐스트해서 쓰면 더 좋다.
    Graphics2D g2d = (Graphics2D) g;
Graphics 일 때
    drawImage(), drawLine(), drawPolygon, drawRect(), drawOval(), fillRect(), fillRoundRect(),
    setColor()
Graphics2D 일 때
    fill3DRect(), draw3DRect(), rotate(), scale(), shear(), transform(), setRenderingHints(), ...

 


오렌지색 사각형 출력 예제

public class SimpleGui3C {

 

    JFrame frame;
    MyDrawPanel drawPanel;
   
    public static void main(String[] args) {
        SimpleGui3C gui = new SimpleGui3C();
        gui.go();
    }
   
    public void go() {
        frame = new JFrame();
        drawPanel = new MyDrawPanel();
       
        frame.getContentPane().add(drawPanel);
       
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 300);
        frame.setVisible(true);
    }
}

class MyDrawPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        g.setColor(Color.ORANGE);
        g.fillRect(80, 50, 100, 100);
    }
}

 


JPEG 출력 예제

class MyDrawPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        Image image = new ImageIcon("aaa.jpg").getImage();
        g.drawImage(image, 30, 40, this);   //좌료 30, 40에 이미지 표현
    }
}

 


검은색 배경에 임의색 원

class MyDrawPanel extends JPanel {
    @Override
    protected 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);    //타원 그리는 메소드(fillOval). 너비, 높이가 같으면 원을 그림.
    }
}

 


고정색 그래디언트 (Graphics2D 활용)

class MyDrawPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        //시작좌표, 시작색, 끝좌표, 끝색
        GradientPaint gradient = new GradientPaint (70, 70, Color.blue, 150, 150, Color.orage);
        g2d.setPaint (gradient);
        g.fillOval (70, 70, 100, 100);    //타원 그리는 메소드(fillOval). 너비, 높이가 같으면 원을 그림.
    }
}

 


임의색 그래디언트 (Graphics2D 활용)

class MyDrawPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;

        int red = (int) (Math.random() * 255);
        int green = (int) (Math.random() * 255);
        int blue = (int) (Math.random() * 255);
        Color startColor = new Color(red, green, blue);
        red = (int) (Math.random() * 255);
        green = (int) (Math.random() * 255);
        blue = (int) (Math.random() * 255);
        Color endColor = new Color(red, green, blue);

        GradientPaint gradient = new GradientPaint (70, 70, startColor, 150, 150, endColor);
        g2d.setPaint (gradient);
        g.fillOval (70, 70, 100, 100);    //타원 그리는 메소드(fillOval). 너비, 높이가 같으면 원을 그림.
    }
}

 


Inner 클래스

어떤 클래스가 다른 클래스의 일부인 것 같은 특성이 있을 때 사용한다.
하나의 클래스에서 같은 메소드를 서로 다른 내부 클래스에서 여러번 구현할 수 있다.
하나의 클래스에서 같은 인터페이스를 여러번 구현할 수 있다.
이러한 점을 이용해 이벤트 핸들러를 만들 때 유용하게 쓰인다.

 


Inner class 예제 (원이 이동되는 애니메이션)

public class SimpleAnimation {
    JFrame frame;
    MyDrawPanel drawPanel;

    int x = 70;
    int y = 70;
   
    public static void main(String[] args) {
        SimpleAnimation gui = new SimpleAnimation();
        gui.go();
    }
   
    public void go() {
        frame = new JFrame();
        drawPanel = new MyDrawPanel();
       
        frame.getContentPane().add(drawPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 300);
        frame.setVisible(true);
       
        for (int i=0; i<130; i++) {
            x++; y++;
            drawPanel.repaint();
            try {
                Thread.sleep(50);
            } catch (InterruptedException ex) {
                Logger.getLogger(SimpleAnimation.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
   
    class MyDrawPanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
           
            g.setColor(Color.GREEN);
            g.fillOval(x, y, 40, 40);
        }
    }
}

 


Inner class 예제 (여러 개의 이벤트 처리)

public class TwoButtons {
    JFrame frame;
    JLabel label;
    MyDrawPanel drawPanel;
    JButton labelButton;
    JButton colorButton;
   
    public void go() {
        frame = new JFrame();
        label = new JLabel("I'm a label");
        drawPanel = new MyDrawPanel();
        labelButton = new JButton("Change Label");
        colorButton = new JButton("Change Circle");
       
        labelButton.addActionListener(new LabelListener());
        colorButton.addActionListener(new ColorListener());
       
        frame.getContentPane().add(BorderLayout.WEST, label);
        frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
        frame.getContentPane().add(BorderLayout.EAST, labelButton);
        frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
       
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 300);
        frame.setVisible(true);
    }
   
    class LabelListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            label.setText("Clicked");
        }
    }
   
    class ColorListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            frame.repaint();
        }
    }
   
    class MyDrawPanel extends JPanel {
        @Override
        protected 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);
            g.setColor(new Color(red, green, blue));
            g.fillOval(70, 70, 100, 100);
        }
    }
   
    public static void main(String[] args) {
        TwoButtons gui = new TwoButtons();
        gui.go();
    }
}