11.Swing
11.1개요
11.1.1기본개념
11.1.2스윙 컴포넌트 종류
11.1.3스윙 컴포넌트 계층도
11.1.4JComponent
11.2최상위 컨테이너
11.2.1개요
11.2.2프레임
11.2.3대화상자
11.2.4애플릿
11.3레이아웃 관리자
11.3.1개요
11.3.2사용법
11.3.3커스텀 레이아웃
11.4중간 단계 컨테이너
11.4.1패널(JPanel)
11.4.2스크롤창(JScrollPane)
11.4.3스플릿창(JSplitPane)
11.4.4탭창(JTabbedPane)
11.4.5툴바(JToolBar)
11.4.6내부 프레임(JInternalFrame)
11.4.7.1투명창(GlassPane)
11.4.7.2다층창(JLayeredPane)
11.4.7.3메뉴바(JMenuBar)
11.5Event Model
11.5.1Delegation Model
11.5.2Listener
11.5.3Adapter
11.6Componets
11.6.1버튼(JButton, JToggleButton)
11.6.2체크박스(JCheckBox)
11.6.3라디오 버튼(JRadioButton)
11.6.4색상 선택 상자(JColorChooser)
11.6.5콤보박스
11.6.6파일 선택 대화상자
11.6.7레이블
11.6.8목록
11.6.10진행 상태바
11.6.11슬라이더
11.6.12테이블
11.6.13텍스트
11.6.14텍스트 필드
11.6.15툴팁
11.6.16트리
11.Swing
11.1개요
11.1.1기본개념
C:\j2sdk1.4.0\demo\jfc\SwingSet2\SwingSet2.html
Swing 컴포넌트는 AWT(Abstract Window Toolkit) 컴포넌트를 기반으로 만든 JFC(Java Foundation Classes)의 일부분이다. 또한, AWT 컴포넌트와 Swing 컴포넌트는 프로그램의 GUI(graphical user interface)를 만들기 위한 자바 API다. 컴포넌트라 불리는 이유는 AWT, Swing API 모두 Component 클래스를 상속받기 때문이다.
JFC는 아래의 기능을 포함한다.
1)Swing 컴포넌트
2)Pluggable Look and Feel 지원
3)Accessibility API
4)Java 2DTM API
5)Drag and Drop 지원
AWT만으로도 완전한 GUI를 만들 수 있지만 Swing으로만 GUI를 만들도록 권장한다.
AWT와 Swing의 주요한 차이는 아래와 같다.
1)AWT 패키지는 java.awt이고, Swing 패키지는 javax.swing이다(eXtention)
2)AWT와는 달리 Swing 컴포넌트는 특정 플랫폼에 의존적인 코드가 없다
3)Swing은 버튼과 레이블에 이미지도 표시할 수 있다
4)Swing은 직사각형 외의 외양을 갖을 수 있다
Swing 프로그램을 만들 때 주의할 점은 아래와 같다.
1)AWT 컴포넌트와 혼용하지 않는다. 대부분의 AWT 컴포넌트는 중량 컴포넌트고, Swing 컴포넌트는 경량 컴포넌트다. 항상 중량 컴포넌트가 경량 컴포넌트의 상위에 그려지므로 혼용하게 되면 겹쳐서 그릴 수 없다.
2)스윙 컴포넌트의 실현(show(), setVisible(true), pack()) 후에 발생하는 컴포넌트 상태를 변경하는 코드는 반드시 이벤트 처리 부분에서 실행해야 한다.(repaint(), revalidate() 제외)
3)스윙 컴포넌트 컨테이너의 상위에는 스윙 컴포넌트 최상위 컨테이너가 있어야 한다.
자바의 GUI 프로그램
GUI 설계(Graphic User Interface) + 프로그램 로직(Business Logic) + 이벤트 처리
GUI의 좌표체계
그래픽 시스템의 좌표체계는 아래의 그림과 같이 왼쪽 상단(0, 0)에서 오른쪽, 아래로 해상도 만큼 픽셀단위로 증가한다.
(0, 0)![]()
11.1.2스윙 컴포넌트 종류
|
최상위 컨테이너(Top-Level Containers) | ||
|
|
|
|
|
JFrame |
|
JApplet |
|
중간단계 컨테이너(General-Purpose Containers) | ||
|
|
|
|
|
JPanel |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
중간단계 컨테이너(Special-Purpose Containers) | ||
|
|
|
|
|
|
Layered pane |
|
|
Editable Displays of Formatted Information | ||
|
|
|
|
|
|
JFileChooser |
JTable |
|
|
|
|
|
JTextArea |
JTree |
|
|
Basic Controls(컴포넌트) | ||
|
|
|
|
|
JButton |
JToggleButton |
JCheckBox |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Borders |
|
|
|
Uneditable Information Displays | ||
|
|
|
|
|
|
|
|
11.1.3스윙 컴포넌트 계층도
![]()
Component Hierarchy: Part 1--AWT Similar
![]()
Component Hierarchy: Part 2--New And Expanded Components
11.1.4JComponent
JComponent 클래스는 최상위 컨테이너를 제외한 거의 모든 스윙 컴포넌트의 선조 클래스다.
java.lang.Object
|
+--java.awt.Component
|
+--java.awt.Container
|
+--javax.swing.JComponent
Component에는 레이아웃, 페인팅, 이벤트 지원등 컴포넌트에 필요한 기본 기능이 있고, Container에는 컨테이너에 컴포넌트를 추가, 배치 등의 기능이 있다.
JComponent의 주요 기능은 아래와 같다.
툴팁(풍선 도움말)
테두리
키보드 액션
외양
속성
레이아웃
더블 버퍼링
아래는 JComponent 클래스의 주요 메서드다.
|
자료형 |
메서드 / 설명 |
|
그리기 관련 | |
|
void void
void
void void void void |
Component.repaint() repaint(Rectangle r) 컴포넌트 전체 또는 일부를 다시 그리도록 update(Graphics g)를 호출을 요청 revalidate() 컴포넌트의 레이아웃 재배치를 요청 paintComponent(Graphics g) paintBorder(Graphics g) paintChildren(Graphics g) // 상속:선조,후손 Swing:부모,자식 paint(Graphics g) |
|
자료형 |
메서드 / 설명 |
|
모양 관련 | |
|
void Border void boolean
void Color void Color void Font FontMetrics |
setBorder(Border border) getBorder() setOpaque(boolean isOpaque) isOpaque() 불투명한 컴포넌트는 자신의 배경을 배경색으로 채운다 setForeground(Color fg) Component.getForeground() setBackground(Color bg) Component.getBackground() setFont(Font font) Component.getFont() Component.getFontMetrics(Font font) 폰트 관련 정보를 얻을 수 있다 |
|
자료형 |
메서드 / 설명 |
|
상태 관련 | |
|
void boolean
void void boolean
void Cursor |
setVisible(boolean aFlag) isVisible() 최상위 컨테이너를 제외한 컴포넌트는 기본으로 화면에 보인다 setToolTipText(String text) setEnabled(boolean enabled) Component.isEnabled() 사용자 입력에 반응할 수 있고 이벤트를 발생 시킬 수 있다 setCursor(Cursor cursor) Component.getCursor() |
|
자료형 |
메서드 / 설명 |
|
컨테이너 관련 | |
|
Component void RootPane Container |
Container.add(Component comp) Container.remove(Component comp) getRootPane() getParent() 컴포넌트를 포함하는 컨테이너를 얻는다 |
|
자료형 |
메서드 / 설명 |
|
레이아웃 관련 | |
|
void
void void void |
Container.setLayout(LayoutManager mgr) 레이아웃을 설정 setPreferredSize(Dimension preferredSize) setAlignmentX(float alignmentX) setAlignmentY(float alignmentY) X, Y축 정렬을 설정 Component.CENTER_ALIGNMENT Component.BOTTOM_ALIGNMENT Component.LEFT_ALIGNMENT Component.RIGHT_ALIGNMENT Component.TOP_ALIGNMENT |
|
자료형 |
메서드 / 설명 |
|
크기, 위치 관련 | |
|
int int Dimension void
int int Rectangle void Point void
Point
Insets |
getWidth() getHeight() getSize(Dimension rv) Component.setSize(Dimension size) 컴포넌트의 크기를 픽셀 단위로 설정하고 얻는다 getX() getY() getBounds(Rectangle rv) Component.setBounds(Rectangle bounds) getLocation(Point rv) setLocation(Point loc) 부모 컨테이너 왼쪽 최상위로부터 컴포넌트의 위치를 설정하고 얻는다 Component.getLocationOnScreen() 스크린 왼쪽 최상위로부터 컴포넌트의 위치를 얻는다 getInsets(Insets rv) 컴포넌트의 밖 여백을 얻는다 |
아래는 관련 클래스와 메서드다
|
자료형 |
메서드 / 설명 |
|
java.awt.Rectangle | |
|
|
Rectangle(int x, int y, int width, int height) Point getLocation() Dimension getSize() |
|
java.awt.Dimension | |
|
|
Dimension(int width, int height) double getHeight() double getWidth() |
|
java.awt.Point | |
|
|
Point(int x, int y) double getX() double getY() |
|
java.awt.Insets | |
|
|
Insets(int top, int left, int bottom, int right) |
|
java.awt.Color | |
|
|
Color(int r, int g, int b) 0-255 Color.red, Color.green, Color.blue, Color.white, Color.black ... |
11.2최상위 컨테이너
11.2.1개요
스윙의 최상위 컨테이너 클래스로 JFrame, JDialog, JApplet이 있다.
컴포넌트가 화면에 나타나기 위해서는 포함관계 계층에 포함되어야 하고, 포함관계 계층의 루트에는 최상위 컨테이너가 있다.
![]()
포함관계 계층
컨테이너는 다른 컨테이너나 컴포넌트를 포함한다. 이러한 포함관계를 계층으로 나타낸 것이 포함관계 계층이다.
최상위 컨테이너는 하나의 내용창을 갖는다. 보여질 대부분의 컴포넌트는 내용창안에 추가된다
메뉴바는 내용창 밖, 최상위 컨테이너에 추가된다
![]()
![]()
11.2.2프레임
프레임이란 테두리, 제목줄, 윈도우 아이콘/최소/종료 버튼 등의 요소들을 갖는 윈도우다. 스윙 어플리케이션은 최소 하나의 프레임을 갖는다. 스윙에서는 JFrame 클래스를 제공한다. 다른 윈도우에 포함되는 윈도우는 내부 프레임을 사용한다.
java.awt.Container
|
+--java.awt.Window
|
+--java.awt.Frame
|
+--javax.swing.JFrame
아래는 JFrame 클래스의 주요 메서드다.
|
자료형 |
메서드 / 설명 |
|
생성자 | |
|
|
JFrame(String name) name은 프레임의 이름 |
|
자료형 |
메서드 / 설명 |
|
기타 | |
|
Container void JRootPane Component JLayeredPane void JMenuBar |
getContentPane() setContentPane(Container content) getRootPane() getGlassPane() getLayeredPane() setJMenuBar(JMenuBar menubar) getJMenuBar() |
![]()
JFrame이 하는 주요한 일은 아래와 같다.
내용창을 얻기
frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
메뉴바 추가
frame.setJMenuBar(cyanMenuBar);
프레임 크기 지정
frame.pack();
프레임 보이기
frame.setVisible(true);
프레임을 이벤트 리스너에 등록
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TopLevelDemo {
public static void main(String s[]) {
JFrame frame = new JFrame("TopLevelDemo");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JLabel yellowLabel = new JLabel("라벨");
yellowLabel.setOpaque(true);
yellowLabel.setBackground(Color.yellow);
yellowLabel.setPreferredSize(new Dimension(200, 180));
JMenuBar cyanMenuBar = new JMenuBar();
cyanMenuBar.setOpaque(true);
cyanMenuBar.setBackground(Color.cyan);
cyanMenuBar.setPreferredSize(new Dimension(200, 20));
frame.setJMenuBar(cyanMenuBar);
frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
11.2.3대화상자
JOptionPane, JDialog
11.2.3대화상자
표준 대화상자는 JOptionPane을 커스텀 대화상자는 JDialog를 사용한다.
대화상자는 모달(modal)과 비모달(modeless)로 분류한다. 모달은 대화상자가 닫혀야 다른 윈도우가 사용자 입력을 받을 수 있다. 비모달은 JDialog를 이용한다.
JDialog는 JFrame을 사용하는 것과 비슷한 방법을 사용한다.
JOptionPane은 내부적으로 JDialog를 생성하고 자신을 JDialog의 내용창으로 추가한다.
1)JOptionPane
javax.swing.JComponent
|
+--javax.swing.JOptionPane
아래는 JOptionPane 클래스의 주요 메서드다.
|
자료형 |
메서드 / 설명 |
|
생성자 | |
|
|
JOptionPane(Object message, int messageType, int optionType, Icon icon, Object[] options, Object initialValue) 매개변수는 모두 생략가능 message - 표현될 객체(보통 문자열) messageType - ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, PLAIN_MESSAGE optionType - DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION, OK_CANCEL_OPTION icon - 아이콘 이미지 options - 사용자가 선택할 수 있는 옵션(보통 문자열) initialValue - 초기 선택된 옵션 |
|
대화상자 표시 | |
|
static void |
showMessageDialog(Component parentComponent, Object message, String title, int messageType, Icon icon) messageType에 따른 대화상자, title부터 생략가능 parentComponent - 대화상자가 표시될 프레임, null이면 기본 프레임 사용 title - 대화상자 제목 |
|
static int |
showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon) optionType에 따른 대화상자, title부터 생략가능 선택된 option을 반환 |
|
static int |
showOptionDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object initialValue) options에 따른 대화상자 선택된 option을 반환 |
|
static Object
static String |
showInputDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[] selectionValues, Object initialSelectionValue) selectionValues에 따른 대화상자, 선택된 Object를 반환 showInputDialog(Object message, Object initialSelectionValue) 사용자 입력을 요구하는 대화상자, 입력된 문자열을 반환 |
// DialogDemo.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogDemo {
public static void main(String s[]) {
JFrame frame = new JFrame("TopLevelDemo");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setVisible(true);
JOptionPane.showMessageDialog(null, "alert", "ALERT", JOptionPane.ERROR_MESSAGE);
//Show an information panel with the options yes/no and message 'choose one':
JOptionPane.showConfirmDialog(null, "choose one", "CHOOSE ONE", JOptionPane.YES_NO_OPTION);
//Show a warning dialog with the options OK, CANCEL, title 'Warning', and message 'Click OK to continue':
Object[] options = { "OK", "CANCEL" };
JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
null, options, options[0]);
//Show a dialog asking the user to type in a String:
String inputValue = JOptionPane.showInputDialog("Please input a value");
System.out.println(inputValue);
//Show a dialog asking the user to select a String:
Object[] possibleValues = { "First", "Second", "Third" };
Object selectedValue = JOptionPane.showInputDialog(null,
"Choose one", "Input",
JOptionPane.INFORMATION_MESSAGE, null,
possibleValues, possibleValues[0]);
System.out.println(selectedValue);
/*
*/
}
}
![]()
![]()
![]()
![]()
![]()
2)JDialog
java.awt.Container
|
+--java.awt.Window
|
+--java.awt.Dialog
|
+--javax.swing.JDialog
11.2.4애플릿
java.awt.Container
|
+--java.awt.Panel
|
+--java.applet.Applet
|
+--javax.swing.JApplet
이후 애플릿 장에서 설명
11.3레이아웃 관리자
11.3.1개요
레이아웃 관리자는 LayoutManager 인터페이스를 구현한 클래스의 객체를 말한다. 모든 컨테이너는 각각의 기본 레이아웃 관리자를 갖는다. 필요에 따라 기본 레이아웃 관리자를 바꿀 수 있다.
레이아웃 관리자의 종류는 아래와 같다
BorderLayout : 모든 내용창의 기본 레이아웃 관리자다
BoxLayout
CardLayout
FlowLayout : JPanel의 기본 레이아웃 관리자다
GridLayout
GridBagLayout
11.3.2사용법
변경하고자하는 레이아웃 관리자 객체를 생성하고, 변경하려는 컨테이너 객체를 이용하여 생성된 레이아웃 관리자 객체로 레이아웃을 설정하면 된다.
frame.getContentPane().setLayout(new FlowLayout());
컨테이너의 모양이 변하면 자동으로 레이아웃 관리자가 호출된다. 컴포넌트의 모델이 변경하여 자동으로 갱신되지 않는다면 컴포넌트에 대해 직접 revalidate() 메서드를 호출한 후 repaint() 메서드를 호출해야 한다.
BorderLayout
BorderLayout은 중앙, 동, 서, 남, 북 다섯 개의 영역이 있다.
내용창은 기본으로 BorderLayout 이므로 아래와 같이 이용할 수 있다.
public void Container.add(Component comp, Object constraints)
frame.getContentPane().add(new JButton("북“), BorderLayout.NORTH);
BorderLayout.CENTER
BorderLayout.NORTH
BorderLayout.SOUTH
BorderLayout.EAST
BorderLayout.WEST
만약 BorderLayout.CENTER에만 컴포넌트가 있다면 전체를 채운다.
기본으로 각 영역의 크기는 영역에 추가된 컴포넌트의 크기로 결정된다. 또한, 추가할 컴포넌트의 setPreferredSize()를 이용하여 각 영역의 선호하는 크기를 지정할 수 있다.
/*
* Swing version.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BorderWindow extends JFrame {
boolean inAnApplet = true;
public BorderWindow() {
Container contentPane = getContentPane();
//Use the content pane's default BorderLayout.
//contentPane.setLayout(new BorderLayout()); //unnecessary
JButton north = new JButton("Button 1 (NORTH)");
north.setPreferredSize(new Dimension(0, 18)); // 0은 의미 없음
JButton west = new JButton("Button 3 (WEST)");
west.setPreferredSize(new Dimension(20, 0));
contentPane.add(north, BorderLayout.NORTH);
contentPane.add(new JButton("2 (CENTER)"), BorderLayout.CENTER);
contentPane.add(west, BorderLayout.WEST);
contentPane.add(new JButton("Long-Named Button 4 (SOUTH)"), BorderLayout.SOUTH);
contentPane.add(new JButton("Button 5 (EAST)"), BorderLayout.EAST);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
if (inAnApplet) {
dispose();
} else {
System.exit(0);
}
}
%
이올린에 북마크하기
이올린에 추천하기
