GUI 응용 프로그램은 키보드뿐 아니라 마우스 사용 지원, 화려하고 다양한 화면과 더불어 사용자가 자유롭게 화면 작동 가능하다.
Java GUI 종류
AWT(Abstract Windows Toolkit) : 운영체제가 제공하는 자원을 이용하여 컴포넌트 생성한다. 따라서 운영체제 별로 느낌이 다르다.
Swing : 컴포넌트가 자바로 작성되어 있기 때문에 어떤 플랫폼에서도 일관된 화면을 보여줄 수 있다.
형식화된 텍스트 입력이나 패스워드 필드 동작과 같은 복잡한 기능이 제공된다.
Java 2D API : 그림, 이미지, 애니메이션 기능을 제공
데이터 전송 : 자르기, 복사, 붙이기 , Drag and Drop 등 데이터 전송 기능 제공 + undo, redo
Container
자바에서 Container는 창의 역할을 한다.
한 개 이상의 Container 위에 Component들이 올려질 영역
Container는 실제로는 Component보다 작은 개념
(예) Frame, Window, Panel, Dialog, Applet
(예) JFrame, JDialog, JApplet, JPanel, JScrollPane
Frame 생성 하기
방법1 : JFrame 객체 생성
Copy import javax . swing . * ;
public class FrameTest1 {
public static void main ( String [] args) {
// TODO Auto-generated method stub
JFrame f = new JFrame( "Frame Test" ) ;
f . setSize ( 300 , 200 ); //크기 지정
f . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE ); //swing에만 존재한다. x버튼 클릭시 종료
f . setVisible ( true ); // Container보이기
}
}
방법2 : JFrame 상속
Copy import javax . swing . * ;
class FrameTest extends JFrame {
public FrameTest () {
setSize( 300 , 200 ) ;
//swing에만 존재한다. x버튼 클릭시 종료
setDefaultCloseOperation( JFrame . EXIT_ON_CLOSE ) ;
setTitle( "Practice Frame" ) ;
setVisible( true ) ;
}
}
public class FrameTest1 {
public static void main ( String [] args) {
FrameTest f = new FrameTest() ;
}
}
메소드 or 생성자
Panel
Component들이 가질 수 있는 컨테이너이다.(컴포넌트들을 붙일 수 있는 판)
메소드 & 생성자
Component
실제로 Container 위에 올려져서 화면 구성을 담당하는 요소들이다.
(예) Button, TextField, TextArea, List
(예) JButton, JTextField, JChoice, JList, JMenu, JCheckbox, JScrollBar,JTextArea, JCanvas
Component 생성하기
Copy import javax . swing . * ;
class FrameTest extends JFrame {
public FrameTest () {
//버튼 생성, 추가
JButton button = new JButton( "버튼" ) ;
// Container위에 Component추가
this . add (button);
//
setSize( 300 , 200 ) ;
setDefaultCloseOperation( JFrame . EXIT_ON_CLOSE ) ;
setTitle( "Practice Frame" ) ;
setVisible( true ) ;
}
}
모양을 설정하는 메소드
Label
편집이 불가능한 텍스트를 표시한다.
Button
사용자가 클릭했을 경우, 이벤트를 발생하여 원하는 동작을 하게 하는데 이용된다.
Text Field
입력이 가능한 한줄의 텍스트 필드를 만드는데 사용한다.
여러가지 Component 생성하기
Copy class FrameTest extends JFrame {
public FrameTest () {
setDefaultCloseOperation( JFrame . EXIT_ON_CLOSE ) ;
setTitle( "Practice Component" ) ;
this . setLayout ( new FlowLayout() );
//한줄을 입력하기위한 텍스트 필드 + 10은 초기열 크
JTextField txt1 = new JTextField( 10 ) ;
this . add (txt1);
// 여러줄 입력하기 위한 텍스트 영역(행, 열)
JTextArea txt2 = new JTextArea( 5 , 10 ) ;
this . add (txt2);
//textarea 영역에 스크롤바 추가
this . add ( new JScrollPane(txt2) );
//비밀번호 필드
JPasswordField txt3 = new JPasswordField( 10 ) ;
this . add (txt3);
setSize( 200 , 200 ) ;
setVisible( true ) ;
}
}
Copy class FrameTest extends JFrame {
public FrameTest () {
ImageIcon img1 = new ImageIcon( "~/Downloads/aa.jpg" ) ;
ImageIcon img2 = new ImageIcon( "~/Downloads/aa.jpg" ) ;
//버튼에 이미지와 문자가 모두 나타나도록 설정
JButton btn1 = new JButton( "버튼1" , img1) ;
//Label을 이미지 또는 문자로 생성
JLabel lbl1 = new JLabel( "Label 입니다." ) ;
JLabel lbl2 = new JLabel(img2) ;
//체크박스 3개 생성 + true가 된곳은 체크가 되도록 설정
JCheckBox chk1 = new JCheckBox( "C++" ) ;
JCheckBox chk2 = new JCheckBox( "Ruby" ) ;
JCheckBox chk3 = new JCheckBox( "Java" , true ) ;
//단일선택 체크박스
JCheckboxGroup group = new JCheckboxGroup() ;
JCheckbox man = new JCheckbox( "남자" , true , group) ;
JCheckbox woman = new JCheckbox( "여자" , false , group) ;
JRadioButton rdo1 = new JRadioButton( "고래 " ) ;
JRadioButton rdo2 = new JRadioButton( "상어 " ) ;
JRadioButton rdo3 = new JRadioButton( "새우 " ) ;
}
}
LayoutManager
Container 위에 Component들을 올릴 때 자리 배치 방법
(예) FlowLayout, BorderLayout , GridLayout , CardLayout , GridBackLayout ...
Layout 설정 형식
Copy Container . setLayout ( new 레이아웃종류());
Flow Laytout
기본적으로 component들이 왼쪽에서 오른쪽으로 추가되는 형태이다.
Container의 크기가 변하면 component의 크기는 그대로 이며, 위치가 변경된다. 가운데 정렬이 기본이다.
Copy import java . awt . FlowLayout ;
import javax . swing . * ;
class FrameTest extends JFrame {
public FrameTest () {
JButton button = new JButton( "버튼" ) ;
this . add (button);
setSize( 300 , 200 ) ;
setDefaultCloseOperation( JFrame . EXIT_ON_CLOSE ) ;
setTitle( "Practice Frame" ) ;
// FlowLayout설정
setLayout( new FlowLayout()) ;
setVisible( true ) ;
}
}
Border Laytout
기본적으로 컴포넌트들이 틀 형태로 존재한다.
Border Layout에 component를 추가할 때는 this.add(컴포넌트, 위치);
를 지정해줘야한다. 위치를 지정해주지 않으면 Default값은 Center이다.
Copy import java . awt . BorderLayout ;
import java . awt . FlowLayout ;
import javax . swing . * ;
class FrameTest extends JFrame {
public FrameTest () {
JButton button = new JButton( "버튼" ) ;
this . add (button , BorderLayout . NORTH );
setSize( 300 , 200 ) ;
setDefaultCloseOperation( JFrame . EXIT_ON_CLOSE ) ;
setTitle( "Practice Frame" ) ;
setVisible( true ) ;
}
}
Grid Layout
테이블 형태의 레이아웃이다. 인수를 주지 않으면 행은 1행으로 고정되고 열이 계속해서 추가된다.
행/열 인수에 0이 들어갈 수 있다.
ex) (2,0)이면 행은 2행으로 고정, 열은 무한대
Copy import java . awt . BorderLayout ;
import java . awt . FlowLayout ;
import java . awt . GridLayout ;
import java . awt . LayoutManager ;
import javax . swing . * ;
class FrameTest extends JFrame {
public FrameTest () {
JButton [] b = new JButton [ 6 ];
setLayout( new GridLayout( 3 , 2 )) ;
for ( int i = 0 ;i < b . length ;i ++ ) {
b[i] = new JButton( "button" + i) ;
this . add (b[i]);
}
setSize( 300 , 300 ) ;
setDefaultCloseOperation( JFrame . EXIT_ON_CLOSE ) ;
setTitle( "Practice Frame" ) ;
setVisible( true ) ;
}
}
Card Layout
구체적인 위치 정하기
setLayout에는 null로 지정한 후 setBounds로 직접적인 좌표값을 지정할 수 있다.
Copy setLayout( null ) ;
setBounds( 0 , 0 , 0 , 0 ) ;
복합적인 레이아웃 설정하기
Copy import java . awt . BorderLayout ;
import java . awt . FlowLayout ;
import java . awt . GridLayout ;
import java . awt . LayoutManager ;
import javax . swing . * ;
class FrameTest extends JFrame {
public FrameTest () {
JPanel pane = new JPanel() ;
JButton [] b = new JButton [ 4 ];
for ( int i = 0 ;i < b . length ;i ++ ) {
b[i] = new JButton( "button" + i) ;
}
pane . add (b[ 0 ]);
pane . add (b[ 1 ]);
this . add (pane , "North" );
this . add (b[ 2 ] , "West" );
this . add (b[ 3 ] , "Center" );
setSize( 300 , 300 ) ;
setDefaultCloseOperation( JFrame . EXIT_ON_CLOSE ) ;
setTitle( "Practice Frame" ) ;
setVisible( true ) ;
}
}
public class FrameTest1 {
public static void main ( String [] args) {
FrameTest f = new FrameTest() ;
}
}
이벤트 처리
이벤트(event) : 마우스로 클릭하거나 키보드로 누르는 일련의 모든 작동
리스너(Listener) : 사용자가 마우스를 클릭하거나 키보드를 누를 때까지 기다리는 것
Copy 버튼을 누른다 -> 이벤트 객체가 발생 -> 이벤트 처리(이벤트 리스너 객체)
즉, 버튼에 반응하려면 이벤트 처리를 해야한다.
액션 이벤트 actionPerformed()
이벤트를 발생시키는 Component(버튼)가 있어야한다.
이벤트 발생 감지 방법 : Listener 인터페이스 를 달아준다.
클래스에서 implements 시켜 method를 구현 방법
Copy MyClass implements ActionListener{
public void actionPerformed( ActionEvent e) {
//꼭 구현해야하는 메소드
//Action 이벤트를 처리하는 코드가 여기에 들어간다.
}
}
new로 생성하여 Component마다 리스너를 붙이는 방법
Copy button1 . addActionListener ( new ActionListener() {메소드 구현 .. });
Event Listener 위치
별도의 클래스로 Event Listener를 작성
별도의 클래스를 두어 이벤트 동작만을 위한 처리를 작성하게 할 수 있다.
별도의 클래스이기때문에 클래스간 변수를 사용하도록 처리해주어야한다.
Copy MyClass implements ActionListener{
public void actionPerformed( ActionEvent e) {
//꼭 구현해야하는 메소드
//Action 이벤트를 처리하는 코드가 여기에 들어간다.
}
}
Copy public class MyFrame extends JFrame {
...
public MyFrame (){
JPanel panel = new JPanel() ;
btn = new JButton( "버튼" ) ;
btn . addActionListener ( new MyListener() );
panel . add (btn);
this . add (panel);
this . setVisible ( true );
}
}
내부 클래스로 Event Listener를 작성
위와 같이 별도로 클래스를 만들면 MyFrame안의 멤버 변수를 쉽게 사용할 수 없으므로 내부 클래스를 만들어줄 수 있다.
Copy import java . awt . event . ActionEvent ;
import java . awt . event . ActionListener ;
import javax . swing . JButton ;
import javax . swing . JFrame ;
import javax . swing . JPanel ;
class MyFrame extends JFrame {
private JButton btn;
public MyFrame () {
this . setSize ( 300 , 200 );
this . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );
this . setTitle ( "내부 클래스 이용하기" );
JPanel panel = new JPanel() ;
btn = new JButton( "버튼" ) ;
btn . addActionListener ( new MyListener() );
panel . add (btn);
this . add (panel);
this . setVisible ( true );
}
private class MyListener implements ActionListener {
public void actionPerformed ( ActionEvent e) {
if ( e . getSource () == btn) {
btn . setText ( "클릭됨" );
}
}
}
}
public class TestCS {
public static void main ( String [] args) {
MyFrame f = new MyFrame() ;
}
}
프레임 클래스가 Event Listener를 구현하도록 작성
public class Simple extends JFrame implements ActionListener{…}
의 형태로 actionPerformed를 구현할 수 있다.
각 컴포넌트들이 공통된 동작을 하는 것이 아니라 다양한 동작을 할대는, 각 컴포넌트에서 Event Listener룰 구현하도록한다.
Copy import java . awt . event . ActionEvent ;
import java . awt . event . ActionListener ;
import javax . swing . JButton ;
import javax . swing . JFrame ;
import javax . swing . JPanel ;
class MyFrame extends JFrame implements ActionListener {
private JButton btn;
public MyFrame () {
this . setSize ( 300 , 200 );
this . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );
JPanel panel = new JPanel() ;
btn = new JButton( "버튼" ) ;
btn . addActionListener ( this );
panel . add (btn);
this . add (panel);
this . setVisible ( true );
}
public void actionPerformed ( ActionEvent e) {
if ( e . getSource () == btn) {
btn . setText ( "클릭됨" );
}
//버튼이 여러개라면 if then else가 길어지는 형태이다.
}
}
public class TestCS {
public static void main ( String [] args) {
MyFrame f = new MyFrame() ;
}
}
각 컴포넌트들이 Event Listener를 구현하도록 작성
Copy import java . awt . event . ActionEvent ;
import java . awt . event . ActionListener ;
import javax . swing . JButton ;
import javax . swing . JFrame ;
import javax . swing . JPanel ;
class MyFrame extends JFrame implements ActionListener {
private JButton btn;
public MyFrame () {
this . setSize ( 300 , 200 );
this . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );
JPanel panel = new JPanel() ;
btn = new JButton( "버튼" ) ;
btn . addActionListener ( new ActionListener() {
public void actionPerformed ( ActionEvent e) {
if ( e . getSource () == btn) {
btn . setText ( "클릭됨" );
}
}
});
panel . add (btn);
this . add (panel);
this . setVisible ( true );
}
}
public class TestCS {
public static void main ( String [] args) {
MyFrame f = new MyFrame() ;
}
}
이벤트의 분류
모든 Component가 지원하는 이벤트
일부 Component가 지원하는 이벤트
Action Event
사용자가 텍스트 필드에서 엔터키를 누르는 경우
Copy import java . awt . Color ;
import java . awt . event . ActionEvent ;
import java . awt . event . ActionListener ;
import javax . swing . JButton ;
import javax . swing . JFrame ;
import javax . swing . JPanel ;
class MyFrame extends JFrame {
private JButton btnYellow , btnPink;
private JPanel panel;
public MyFrame () {
this . setSize ( 300 , 200 );
this . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );
panel = new JPanel() ;
btnYellow = new JButton( "Yellow" ) ;
btnYellow . addActionListener ( new MyListener() );
panel . add (btnYellow);
btnPink = new JButton( "Pink" ) ;
btnPink . addActionListener ( new MyListener() );
panel . add (btnPink);
this . add (panel);
this . setVisible ( true );
}
private class MyListener implements ActionListener {
public void actionPerformed ( ActionEvent e) {
if ( e . getSource () == btnYellow) {
panel . setBackground ( Color . YELLOW );;
} else if ( e . getSource () == btnPink) {
panel . setBackground ( Color . PINK );;
}
}
}
}
public class TestCS {
public static void main ( String [] args) {
MyFrame f = new MyFrame() ;
}
}
getSource()
메소드를 이용해 이벤트를 발생시킨 객체를 식별한다.
getId()
메소드를 이용해 이벤트의 타입을 식별한다.
getActionCommand()
메소드를 이용해 이벤트를 발생시킨 컴포넌트의 이름을 식별한다.
Key Event
keyListener
인터페이스를 구현한다.
Copy import java . awt . event . KeyEvent ;
import java . awt . event . KeyListener ;
import javax . swing . JFrame ;
import javax . swing . JPanel ;
import javax . swing . JTextField ;
public class KeyEventPractice extends JFrame implements KeyListener {
public KeyEventPractice () {
this . setSize ( 300 , 300 );
this . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );
JTextField tf = new JTextField( 20 ) ;
tf . addKeyListener ( this );
this . add (tf);
this . setVisible ( true );
}
@ Override
public void keyTyped ( KeyEvent e) {
// TODO Auto-generated method stub
display(e , "key typed" ) ;
}
@ Override
public void keyPressed ( KeyEvent e) {
display(e , "key pressed" ) ;
// TODO Auto-generated method stub
}
@ Override
public void keyReleased ( KeyEvent e) {
// TODO Auto-generated method stub
display(e , "key Released" ) ;
}
private void display ( KeyEvent e , String string) {
// TODO Auto-generated method stub
char c = e . getKeyChar ();
int keyCode = e . getKeyCode ();
String modifiers = e . isAltDown () + " " + e . isControlDown () + " " + e . isShiftDown ();
System . out . println (string + " " + c + " " + keyCode + " " + modifiers);
}
}
Mouse 이벤트
Copy import java . awt . event . MouseEvent ;
import java . awt . event . MouseListener ;
import java . awt . event . MouseMotionListener ;
import javax . swing . JFrame ;
import javax . swing . JPanel ;
public class MouseEventPractice extends JFrame implements MouseListener {
MouseEventPractice (){
this . setSize ( 300 , 300 );
this . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );
JPanel panel = new JPanel() ;
panel . addMouseListener ( this );
add(panel) ;
setVisible( true ) ;
}
@ Override
public void mouseClicked ( MouseEvent e) {
// TODO Auto-generated method stub
display( "Mouse clicked (# of clicks: " + e . getClickCount() + ")" , e) ;
}
@ Override
public void mousePressed ( MouseEvent e) {
// TODO Auto-generated method stub
display( "Mouse pressed (# of clicks: " + e . getClickCount() + ")" , e) ;
}
@ Override
public void mouseReleased ( MouseEvent e) {
// TODO Auto-generated method stub
display( "Mouse released (# of clicks: " + e . getClickCount() + ")" , e) ;
}
@ Override
public void mouseEntered ( MouseEvent e) {
// TODO Auto-generated method stub
display( "Mouse entered" , e) ;
}
@ Override
public void mouseExited ( MouseEvent e) {
// TODO Auto-generated method stub
display( "Mouse exited" , e) ;
}
protected void display ( String s , MouseEvent e) {
System . out . println (s + " X=" + e . getX () + " Y=" + e . getY ());
}
}
Mouse의 좌표 얻기
참조 페이지