▶ 이벤트 처리


- 키보드나 마우스를 클릭하거나 마우스를 움직이는 등의 컴퓨터 내의 동작들을 이벤트(Event)가 발생했다고 하며, 해당 동작들을 어떻게 처리할지 결정하는 것을 이벤트 처리라고 한다. 해당 이벤트는 이벤트 리스너(Event Listener) 객체를 생성하여 처리한다.


- 이벤트-구동 프로그래밍(Event-Driven Programming) : 대부분의 프로그램은 알고리즘에 의해 문장들이 차례대로 실행된다. 그러나 이벤트-구동 프로그래밍의 경우 순서에 상관없이 이벤트가 발생함에 따라 프로그램을 실행한다.




 이벤트 객체


- 이벤트가 발생했을 때, 해당 이벤트를 처리하기 위해 이벤트를 보관 또는 저장하는 객체라고 생각하면 될 것이다. 


모든 이벤트 객체는 EventObject 클래스를 상속받는다.


- EventObject 클래스는 getSource() 메소드를 가지고 있으며이 메소드는 해당 이벤트를 일어나게 만든 이벤트 소스를 반환한다. 이벤트 소스란 어떤 원인(버튼 클릭, 키보드 입력 등)에 의해 이벤트가 발생했는지를 알려준다. 리턴 타입이 Object 이므로 필요한 타입으로 타입 변환하여 사용해야 한다.




 이벤트 리스너(Event Listener)


이벤트가 발생하면 이벤트에 대한 다양한 정보를 가진 이벤트 객체가 생성된다이 때발생된 이벤트 객체에 반응하여 이벤트를 처리하는 객체를 의미한다. 리스너는 인터페이스이므로 리스너 인터페이스를 구현하는 클래스와 이벤트 객체를 연결하면 된다.


- 이벤트 리스너 등록하기


public class Test extends JFrame {


//FIELDS

JButton button = new JButton("버튼“);


//CONSTRUCTOR

public Test() {

// 리스너를 등록할 때 매개변수로 이벤트 리스너 인스턴스(클래스)를 넘긴다.

button.addActionListener(new EventListenerA());

...

}

} 


이벤트 소스에 이벤트 리스너가 등록되어 있다면이벤트 발생 시 이벤트 리스너 내부의 이벤트 처리 메소드가 자동 호출된다등록된 리스너가 없으면 아무 일도 발생하지 않는다(컴포넌트의 addXXXXListener() 메소드 호출) 


- 이벤트 리스너를 생성하는 방법은 다양하다.


1. 리스너를 독립적인 클래스로 생성

=> 리스너 클래스가 이벤트가 발생한 클래스 내부의 멤버로 접근하는 것이 어렵다.


//이벤트 리스너를 구현하는 독립적인 클래스

class ListenerExample implements ActionListener {


@Override

public void actionPerformed(ActionEvent e) {

...//이벤트 처리 코드 작성

}


}

 

class FrameExample extends JFrame {


//FIELDS

private JButton button = new JButton("button");


//CONSTRUCTOR

public FrameExample() {

...

button.addActionListener(new ListenerExample()); //리스너는 필드에 선언해도 상관없다.

...

}


}

 

public class Main() {

public static void main(String[] args) {

FrameExample fe = new FrameExample();

}

}



2. 내부 클래스로서 리스너 클래스를 생성

=> 내부 클래스는 외부 클래스의 멤버 변수들을 자유롭게 사용할 수 있다.


//이벤트 리스너를 구현하는 중첩 클래스 - 인스턴스 멤버 클래스

class FrameExample extends JFrame {


//FIELDS

private JButton button = new JButton("button");


//CONSTRUCTOR

public FrameExample() {

...

button.addActionListener(new ListenerExample()); //리스너는 필드에 선언해도 상관없다.

...

}

 

private class ListenerExample implements ActionListener { //중첩 클래스

@Override

public void actionPerfomed(ActionListener e) {

...//이벤트 처리 코드 작성

}

}

}

 

public class Main() {

public static void main(String[] args) {

FrameExample fe = new FrameExample();

}

}



3. 해당 클래스가 이벤트를 바로 처리

=> actionPerformed(ActionEvent e) 메소드를 클래스 내부에 생성한다.


//해당 클래스가 이벤트 리스너를 구현한다.

class FrameExample extends JFrame implements ActionListener {


//FIELDS

JButton button = new JButton("button");

 

//CONSTRUCTOR

public FrameExample() {

...

button.addActionListener(this); //자기 자신이 리스너의 구현 클래스이므로 this를 매개변수로 준다.

...

}

 

//METHODS

@Override

public void actionPerformed(ActionListener) {

...//이벤트 처리 코드 작성

}

}


public class Main() {

public static void main(String[] args) {

FrameExample fe = new FrameExample();

}

}


 

4. 이벤트를 한번만 사용할 경우 무명 클래스 사용 (익명 객체)

=> 코드가 정의되자마자 바로 사용됨.


//처리하는 이벤트가 적은 경우에 주로 사용되며, 이벤트를 일으키는 컴포넌트가 많은 경우에는 추천하지 않는다.

class FrameExample extends JFrame implements ActionListener {


//FIELDS

JButton button = new JButton("button");

 

//CONSTRUCTOR

public FrameExample() {

...

button.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

if(e.getSource() == button)) { ... }

}

});

...

}

}


public class Main() {

public static void main(String[] args) {

FrameExample fe = new FrameExample();

}

}



5. 이벤트 핸들러 클래스 사용

=> 하나의 문장으로 간단하게 이벤트 리스너를 생성하므로 코드의 간결화를 유도한다.


//아주 간단한 타입의 이벤트 리스너에 대해서만 유용하다.

class FrameExample extends JFrame implements ActionListener {


//FIELDS

JButton button = new JButton("button");

 

//CONSTRUCTOR

public FrameExample() {

...

button.addActionListener((ActionListener) EventHandler.create(ActionListener.class, JFrame메소드명));

...

}

}


public class Main() {

public static void main(String[] args) {

FrameExample fe = new FrameExample();

}

}




 이벤트 종류


모든 컴포넌트가 제공하는 이벤트

 ComponentEvent 

 컴포넌트 위치 및 크기가 변경되면 발생

 FocusEvent 

 키보드 입력을 받거나 입력을 받지 않는 경우에 발생

 ContainerEvent 

 컨테이너에 컴포넌트가 추가 혹은 삭제될 경우 발생

 KeyEvent 

 키를 누르면키보드 포커스를 가지고 있는 객체에서 발생

 MouseEvent 

 마우스가 Clicked, Pressed, Released, Entered, Exited의 상황에서 발생

 MouseMotionEvent 

 마우스가 움직였을 때 발생

 MouseWheelEvent 

 컴포넌트 위에서 마우스 휠을 움직이면 발생

 WindowEvent 

 윈도우가 열리거나 닫히거나 아이콘화 되는 등과 같이 어떤 변화가 있을 때 발생 


 

 일부 컴포넌트만 제공하는 이벤트

 ActionEvent 

 사용자가 어떤 동작을 할 경우 발생

 해당 컴포넌트 : JButton, JCheckBox, JComboBox, JFileChooser, JMenuItem, JRadioButton,  JTextField

 CaretEvent 

 텍스트 삽입점이 이동하거나 텍스트 선택이 변경될 경우 발생

 해당 컴포넌트 JTextArea, JTextField

 ChangeEvent 

 객체의 상태가 변경되었을 경우 발생

 해당 컴포넌트 JButton, JCheckBox, JColorChooser, JMenuItem, JProgressBar, JRadioButton, JSlider,

 JSpinner

 DocumentEvent 

 문서의 상태가 변경되는 경우 발생

 해당 컴포넌트 JTextArea, JTextField

 ItemEvent 

 선택 가능한 컴포넌트에서 사용자가 선택하는 경우 발생

 해당 컴포넌트 JButton, JCheckBox, JComboBox, JMenuItem, JRadioButton

 ListSelectionEvent 

 테이블이나 리스트에서 선택이 변경되면 발생

 해당 컴포넌트 JList, JTable

 TreeSelectionEvent

 트리 구조의 컴포넌트에서 선택이 변경되면 발생
 해당 컴포넌트 : JTree




 리스너 인터페이스 요약


리스너 인터페이스

어댑터 클래스

메소드

ActionListener

X

actionPerformed()

AdjustmentListener

X

adjustmentValueChanged()

ComponentListener

ComponentAdapter

componentHidden(), componentMoved(), componentResized(),

componentShown()

ContainerListener

ContainerAdapter

componentAdded(), componentRemoved()

FocusListener

FocusAdapter

focusGained(), focusLost()

ItemListener

X

itemStateChanged()

KeyListener

KeyAdapter

KeyPressed(), KeyTyped(), KeyReleased()

MouseListener

MouseAdapter

mouseClicked(), mouseEntered(), mouseExited(), mousePressed(), 

mouseReleased()

MouseMotionListener

MouseMotionAdapter

mouseDragged(), mouseMoved()

TextListener

X

textValueChanged()

WindowListener

WindowAdapter

windowActivated(), windowClosed(), windowClosing(),

windowDeactivated(), windowDeiconified(), windowIconified()

windowOpened()




▶ 어댑터 클래스

 

이벤트를 처리하기 위해서는 리스너 인터페이스에서 정의되어 있는 모든 메소드를 구현해야 한다따라서 원하는 메소드가 하나뿐인 경우에도 인터페이스의 모든 메소드를 구현해야 하는 불편함이 있다.

 

어댑터 클래스(Adapter Class)는 각 리스너(Listener)에 대응되는 클래스로원하는 메소드만을 구현하는 것이 가능하다.

 

리스너는 인터페이스고 어댑터는 클래스의 형태로 제공되기 때문에 리스너를 사용할 때는 implements 키워드를어댑터를 사용할 때는 extends 키워드를 사용해야 한다.

 

자바에서는 다중 상속을 허용하지 않기 때문에 두 개의 클래스를 동시에 상속받을 수 없다따라서 어댑터 클래스를 내부 클래스(중첩 클래스)로 정의하여 사용한다.

 

리스너의 메소드가 하나인 의미적 메소드의 경우 대응하는 어댑터 클래스가 없다.


public class MyFrame extends JFrame {



MyFrame() {

...

addKeyListener(new MyKeyAdapter());

...

}

 

class MyKeyAdapter extends KeyAdapter {

@Override

public void keyTyped(KeyEvent e) { //하나의 메소드만 처리 가능

...//이벤트 처리 코드 작성

}

}

}






 

 

 

그래픽의 종류

 

그래픽은 문자나 숫자보다 더 빠르고 쉽게 정보를 전달할 수 있다.

 

자바에서 제공하는 그래픽으로는 색상, 폰트, 도형 그리기, 텍스트 출력, java2D 기초 등이 포함된다.

 

그래픽 프로그래밍은 두 가지 방법으로 이루어진다. 첫 번째 방법은 전통적인 AWT 패키지를 이용하는 것이고, 두 번째 방법은 최근에 출시된 Java 2D API를 이용하는 것이다. Java 2D를 사용하면 커브 그리기, 도형 회전 및 앤티앨리어싱과 같은 고차원적인 연산들을 할 수 있다.

 

자바는 플랫폼에 독립적이기 때문에 자바의 그래픽 모델도 플랫폼에 독립적이다. , 운영체제에 상관없이 어디서나 유사한 모양으로 나타난다.




그래픽 프로그래밍

 

프레임과 패널의 차이를 여기서 느낄 수 있을 것이다. 프레임 위에도 그래픽을 그리는 것이 가능하나 이것은 좋은 방법이 아니다. 프레임의 본 역할은 다른 컴포넌트를 포함하는 컨테이너의 역할로 설계되었기 때문이다.

 

그래픽을 컴포넌트 위에 그린 후, 해당 컴포넌트를 프레임 추가하는 것이 적절한 방법이다.

 

보편적으로 패널(JPanel) 에 그래픽을 그린다. 패널은 그림을 그릴 수 있는 서비스를 가지고 있을 뿐만 아니라, 동시에 컨테이너의 역할도 하기 때문에 배경을 그린 후에 버튼과 같은 다른 컴포넌트를 추가할 수 있다. , 사용자 인터페이스(UI)와 그래픽을 동시에 구현할 수 있는 것이다.

 

- paintComponent(Graphics g)

  • JComponent의 메소드로 스윙 컴포넌트가 자신의 모양을 다시 그릴 필요가 있을 때마다 호출되는 메소드이다.

  • , 사이즈를 변경하거나 프레임이 가려졌다가 다시 나타나게 되면 자바 시스템이 호출한다

  • 주로 고정 이미지, 라벨, 버튼, 메뉴바 등 항상 바뀌지 않는 컴포넌트가 필요할 때 사용하면 된다.

  • 그림을 그리는 코드에 paintComponent 메소드는 반드시 포함되어야 한다! 매개변수로 주어지는 Graphics 객체는 해당 프레임의 그래픽 객체이다. 따라서 선언하지 않아도 된다.

 

- Graphics 클래스 : 그림을 그리는데 필요한 모든 설정값과 그림 그리는 메소드를 가지고 있다. 따라서 자바에서의 모든 그리기는 그래픽 객체에서 이루어져야 한다.

 

- repaint() : paintComponent 메소드는 사용자가 아닌 자동적으로 호출되어야 한다. 따라서 사용자가 화면을 다시 그리고 싶다면 repaint()메소드를 호출하면 된다. 그러면 repaint 메소드는 적절한 시기에 paintComponent 메소드를 호출한다.

 

- super.paintComponent(g) : 이 문장은 그림이 그려지는 컴포넌트가 JPanel이나 JLabel처럼 그래픽 컴포넌트인 경우, paintComponent 메소드를 재정의 할 때 내부에 호출되면 좋은 문장이다그래픽 컴포넌트를 상속받았을 때, 부모 클래스가 그려야 될 부분도 있기 때문이다. 자기 그림만 그리고 종료해버리면 부모 클래스는 그릴 기회를 얻지 못한다.

 

그래픽 좌표계는 왼쪽 상단이 원점(0, 0)이고, 오른쪽으로 갈수록 x좌표 증가, 왼쪽으로 갈수록 y좌표가 증가한다. 모든 좌표값은 양수이며, 단위는 픽셀(pixel)이다.

 

 

 

그리기 메소드

 

목적 

메소드 

설명 

직선 그리기

 drawLine(int x1, int y1, int x2, int y2)

 좌표(x1, y1)에서 좌표(x2, y2)까지 직선을 그린다.

 drawPolyline(int[] xpoints, int[] ypoints,

                                            int npoints)

 배열 xpoints[]와 배열 ypoints[]을 가지고 여러 개의 직선을 그린다. poygon과 다른 점은 첫 번째 점과 마지막 점이 연결되지 않는다.

 사각형 그리기

 drawRect(int x, int y, int width, int height)

 사각형의 왼쪽 상단 좌표(x, y)를 기준으로 너비 width, 높이 height인 사각형을 그린다.

 fillRect(int x, int y, int width, int height)

 사각형의 왼쪽 상단 좌표(x, y)를 기준으로 너비 width, 높이 height인 채워진 사각형을 그린다.

 draw3DRect(int x, int y, int width, int height,

                                        boolean rasied)

 매개변수 rasied는 3차원 사각형을 볼록하게 보이게 할 것인지(true), 오목하게 보이게 할 것인지 (false)를 지정하며나머지 매개변수를 토대로 약간의 3차원 효과를 가미한 사각형을 그린다3원 효과를 내기 위해서는 전경색과 배경색을 잘 선택해야한다.

 fill3DRect(int x, int y, int width, int height,

                                        boolean rasied)

 매개변수는 draw3DRect 메소드의 것과 똑같은 역할을 하며이를 토대로 3차원 효과를 내는 채워진 사각형을 그린다.

 drawRoundRect(int x, int y, int width, int height,
                         int arcWidth, int arcHeight)

 매개변수 arcWidth arcHeight는 사각형의 둥근 모서리에 겹쳐지는 타원에 대한 호의 너비와 호의 높이를 의미한다. 매개변수에 해당하는 둥근 모서리를 가진 사각형을 그린다.

 fillRoundRect(int x, int y, int width, int height,

                          int arcWidth, int arcHeight)

 매개변수는 drawRoundRect 메소드의 것와 똑 역할을 하며, 이를 토대로 둥근 모서리를 가진 워진 사각형을 그린다.

 타원 그리기

 drawOval(int x, int y, int width, int height)

 좌측 상단의 좌표가 (x, y)이며, 너비 width, 높 height인 사각형 안에 내접하는 타원을 그린다

 fillOval(int x, int y, int width, int height)

 매개변수는 drawOval 메소드의 것과 똑같은 역할을 하며, 이를 토대로 채워진 타원을 그린다.

 호 그리기

 drawArc(int x, int y, int width, int height,

                         int startAngle, int arcAngle)

 좌측 상단의 좌표가 (x, y)이며, 너비 width, 높이 height의 사각형 안에 내접하는 타원의 호를 startAngle을 시작 각도로 하여 arcAngle의 각도큼 그린다.

 fillArc(int x, int y, int width, int height,

                         int startAngle, int arcAngle)

 매개변수는 drawArc 메소드의 것과 똑같은 역할을 하며, 이를 토대로 채워진 호를 그린다.

 문자열 그리기

 drawString(String s, int x, int y)

 매개변수는 출력할 문자열(s)과 문자열의 위치 (x, y)를 의미한다. 폰트가 지정되어 있지 않으면 디폴트 폰트가 사용된다.



 

색상(Color)

 

 생성자

설명 

 Color(int value)

 value는 0~ 255의 중 하나의 값을 가진다.

 Color(int r, int g, int b)

 r, g, b는 0~ 255의 중 하나의 값을 가진다.

 Color(int r, int g, int b, int alpha)

 alpha값은 불투명한 정도를 나타낸다. 0이면 투명


상수

  • Color.black : RGB값이 (0, 0, 0)이다.

  • Color.blue : RGB값이 (0, 0, 255)이다.

  • Color.cyan : RGB값이 (0, 255, 255)이다.

  • Color.red : RGB값이 (255, 0, 0)이다.

  • Color.green : RGB값이 (0, 255, 0)이다.

  • Color.white : RGB값이 (255, 255, 255)이다.

기타 더 많은 정보는 오라클 사이트에 가면 알 수 있다.


- 아래는 Color가 활용되는 메소드의 예시이다. Color 객체에 정의된 메소드가 아니다.


 메소드

설명 

 void setBackground(Color color)

 컴포넌트 객체에서 배경색을 설정한다.

void setColor(Color color)

 전경색을 설정한다.

Color getColor()

 현재의 전경색을 반환한다.


색상 선택기 : 애플리케이션에 따라 사용자로부터 색상을 선택하도록 하는 경우도 많다. 이 때 간편하게 사용할 수 있는 클래스가 JColorChooser 이다. 이 클래스는 색상 팔레트에서 사용자가 쉽게 색상을 선택할 수 있게 한다.


//c는 최초 색상을 나타내는 컬러 변수이다.

//초기 색상을 설정하지 않으면 Color.white를 표시한다.

JColorChooser colorChooser = new JColorChooser(Color c);



 

폰트(Font)

 

- 윈도우에 문자열을 출력하기 위해 그래픽 객체의 drawString메소드를 호출한다

 

폰트를 지정하기 위해서는 Font 클래스를 사용한다. 생성자는 매개변수로 폰트 이름, 스타일, 크기를 받는다.


 //Serif폰트의 BOLD 스타일을 가진 크기 24의 폰트를 생성한다.

Font font = new Font(“Serif”, Font.BOLD, 24);


-첫 번째 매개변수로 오는 폰트 이름은 프로그램이 실행되는 컴퓨터에 설치된 모든 폰트가 사용될 수 있다. 그러나 모두에게 설치되지 않은 폰트도 존재하므로 자바에서는 논리적인 폰트를 제공한다.

 

자바에서 제공하는 논리적인 폰트(Font)

 Serif

 삐침(serif)을 가지지 가변폭 글꼴

 SansSerif 

 삐침(serif)을 가지지 않는 가변폭 글꼴

 Monospaced 

 고정폭을 가지는 글꼴

 Dialog 

 대화상자에서 텍스트 출력을 위하여 사용되는 글꼴

 DialogInput 

 대화상자에서 텍스트 입력을 위하여 사용되는 글꼴


폰트 스타일 : 스타일을 조합하고 싶으면 폰트스타일A | 폰트스타일B”와 같이 한다.

  • Font.BOLD : 볼드체
  • Font.ITALIC : 이탤릭체
  • Font.PLAIN : 표준체

 

폰트 설정하기

setFont(Font font)컴포넌트나 그래픽 객체에서 폰트를 지정한다.

 

 

 

Graphics2D 클래스

 

- Java2D를 사용하기 위해 Graphcis 클래스를 상속받아 확장하여 향상된 기능을 제공한다.

 

광범위한 그래픽 객체를 그릴 수 있다.

 

도형의 내부를 그라디언트(gradient)나 무늬로 채울 수 있다.

 

문자열을 출력할 때 폰트와 렌더링 과정을 세밀하게 조정할 수 있다.

 

이미지를 그릴 수 있꼬 필터링 연산을 적용할 수 있다.

 

그래픽 객체들의 충돌을 감지할 수 있는 메커니즘을 제공한다.

 

렌더링 중간에 객체들을 조합하거나 변형할 수 있다.

 

화면과 프린터에 같은 방법으로 그릴 수 있다.

 

- Graphics2D를 사용하려면, paintComponent 메소드의 매개변수인 Graphics 참조 변수를 Graphics2D 참조 변수로 타입 변환하여 사용하면 된다.

 

- Java 2D에서는 도형들의 좌표를 float형 또는 double형으로 표현한다.

 

형상을 그리는 메소드 (모든 도형 클래스들은 Shape인터페이스를 구현한다.)


메소드

설명 

 draw(Shape s)

 도형 객체의 외곽선을 그린다.

 fill(Shape s)

 도형 객체의 내부를 색상이나 패턴으로 채워서 그린다.

 drawString(String s, int x, int y)

 문자열을 그린다.

 drawImage(Image image, int x, int y, ImageObserver observer)

 지정된 이미지를 그린다.


그리기의 속성(attribute)을 변경하는 메소드


메소드

설명 

setStroke(new BasicStroke(int value))

 선의 두께(value)을 설정한다.

setRenderingHint(RenderingHints.KEY_ANTIALASING,

                                RenderingHints.VALUE_ANTIALIAS_ON)

 앤티에일리어싱은 도형을 매끄럽게 그리기 위하여 설정한다연산 시간은 조금 더 걸리지만 그만큼 그래픽의 품질이 좋아진다.


 

 

이미지 그리기

 

자바는 gif, png, jpeg 타입의 이미지를 화면에 그릴 수 있다.

 

- Java 2D로 작성된 그림을 이미지 파일로 저장할 수 있다.

 

- java.awt.Image : 이미지를 픽셀들의 2차원 배열로 나타내는 수퍼 클래스이다.

 

- java.awt.image.BufferedImage : Image 클래스를 확장한 클래스로 직접 이미지 데이터를 처리할 수 있다. , 픽셀을 읽거나 쓸 수 있다. 애플리케이션은 이 클래스의 객체를 생성하는 것이 좋다.

 

이미지 로딩 : 디지털 이미지의 경우, 일반적으로 jpeggif 형식으로 압축되어서 파일 형태로 존재한다. 프로그램에서 제일 먼저 해야 할 일은 이들 파일을 읽어서 내부 형식의 이미지로 변환하는 것이다.


// javax.imageio.ImageI/O 클래스는

// gif,png,jpeg,bmp,wbmp 형식의 이미지 파일을 읽을 수 있다.


BufferedImage img = null;

try {

img = ImageIO.read(new FIle(“sampleimg.jpg”));

} catch (IOException e) { }


- 이미지 그리기 관련 메소드는 자주 사용되는 것 두 가지만 알아보고, 나머지는 아래의 오라클 사이트를 참조하면 오버로딩된 메소드를 알 수 있다.

https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html


메소드 

설명 

 boolean drawImage(Image img, int x, int y, 

                                         ImageObserver observer)

 이미지의 좌측 상단(x,y)를 기준으로 이미지를 그린다.

 observer는 일반적인 경우에 null을 전달하면 된다

 이 메소드는 전체의 이미지를 화면에 1:1로 매핑하여서 그

 리는 것이다.

 boolean drawImage(Image img, int dstx1, int dsty1, 

int dstx2, int dsty2, int srcx1, int srcy1, int srcx2, int srcy2,

                                         ImageObserver observer)

 이미지 전체를 그리지 않고 일부만 그리고 싶은 경우에는 이 메소드를 사용한다. src로 시작하는 변수는 원본 이미지에서 그리고 싶은 영역이다. dst로 시작하는 변수들은 화면의 영역을 의미한다화면에 그려지는 이미지의 폭과 높이 (dstx2-dstx1)과 (dsty2-dsty1)으로 계산할 수 있다. 따라서 src 영역과 dst 영역이 다르면 이미지는 늘려지거나 줄여진다.







 

 

 

배치 관리자(Layout Manager)

 

컨테이너 안에 추가되는 컴포넌트의 위치와 크기를 자동적으로 결정한다.




 FlowLayout


컴포넌트들을 왼쪽에서 오른쪽으로 배치한다. JPanelApplet(awt.애플릿)의 디폴트 배치 관리자이다.


- 너비를 벗어날 경우 다음 줄에서 다시 배치를 시작한다.

 


생성자 

설명 

 FlowLayout()

 새로운 FlowLayout객체를 생성하는 디폴트 생성자이다기본 설정은 

 중앙(center)배치이며간격은 세로가로 각각 5픽셀이다.

 FlowLayout(int align)

 매개변수로 정수로 받는데이는 정렬 방식을 의미한다정렬 매개변수로

 FlowLayout.LEADING, FlowLayout.CENTER, FlowLayout.TRAILING 

 이 있다.

 FlowLayout(int align, int hgap, int vgap)

 매개변수로 정렬 방식과 수평 간격(hgap)과 수직 간격(vgap)을 받으며

 이를 토대로 새로운 FlowLayout 객체를 생성한다.




 BorderLayout


- 컴포넌트들이 상(North), (South), (East), (West) 그리고 중간(Center)에 배치된다.


- JFrameJApplet(swing.애플릿), 대화 상자와 같은 최상위 컨테이너의 디폴트 배치 관리자이다.


- 컴포넌트의 영역을 지정하지 않을 경우 자동으로 중간 영역에 배치된다.


- 같은 위치에 컴포넌트들이 추가되면 뒤 컴포넌트에 가려서 앞의 컴포넌트가 보이지 않는다.


- 배치된 컴포넌트는 항상 컨테이너 내부를 채우게 되며, setLocation, setSize 함수로 크기나 위치조절이 되지 않는다. (확인 결과 West, East의 경우 너비 조절은 가능하나 높이 조절은 안됩니다.)

 


생성자 

설명 

 BorderLayout()

 새로운 BorderLayout객체를 생성하는 디폴트 생성자이다.

 BorderLayout(int hgap, int vgap)

 매개변수로 수평 간격수직 간격을 받아 이들을 가지는 새로운 

 BorderLayout 객체를 생성한다.


메소드 

설명 

 void setHgap(int hgap)

 컴포넌트 사이의 수평 간격을 설정한다. (픽셀 단위)

 void setVgap(int vgap)

 컴포넌트 사이의 수직 간격을 설정한다. (픽셀 단위)




 GridLayout


- 컴포넌트를 격자 모습으로 배치한다. 행과 열로 관리된다.


- 모든 컴포넌트들의 크기는 같게 되며 컨테이너의 모든 공간은 컴포넌트로 채워진다. 따라서 윈도우의 크기를 바꾸면 GridLayout은 컴포넌트의 크기를 변경하여 윈도우의 크기에 맞춘다.



생성자 

설명 

GridLayout(int rows, int cols)

 row행과 cols열을 가지는 GridLayout객체를 생성한다만약 rows와 

 cols가 0이면 필요한 만큼의 행이나 열이 만들어진다.

 GridLayout(int rows, int cols, int hgap, int vgap)

 매개변수로 수평 및 수직 간격을 추가로 받아서 초기화한 뒤, rows행 cols

 을 가진 GridLayout객체를 생성한다.




 BoxLayout


컴포넌트를 하나의 행이나 열에 배치하며, Box를 쌓는 모양으로 정렬된다. 컴포넌트를 정렬할 수도 있다.

 


생성자 

설명 

BoxLayout(Container container, int align)

 매개변수로 배치 관리자를 설정할 컨테이너와정렬 방식을 받는다.  BoxLayout의 정렬 방식은 BoxLayout.X-AXIS(x축 정렬), BoxLayout.Y-AXIS(y축 정렬)로 두 가지가 있다.




▶ CardLayout


- 여러 장의 카드처럼 컨테이너를 배치하여 각각의 컨테이너 위에 컴포넌트(JComponent)를 배치한다.


- 즉, 순서가 변경되면, 해당 순서의 컨테이너가 나타나고, 그 외의 것은 감추어진다. 카드가 번갈아가며 나타나는 형태이다.

 

[버튼을 클릭하면 카드가 변경된다.]


생성자 

설명 

CardLayout()

 새로운 CardLayout객체를 생성하는 디폴트 생성자이다.

CardLayout(int hgap, int vgap)

 hgap과 vgap은 컴포넌트 사이의 수평 간격과 수직 간격을 픽셀로 표시한  다기본값은 0이다.


메소드

설명 

void first(Container parent)

 첫 번째 순서의 컨테이너를 보여준다.

void next(Container parent)

 다음 순서를 보여주며현재 순서가 마지막이면 처음 순서를 보여준다.


void previous(Container parent)

 이전 순서를 보여주며, 현재 순서가 처음이면 마지막 순서를 보여준다.

void last(Container parent)

 마지막 순서의 컨테이너를 보여준다.

void show(Container parent, String s)

 문자열 s로 지정한 컨테이너를 보여준다. 각 컨테이너별로 이름을 지어줄 

 수 있다.




▶ Example


- 컨테이너 클래스에 배치 관리자를 설정하려면 먼저 new 연산자를 이용하여 배치 관리자 객체를 만들고 컨테이너 클래스의 setLayout() 메소드를 사용하여 해당 객체를 배치 관리자로 설정한다.


JFrame frame = new JFrame(“My Frame”);

frame.setLayout(new BorderLayout());


또는


JFrame frame = new JFrame(“My Frame”);

BorderLayout bl = new BorderLayout();

frame.setLayout(bl);

 

컴포넌트의 크기에 대한 힌트를 배치 관리자에게 주는 방법으로 아래의 메소드들이 있다.

  • setMinimumSize(Dimension minimumsize)

  • setMaximumSize(Dimension maximumsize)

  • setPreferredSize(Dimension preferredsize) - setSize()와 유사하지만 레이아웃에 따라 setSize()로 지정할 경우 나타나지 않을 수 있으므로 레이아웃을 지정할 경우 setPreferredSize()를 사용하는 것이 좋다. 

 

컴포넌트의 정렬에 대한 힌트

  • setAlignmentX()

  • setAlignmentY()

 

배치 방향을 설정하기 위한 메소드 (Orientation방향, 지향이란 뜻을 가진다.)

  • setComponentOrientation()

  • applyComponentOrientation()

 

 

 

절대 위치로 배치하기


...


JButton button = new JButton("Button");

setLayout(null); // 배치 관리자를 null로 설정할 경우

button.setBounds(int x, int y, int width, int height); // 컴포넌트의 위치크기를 꼭 설정해야함.

add(Button("Button")) // 컴포넌트를 추가한다.


...

  

- setBounds() 메소드 대신에아래의 두 메소드를 호출해도 된다. Layout을 설정하지 않았기 때문이다.

  • setSize(int width, int height)

  • setLocation(int x, int y)








▶ Graphical User Interface (GUI) - 그래픽 사용자 인터페이스


- GUI 는 사용자와 상호작용하는 프로그램을 쉽게 작성할 수 있다.


현재 자바에서 사용되어지는 GUI 객체는 Abatract Windows Toolkit(AWT) 와 스윙(Swing)으로 두 가지가 있다.

  

- AWT -> java.awt.*;

1. 운영 체제가 제공하는 자원을 이용하여 컴포넌트를 생성한다

2. 다양한 플랫폼에서 쉽게 컴포넌트를 제공할 수 있다.

3. 컴포넌트가 플랫폼에 종속되므로 실행되는 플랫폼에 따라서 컴포넌트의 모습이 달라진다.

, 일관된 화면을 제공하는 것이 어렵다.

 

플랫폼은 소프트웨어 응용 프로그램들을 돌리는 데 쓰이는 하드웨어와 소프트웨어의 결합이다. 플랫폼은 하나의 운영 체제 또는 컴퓨터 아키텍처라고 단순히 말할 수 있으며 그 두 가지를 통칭해서 말할 수도 있다일반적으로 플랫폼은 컴퓨터의 아키텍처, 운영 체제(OS), 프로그램 언어, 그리고 관련 런타임 라이브러리 또는 GUI를 포함한다. - [출처] 위키백과

 

- Swing -> javax.swing.*; / javax.swing.event*;

1. 컴포넌트가 자바로 작성되어 있기 때문에 플랫폼에 상관없이 일관된 화면을 보여준다.

2. 스윙은 AWT에서 없는 다양한 컴포넌트들을 제공한다. (현재는 스윙의 사용이 권장되고 있다.)

3. 스윙은 AWT를 대체하기 위하여 AWT의 컴포넌트 이름 앞에 J를 붙인 JButton, JLabel 등으로 나타내고, 동일한 기능을 제공한다.

4. 다양한 룩앤필(Look and feel)을 선택할 수 있다. 룩앤필이란 각 운영 체제가 제공하는 GUI의 모습을 뜻한다. 룩앤필에 따라서 외관이 조금씩 달라진다.




▶ Swing의 기본 구조

 


1. Component(컴포넌트) : 레이블, 버튼, 텍스트 필드와 같은 GUI를 작성하는 기본 빌딩 블록을 의미한다. 윈도우 시스템(ex- javaFX)에서는 컨트롤(control)이라고 한다. 컴포넌트 클래스는 화면에 표시되어서 사용자와 상호 작용하는 시각적인 객체를 나타낸다. 이 클래스는 모든 스윙 클래스들이 가지고 있는 공통적인 기본 메소드를 정의한다.

 

- 기본 컴포넌트 : JButton, JLabel, JCheckBox, JList, JMenu, JTextField, JTextArea

- 컨테이너 컴포넌트 : JFrame, JDialog, JApplet, JPanel, JScrollPane

 

2. Container(컨테이너) : 다른 컴포넌트들을 내부에 놓을 수 있는 컴포넌트


- 최상위 컨테이너 : 다른 컨테이너 안에 포함될 수 없는 컨테이너

ex) JFrame, JDialog, JApplet

* JFrame : 윈도우와 메뉴를 가지는 일반적인 데스크탑 애플리케이션에 적합하다.

* JDialog : 메뉴가 없는 대화 상자 형식의 간단한 애플리케이션에 사용된다.

* JApplet : 애플릿을 작성하는데 사용된다.

 

- 일반 컨테이너 : 다른 컨테이너 안에 포함될 수 있는 컨테이너

ex) JPanel, JScrollPane




▶ 프레임(Frame)


컴포넌트를 추가할 수 있는 윈도우


생성자

설명 

 JFrame()

 타이틀이 없는 새로운 프레임을 생성

 JFrame(String title)

 매개변수로 받은 문자열을 타이틀로 하여 새로운 프레임을 생성


- JFrame은 "pane"이라는 것들로 분리되어지는데, 이들은 서로가 최상위에 위치해있다. Pane의 종류로는 Root Pane, Layered Pane, Content Pane, Glass Pane이 있고, 각 Pane은 다른 기능을 수행한다. 주로 컴포넌트가 추가되는 pane은 ContentPane이고 여기서는 ContentPane에 대해서만 다룬다.



- Content Pane에는 직접적으로 접근할 수 있는데, 그 방법으로 JPanel을 이용하는 것이다. 프레임의 ContentPane에 생성한 JPanel을 추가할 경우 보다 쉽게 프레임 속의 모든 것들을 다루게 된다.


프레임의 속성 변경 : 프레임도 객체이므로 속성을 변경하려면 set으로 시작하는 설정자 메소드를 사용하여야 한다

(반환형은 모두 void 이다.)


 설정자 메소드

 설명

setLocation(int x, int y)

(컴포넌트도 사용가능)

 모니터에서 프레임(or 컴포넌트)의 위치 설정

setSize(int width, int height)

(컴포넌트도 사용가능)

 프레임(or 컴포넌트)의 크기 설정

setBounds(int x, int y, int w, int h)

(컴포넌트도 사용가능)

 프레임(or 컴포넌트)의 위치와 크기 설정

 setIconImage(ImageIcon icon)

 윈도우 시스템에 타이틀 바태스크 스위처에 표시할 아이콘을 설정

setTitle(String title) 

 타이틀 바의 제목을 설정한다.

setResizable(boolean resizable) 

 사용자가 프레임의 크기를 조절할 수 있는 지 설정한다.

 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

 사용자가 프로그램 닫기를 눌렀을 때 프로그램이 완전히 종료되는

 지의 여부를 설정하며, 기본값은 닫기를 눌러도 프로그램이 종료되

 지 않도록  되어 있다.

setLayout(LayoutManager manager)

(패널도 사용가능)

 레이아웃을 설정하는 메소드로 매개변수는 컴포넌트들을 배치하

 는 배치관리자이다. 디폴트 값은 BorderLayout 이고, 컴포넌트

 위치를 변경하고 싶다면 LayoutManager null로 설정해야 한다.

setVisible(boolean visible)

(컴포넌트도 사용가능)

 프레임(or 컴포넌트)이 눈에 보이게 하는지 설정하는 메소드이다. 

 기본값이 false 이므 true로 설정해야 프레임을 볼 수 있다

 설정안하면 안보인다.

setLocationRelativeTo(Component component) 

 매개변수로 지정받은 컴포넌트 위치에 따라 상대적으로 프레임의

 위치가 결정된다. 그러나 매개변수로 null을 전달할 경우 모니터 

 화면의 중앙을 기준으로 프레임이 배치된다.

 setMenuBar(JMenuBar menubar)

 현재 프레임에 메뉴바를 붙인다.

 setContentPane(JPanel panel)

 컨테이너에 패널을 추가




▶ 패널(Panel)


- 컴포넌트들을 포함하고 있도록 설계된 컨테이너이다. 패널에 컴포넌트들을 추가하고 해당 패널을 프레임에 추가하는 것이 일반적으로 컴포넌트들을 화면에 표시하는 방법이다. 패널을 프레임에 추가하지 않고 프레임에 컴포넌트들을 직접 추가하는 것도 가능하다. 그러나 별도의 패널을 쓰는 것이 유지 보수 및 배치 관리에 좋은 경우가 많다. 쉽게 말해 패널은 스윙의 "위젯"을 성립시키기 위해 이용되어진다.

 

 생성자

 설명

 JPanel()

 새로운 패널 생성

 JPanel(boolean isDoubleBuffered)

 매개변수가 참일 경우 더블 버퍼링을 사용

 JPanel(LayoutManager layouy)

 매개변수로 지정된 배치 관리자를 사용하는 패널 형성


 메소드

 설명

void setLayout(LayoutManager layout)

 설명은 위와 같고, 디폴트는 FlowLayout 이다.

 void setToolTipText(String text)

 사용자가 마우스를 패널(or 컴포넌트)의 빈 곳에 올려놓으면 툴팁을 표시한다.




▶ 그 외 프레임 또는 패널에서 자주 쓰이는 메소드


 메소드

 설명

 void add(Component c)

 지정된 컴포넌트를 추가한다.

void remove(Component c)

 지정된 컴포넌트를 제거한다.

void pack()

 프레임 크기를 추가된 컴포넌트들의 크기에 맞도록 조절한다.




 레이블(Label) 


편집이 불가능한 텍스트를 표시하기 위한 컴포넌트


JLabel

 생성자

 JLabel()

 비어있는 새로운 레이블을 생성한다.

 JLabel(String text)

 매개변수로 받은 텍스트를 표시하는 레이블을 생성한다.

 JLabel(Icon icon)

 매개변수로 받은 아이콘을 표시하는 레이블을 생성한다. 

 주로 ImageIcon을 사용하여 레이블의 이미지를 생성한다.

 메소드

 void setText(String text)

 레이블의 텍스트를 설정한다.

 String getText()

 레이블의 텍스트를 반환한다.

void setIcon(Icon icon)

 레이블의 아이콘을 설정한다. 

  Icon getIcon()

 레이블의 아이콘을 반환한다. 




 버튼(Button)


- 사용자가 클릭했을 때, 이벤트를 발생하여 원하는 행위를 하게 하는 데 이용된다.

 

JButton

 생성자

 JButton()

 레이블이 없는 버튼을 생성한다.

JButton(String label)

 매개변수로 받은 텍스트가 표시되는 버튼을 생성한다.

 JButton(Icon icon)

 매개변수로 받은 아이콘이 표시되는 버튼을 생성한다. 

 주로 ImageIcon을 사용하여 버튼 이미지를 생성한다.

 메소드

 void setText(String text)

 버튼의 텍스트를 설정한다.

 String getText()

 버튼의 텍스트를 반환한다.

void setIcon(Icon icon)

 버튼의 아이콘을 설정한다. 

  Icon getIcon()

 버튼의 아이콘을 반환한다. 

 void doClick()

 사용자가 버튼을 누른 것처럼 이벤트를 발생한다.

void setBorderPainted(boolean value)

 버튼의 경계를 나타내거나 감춘다.

void setContentAreaFilled(boolean value)

 버튼의 배경을 채울 것인지를 설정한다.

 void setEnabled(boolean value)

 버튼을 활성화하거나 비활성화한다.

 void setRollOverEnabled(boolean value)

 마우스가 버튼 위에 있으면 경계를 진하게 하는 롤오버 효과를 

 설정한다.




 텍스트 필드(TextField) 


- 입력이 가능한 한줄의 텍스트 필드를 만드는데 사용된다.

 

JTextField

 생성자

JTextField()

 비어있는 새로운 텍스트 필드를 생성한다.

 JTextField(int num)

 매개변수로 지정된 글자 수를 가지고 있는 텍스트 필드를 생성한다.

 JTextField(String text)

 지정된 문자열로 초기화된 텍스트 필드 생성

 메소드

 void setText(String text)

 텍스트 필드의 문자열을 설정한다.

 String getText()

 텍스트 필드에 입력된 문자열을 반환한다.

void setEditable(boolean value)

 사용자가 텍스트 필드를 수정할지의 여부를 설정한다.

  boolean isEditable()

 사용자가 텍스트 필드를 수정할 수 있으면 true, 없으면 false를 반환한다.





+ Recent posts