Swing으로 GUI만들기

Objective
- JDK 1.2에서는 JFC를 제공하고 있다.
- JFC의 한 부분으로 100% pure Java로 구현한 Swing이라는 새로운 Component를 제공하고 있다.
- JFC에 대한 간단한 소개와
- Swing package에 대한 소개를 하고,
- Swing component에 대한 정의와
- container와 component를 정의하고, SwingGUI를 만들기 위해서 어떻게 상호간에 동작하는 가를 보고,
- 간단한 Swing application을 compile하고 실행시켜 본다.
- JComponent Class의 주요한 특징
JFC란?
- 앞의 강의에서 배웠던 JDK 1.1 의 GUI인 AWT를 확장한 것으로 AWT기반의 Application과 완전히 호환되는 그래픽 사용자 인터페이스(GUI) 클래스 라이브러리를 추가한 것이다. JFC는 다음과 같이 구성이 되어 있다.
AWT |
앞의 강의에서 배웠던 것처럼 Java application에 있어서 광범위하게 사용되는 GUI tools을 제공한다. |
Swing 1.0 |
platform 독립적으로 보여질 수 있는 GUI를 만들기 위한 많은 component와 framework을 제공한다. 즉, form-based application 개발을 위해서 설계되었다. |
Drag and Drop |
Java application과 non-java application간의 데이터를 공유하는 것으로 MIME 기반의 확장 가능한 데이터 타입 시스템을 사용해서 가능하게 했다 |
Java 2D class library |
컬러 제어, 라인아트, 이미지 프로세싱, 스타일드 텍스트등을 다룰수 있다. |
Accessibility |
비 전통적인 입출력을 사용하는 application 개발을 돕기 위한 도구를 제공한다. 이 api를 사용해서, screen readers, screen magnifiers, audible text readers같은 보조적인 기술에 대한 interface를 제공한다. |
Swing에 대해서
Swing의 이점
- Swing component는 Beans이다. 그렇기 때문에 Beans를 지원하는 모든 개발환경에서 사용할 수 있다.
- Swing은 대부분의 UI component를 제공한다.
- 속도의 측면에서도 모든 component는 lightweight이다.
- Swing은 portability의 측면에 있어서도 전부 자바로 작성되어졌기 때문에 충분히 만족한다.
- Keyboard의 이동을 자동으로 구현을 해 준다. - 기존의 AWT는 특별한 code가 필요하다.
- Scrolling의 지원은 큰 노력이 필요하지 않다. 단지 JScrollPane에 component를 add하면 된다.
- Swing은 "pluggable look and feel"을 지원한다. UI의 appearance를 현재 작업하고있는 platform에 상관없이 동적으로 바꿀 수 있다.
Pluggable Look and Feel
- 앞의 강의에서 배웠던 JDK 1.1의 AWT를 사용하면, 아래의 그림 중에서 1) 혹은 2) 모습이다. (Win95환경경우는 1), Motif환경의 경우는 2).
- Swing을 사용하면, 사용자가 사용자의 마음에 드는 디자인과 인터페이스를 제공할 수 있도록 Programing을 할 수가 있다. 이와 같은 것을 pluggable look and feel(교체 가능한 룩앤필)이라고 한다.
- 기존의 환경에서, 그리고, JDK1.1에서 제공하는 AWT를 사용할 때는 하나의 디자인과 인터페이스를 가지고 있어서 그것을 따를 수밖에 없었다. Swing을 이용하면, 사용자가 다양한 look and feel을 선택하거나 프로그램 상황에 맞게[ 룩앤필을 정해놓고 사용할 수 있다.
Swing vs AWT
- Swing component는 JDK 1.1에서의 AWT component와 마찬가지로 경량(light weight)component 이지만, 더 많은 component를 제공하며, 이들은 많은 새로운 형태의 기능을 수행하게 한다.
Swing과 AWT과의 차이점
Swing과 AWT 간의 가장 큰 차이점은
- Swing component는 수행될 때, 플랫폼으로부터 어떠한 native code도 가져다 쓰지 않는 다는 것이다. 다시 말해서 swing은 전혀 platform 종속적인 수행을 하지 않는 다는 것이다. 그리고 대신에 직접 작성된 교체 가능한 Look and Feel을 사용한 자신의 component를 만들었다.
- AWT component는 사용자의 입력에 응답하고 그들 자신을 표현하기 위해 peer 형태로 native code에 의존하지만, Swing component는 순수하게 자바로 쓰여졌다는 점이 차이가 난다. Swing component는 자신과 이벤트를 처리하기 위해 UI Object라 불리는 것을 사용하는데, 이 UI object 또한 순수 자바로 작성돼 있다. 이것은 앞서 말한 pluggable Look and Feel 형태를 지원한다.
※ 즉, Swing compont는 native code에 의존하지 않고, 특정 플랫폼에 제한되어 있지 않아서 AWT보다 강력한 기능을 가진다 그래서 Swing은 텍스트와 애니메이션을 포함한 이미지들을 나타낼 수 있다.
Swing Hierarchy
Swing Component
다음은 Swing 제공하는 Component이다.
javax.swing.* package
스윙 패키지 |
주 요 기 능 |
javax.swing |
기본적인 스윙 컴포넌트 클래스를 정의 |
javax.swing.border |
스윙의 경계선(border) 특징을 지정하는 클래스 |
javax.swing.colorchooser |
스윙에서 색의 선택 기능을 제공 |
javax.swing.event |
스윙에서 필요로 하는 이벤트 타입과 리스너를 정의 |
javax.swing.filechooser |
파일 선택 기능을 제공하기 위한 클래스 및 인터페이스를 제공 |
javax.swing.plaf |
스윙의 look-and-feel에 관련된 클래스 및 인터페이스를 제공 |
javax.swing.plaf.basic |
기본적인 look-and-feel에 관련된 UI 객체 생성을 지원 |
javax.swing.plaf.metal |
metal look-and-feel에 관련된 UI 객체 생성을 지원 |
javax.swing.plaf.multi |
복합 look-and-feel에 관련된 UI 객체 생성을 지원 |
javax.swing.table |
스윙의 테이블 관련 클래스를 정의 |
javax.swing.text |
스윙의 텍스트 관련 클래스를 정의 |
javax.swing.text.html |
텍스트 에디터를 만들기 위한 클래스를 제공 |
javax.swing.text.html.parser |
html 문서의 parser 기능을 제공 |
javax.swing.text.rtf |
Rich-Text-Format과 관련된 에디터를 만들기 위한 클래스 제공 |
javax.swing.tree |
스윙의 트리 작성에 필요한 클래스를 제공 |
javax.swing.undo |
텍스트 에디터와 같은 어플리케이션에서 undo/redo 기능을 제공 |
AWT Component와 Swing Component의 비교
AWT의 컴포넌트 |
스윙 컴포넌트 |
Frame |
JFrame |
Panel |
JPanel |
Button |
JButton |
TextField |
JTextField |
TextArea |
JTextArea |
List |
JList |
Choice |
JCombo |
Checkbox |
JCheckbox |
Label |
JLabel |
Dialog |
JDialog |
FileDialog |
JFileChooser |
ScrollPane |
JScrollPane |
MenuBar |
JMenuBar |
Menu |
JMenu |
MenuItem |
JMenuItem |
PopupMenu |
JPopupMenu |
Swing에서 새롭게 추가된 Component
스윙 컴포넌트 |
기 능 |
JProgressBar |
어떤 작업의 진행정도를 그래픽하게 보여준다 |
JSlider |
숫자의 입력을 슬라이드로 할 수 있게 한다 |
JToolBar |
메뉴와 비슷하나 floating될 수 있다(도구상자 등) |
JTable |
편리한 테이블 작성을 지원한다 |
JTabbedPane |
제목이 있는 여러 화면을 겹치게 구성한다 |
JSplitPane |
pane을 두영역으로 나눈다 |
JInternalFrame |
프레임 내에 프레임을 만든다 |
JLayeredPane |
여러 장의 화면을 중첩할 수 있게 한다 |
JTree |
트리 구조로 항목을 나열한다(디렉토리 구조 등) |
JColorChooser |
Color를 선택할 수 있게 한다 |
JToggleButton |
버튼이 on, off 상태를 가진다 |
AWT에서의 버튼과 Swing의 버튼 비교
'
- // AWT의 Button 생성 프로그램 ----------------
- import java.awt.*;
- public class Test {
- public void go() {
- Frame frame = new Frame("Button Test");// 프레임 생성
- Panel panel = new Panel();// 패널 생성
- Button button = new Button("Button Test");// 버튼 생성
- panel.add(button);
- frame.add(panel);
- frame.setSize(300,100);
- frame.setVisible(true);
- }
- public static void main(String args[]) {
- new Test().go();
- }
- public void go() {
- }
- // 스윙의 JButton 생성 프로그램 ----------------
- import java.awt.*;
- import javax.swing.*;
- public class Test {
- public void go() {
- JFrame frame = new JFrame("JButton Test");// 프레임 생성
- JPanel panel = new JPanel();// 패널 생성
- JButton button = new JButton("JButton Test");// 버튼 생성
- panel.add(button);
- frame.getContentPane().add(panel);
- frame.setSize(300,100);
- frame.setVisible(true);
- }
- public static void main(String args[]){
- new Test().go();
- }
- public void go() {
- }
크게 달라진점 3가지
- 스윙에서는 import javax.swing.* 이 필요함
- 스윙 컴포넌트 클래스의 이름의 변경됨 (Button -> JButton)
- 스윙 컴포넌트를 프레임에 직접 추가하지 못하고 content pane에 추가 해야 함
- 다음은 Component들 중에 기본이 되는 component에 대한 간단한 예제와 그 실행의 예이다. 다음의 예를 살펴보면서 중요한 부분과 특징을 살펴 볼 수 있다
JButton
- import java.awt.*;
- import javax.swing.*;
- import javax.swing.plaf.basic.*;
- import javax.swing.border.*;
- public class Test {
- public void go() {
- JButton button = new JButton("JButton");
- JPanel panel1 = new JPanel();
- JPanel panel2 = new JPanel();
- BasicArrowButton up =
- new BasicArrowButton(BasicArrowButton.NORTH);
- BasicArrowButton down =
- new BasicArrowButton(BasicArrowButton.SOUTH);
- BasicArrowButton right=
- new BasicArrowButton(BasicArrowButton.WEST);
- BasicArrowButton left =
- new BasicArrowButton(BasicArrowButton.EAST);
- panel2.add(up);
- panel2.add(down);
- panel2.add(right);
- panel2.add(left);
- panel2.setBorder(new TitledBorder("Basic Arrow Button"));
- JToggleButton toggle = new JToggleButton("Toggle");
- JRadioButton radio = new JRadioButton("Radio");
- panel1.add(button);
- panel1.add(panel2);
- panel1.add(toggle);
- panel1.add(radio);
- JFrame frame = new JFrame("JButton Test");
- frame.getContentPane().add(panel1);
- frame.setSize(400,100);
- frame.setVisible(true);
- }
- public static void main(String args[]) {
- new Test().go();
- }
- public void go() {
- }
Borders
- 스윙에서는 모든 컴포넌트의 경계선을 다양하게 표현할 수 있다. 이 경계선을 표현하기 위해서 아래의 메쏘드를 사용하고 경계선의 종류는 다음과 같다.
- public void setBorder(Border bd);
- Border class
- TitledBorder("Title")
- EtchedBorder();
- LineBorder(Color.blue)
- MatteBorder(5,5,30,30,Color.green);
- BevelBorder(BevelBorder.LOWERED)
- CompoundBorder(new EtchedBorder(),new LineBorder(Color.red))
Tool Tips
- 컴포넌트 위에 마우스가 오면 간단한 설명문을 보여주는 기능을 Tool Tips라고 한다. 어떤 컴포넌트가 Tool Tips를 제공하도록 하려면 다음과 같은 메소드를 호출하면서 간단한 설명문의 내용을 스트링 타입의 인자 s로 주면 된다.
public void setToolTipText(String s);
아래에 버튼에 Tool Tips를 지정하는 예와 해당 프로그램 보였다.
- import java.awt.*;
- import javax.swing.*;
- public class Test {
-
- public void go() {
- JButton button = new JButton("button");
- JPanel panel = new JPanel();
- button.setToolTipText("Tool Tip Test");
- panel.add(button);
- JFrame frame = new JFrame("ToolTip Test");
- frame.getContentPane().add(panel);
- frame.setSize(150,100);
- frame.setVisible(true);
- }
- public static void main(String args[]) {
- new Test().go();
- }
- public void go() {
- }
Button Groups
- "exclusive or" 형태의 동작을 하는 radio button은 button group에 더할 수 있다. 그리고, 예전의 awt보다는 훨씬 자유스러운 것을 알 수 있다. 아래의 예제에서는 abstract button을 button Group에 더하는 예이다.
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
- import javax.swing.border.*;
- public class ButtonGroups extends JPanel{
-
- public ButtonGroups(){
- ButtonGroup bg1 = new ButtonGroup();
- ButtonGroup bg2 = new ButtonGroup();
- JPanel jp1 = new JPanel();
- JPanel jp2 = new JPanel();
- jp1.setBorder(new TitledBorder("JButton Group"));
- JButton jb1= new JButton("JButton1");
- JButton jb2= new JButton("JButton2");
- JButton jb3= new JButton("JButton3");
- JButton jb4= new JButton("JButton4");
- jp1.add(jb1);
- bg1.add(jb1);
- jp1.add(jb2);
- bg1.add(jb2);
- jp1.add(jb3);
- bg1.add(jb3);
- jp1.add(jb4);
- bg1.add(jb4);
- add(jp1);
- jp2.setBorder(new TitledBorder("JToggleButton Group"));
- JToggleButton JT1 =new JToggleButton ("JToggleButton1");
- JToggleButton JT2 =new JToggleButton ("JToggleButton2");
- JToggleButton JT3 =new JToggleButton ("JToggleButton3");
- JToggleButton JT4 =new JToggleButton ("JToggleButton4");
- jp2.add(JT1);
- bg2.add(JT1);
- jp2.add(JT2);
- bg2.add(JT2);
- jp2.add(JT3);
- bg2.add(JT3);
- jp2.add(JT4);
- bg2.add(JT4);
- add(jp2);
- }
- public static void main(String args[]){
- JFrame f = new JFrame();
- ButtonGroups bgt = new ButtonGroups();
- f.getContentPane().add(bgt);
- f.setSize(400,400);
- f.setVisible(true);
- }
- public ButtonGroups(){
- }
ListBox 와 ComboBox
- Swing에서의 List Box와 Combo Box는 예전의 AWT보다 더 많은 일을 할 수 있다. 그리고, 필요하다면, 사용할 수 있는 많은 함수를 가지고 있다.
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
- public class ListCombo extends JPanel{
-
- static String ids[] = {"June","Ward","Beaver","Wally","Eddie","Lumpy"};
- public ListCombo(){
- setLayout(new BorderLayout());
- JList list = new JList(ids);
- add(new JScrollPane(list), "Center");
- JComboBox combo = new JComboBox();
- for( int i =0; i <100 ; i++)
- combo.addItem(Integer.toString(i));
- add(combo,"South");
- }
- public static void main(String args[]){
- JFrame f = new JFrame();
- ListCombo list = new ListCombo();
- f.getContentPane().add(list);
- f.pack();
- f.setVisible(true);
- }
- }
실행결과
- JList는 자동으로 Scrolling을 제공하지 않기 때문에 List을 JScrollpane에 add한후 사용할 수 있다.
JSliders
- 슬라이더(JSlider)는 볼륨조절 등을 할 때와 같이 어떤 수치를 직접 입력하는 대신 그래픽으로 입력하는 기능을 제공한다. 슬라이더가 AWT의 스크롤바와 다른점은 스크롤바는 어떤 물체의 보이는 영역을 움직이는데 사용되고 슬라이더는 어떤 값을 입력하는데 사용된다는 것이다. (스윙에서는 스크롤바를 평면적으로 제공하기 위하여 JScrollPane 클래스를 제공하고 있다.)
- JSlider는 여러 형태의 생성자를 제공하는데 예를들어 다음과 같은 생성자에서 orientation은 수평 또는 수직방향을 나타내고 min은 슬라이더의 최소값을, max는 최대값을, value는 초기값을 각각 지정한다.
- JSlider(int orientation, int min, int max, int value)
- JSlider가 제공하는 주요 메소드는 다음과 같다.
- setMajorTickSpacing(int t)// 눈금의 간격을 지정
- getValue() // 현재의 슬라이더의 값을 읽음
- setValue() // 현재의 슬라이더의 값을 지정
- setPaintTicks(true)// 눈금을 나타냄
- setPaintLabels(true)// 눈금의 값을 나타냄
- addChangeListener(ChangeListener c) // 리스너 연결
- JSlider(int orientation, int min, int max, int value)
- 아래에는 0과 100 사이의 값을 입력하는 슬라이더와 해당 프로그램을 보였는데 현재의 슬라이더의 위치 값을 JTextField에 나타내고 있다. 슬라이드가 움직일 때 발생하는 이벤트를 익명클래스로 처리하고 있으며 리스너를 연결하기 위하여 addChangeListener() 메소드를 사용하고 있다.
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
- import javax.swing.event.*;
- public class SliderTest {
-
- JPanel panel = new JPanel();
- JTextField jtf = new JTextField(20);
- JSlider sd = new JSlider(JSlider.HORIZONTAL, 0, 100, 60);
- public void go() {
- panel.setLayout(new GridLayout(2, 1));
- panel.add(jtf);
- sd.setValue(0);
- sd.setMajorTickSpacing(20);
- sd.setMinorTickSpacing(5);
- sd.setPaintTicks(true);
- sd.setPaintLabels(true);
- sd.addChangeListener(new ChangeListener() {// 익명클래스
- public void stateChanged(ChangeEvent e) {
- jtf.setText("Position is "+ sd.getValue());
- }
- public void stateChanged(ChangeEvent e) {
- } );
- panel.add(sd);
- JFrame frame = new JFrame();
- frame.getContentPane().add(panel);// 프레임에 패널을 추가
- frame.setSize(200,200);
- frame.setVisible(true);
- }
- public static void main(String args[]) {
- new SliderTest().go();
- }
- }
JProgressBar
- JProgressBar는 어떤 작업의 진행정도를 그래픽하게 나타내는 데 사용된다. JProgressBar는 여러가지 생성자를 제공하는데, 예를들어 다음과 같은 생성자에서 orientation은 수평 또는 수직방향을 나타내고, min은 최소값을, max는 최대값을 각각 나타낸다.
- JProgressBar(int orientation, int min, int max)
- JProgressBar가 제공하는 주요 메소드는 다음과 같다.
- setValue(int) // JProgressbar의 값을 지정함
- getValue() // JProgressbar의 값을 읽음
- getPercentComplete() // JProgressbar의 값을 백분율로 읽음
- 아래는 앞에서 소ws개한 JSlider 응용 예제에 ProgressBar의 기능을 추가시킨 것인데, 슬라이더를 움직이면 슬라이더의 현재 값을 읽어 그림의 상단에 있는 JProgressBar에 그대로 나타내고 있다.
- 위와같은 결과를 얻기 위해 JSlider 예제의 Test 클래스에 추가되는 코드는 다음과 같다.
- JProgressBar jp = new JProgressBar();
- . . .
- public void go() {
- panel.setLayout(new GridLayout(3, 1));
- panel.add(jp);
- . . .
- sd.addChangeListener(new ChangeListener() {
- public void stateChanged(ChangeEvent e) {
- jtf.setText("Position"+sd.getValue());
- jp.setValue(sd.getValue());
- }
- public void stateChanged(ChangeEvent e) {
- . . .
JToolBar
- 툴바(JToolBar)는 메뉴와 유사한 기능을 제공하는 것으로, 화면 상단에 여러 도구상자 등을 나타내는데 사용될 수 있다. JToolBar는 인자 없는 생성자 한 가지만을 제공하고 있다. JToolBar가 제공하는 주요 메소드는 다음과 같다.
- add(Component c) // 컴포넌트를 툴바에 추가한다
- addSeparator() // 툴바에 경계선을 추가한다
- setFloatable(boolean b)// 툴바가 플로팅될 수 있는지를 지정한다
- isFloatable() // 툴바가 플로팅될 수 있는지 알아본다
- 툴바는 플로팅 기능을 제공하는데 이것은 화면에 나타난 툴바를 프레임에서 떼어 내어 화면상의 다른 곳으로 이동시킬 수 있는 기능이다. 아래의 좌측 그림은 툴바를 처음 만든 것이고 우측의 그림은 툴바 부분을 프레임에서 떼어 내어 다른 곳으로 움직인 결과이다. 이들을 구현하는 코드를 아래에 나타냈다.
- import javax.swing.*;
- import java.awt.*;
- public class ToolbarTest {
-
- public void go() {
- JPanel panel = new JPanel();
- JToolBar toolbar = new JToolBar();
- toolbar.setLayout(new GridLayout(1,3));
- JButton button1, button2, button3;
- button1 = new JButton(new ImageIcon("duke.gif"));
- button2 = new JButton(new ImageIcon("javalogo.gif"));
- button3 = new JButton("Button !!");
- toolbar.add(button1);
- toolbar.add(button2);
- toolbar.add(button3);
- panel.add(toolbar);
- JFrame frame = new JFrame();
- frame.getContentPane().add(panel,"North");
- frame.getContentPane().add(new JTextArea(),"Center");
- frame.setSize(180,150);
- frame.setVisible(true);
- }
- public static void main(String args[]) {
- new ToolbarTest().go();
- }
- public void go() {
- }
JMenu
- 스윙에서도 메뉴를 사용하려면 AWT에서와 같이 메뉴바를 먼저 만들고 메뉴를 메뉴바에 추가한 후, 메뉴항목들을 메뉴에 추가하여야 한다. 그러나 스윙의 메뉴 기능은 AWT보다 다양해졌는데, 예를들면 AWT에서와 달리 메뉴를 Panel이나 Applet에서도 사용할 수 있게 하였다(AWT에서는 프레임에만 사용할 수 있었음). 또한 메뉴항목에 텍스트 뿐 아니라 이미지도 넣을 수 있게 하였다.
- 아래에 그림이 들어있는 메뉴항목을 포함하여, 세개의 메뉴항목이 있는 메뉴를 만든 결과 그림과 이 결과를 얻는 프로그램을 나타냈다.
- import java.awt.*;
- import javax.swing.*;
- public class Test {
- public void go() {
- JFrame frame = new JFrame();
- JMenuBar jmenubar = new JMenuBar();// 메뉴바 생성
- frame.setJMenuBar(jmenubar);// 메뉴바 설치
- JMenu jmenu = new JMenu("Menu Test");// 메뉴 생성
- jmenubar.add(jmenu);// 메뉴 추가
- JMenuItem jm1, jm2, jm3;
- jm1 = new JMenuItem("Text Only");
- jm2 = new JMenuItem("Text and Icon", new
- ImageIcon("javalogo.gif"));
- jm3 = new JMenuItem(new ImageIcon("duke.gif"));
- jmenu.add(jm1);// 메뉴항목 추가
- jmenu.add(jm2);
- jmenu.add(jm3);
- frame.getContentPane().add(new JTextArea(), "Center");
- frame.setSize(200,100);
- frame.setVisible(true);
- }
- public static void main(String args[]) {
- new Test().go();
- }
- public void go() {
- }
JTable
- 스윙이 제공하는 기능 중 가장 편리한 기능이 아마 테이블(JTable)일 것이다. 특히 온라인으로 데이터베이스 처리를 하고 결과를 테이블 형태로 보여주면 편리한 경우가 많아 JTable이 널리 사용되고 있다.
- 예를들어 아래의 그림은 4x3의 테이블을 나타내고 있다.
- 위와같은 테이블을 만드는 코드를 아래에 보였다. 테이블의 내용을 담기 위하여 2차원 어레이를 사용하는데 먼저 4x3 어레이 tableData[4][3]을 정의하고 초기값을 주었다. 다음에 테이블 각 컬럼의 이름을 주기 위하여 스트링 타입의 어레이 column[3]를 만들고 이들을 사용하여 다음과 같이 테이블을 생성하였다.
- JTable table = new JTable(tableData, column)
- JTable table = new JTable(tableData, column)
- 아래 프로그램에서는 사용자가 테이블의 어떤 항목을 마우스로 클릭하면 그 항목의 내용을 테이블 상단에 있는 텍스트필드에 출력하도록 하였는데(위 그림에서는 Unix를 선택하고 있음), 이를 처리하기 위하여 MouseListener를 연결하였고 mouseClicked() 메소드를 구현하였다. mouseClicked()에서는 showMe()라는 메소드를 호출하는데 여기서 테이블의 선택된 항목을 읽어 텍스트필드에 출력한다.
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
- import javax.swing.event.*;
- import javax.swing.table.*;
- public class JTableTest {
- Object tableData[][] = {// 테이블 내용
- {new Integer(1), "Java Programming", "Electronics"},
- {new Integer(2), "Socket Programming", "General"},
- {new Integer(3), "Unix", "Enginerring College"},
- {new Integer(4), "Corba Programming", "Graduate school"}
- };
- String column[] = {"Number", "Course", "Department"};
- JTable table;
- JTextField text;
- public void go() {
-
- JPanel panel = new JPanel();
- table = new JTable(tableData, column);// 테이블 생성
- text = new JTextField("");
- JScrollPane scrollPane = new JScrollPane(table);
- panel.setLayout(new BorderLayout());
- panel.add(text, "North");
- panel.add(scrollPane, "Center");
- table.addMouseListener(new MouseAdapter() {// 마우스 리스너
- public void mouseClicked(MouseEvent e) {
- showMe();
- }
- public void mouseClicked(MouseEvent e) {
- });
- JFrame frame = new JFrame("Table Example");
- frame.getContentPane().add(panel);
- frame.setSize(400, 200);
- frame.setVisible(true);
- }
- private void showMe() {
-
- int numRows = table.getSelectedRow();// row 값을 얻는다
- int numColumns = table.getSelectedColumn();// column 값
- TableModel model = table.getModel();
- text.setText(model.getValueAt(numRows, numColumns).toString());
- }
- public static void main(String args[]) {
-
- new JTableTest().go();
- }
- }
JTabbedPane
- JTabbedPane은 아래 그림처럼 여러 pane으로 된 문서에서 특정 탭을 가진 pane을 쉽게 찾아주는 기능을 제공한다(견출지를 붙인 것과 같이). 아래 그림에서 견출지의 역할을 하는 부분을 탭이라고 하는데, 모든 탭은 만들어진 순서대로 index 값을 배정받는다(0부터 시작함). 탭은 스트링 타입의 이름을 가질 수 있다.
- 프로그램에서 탭의 이름으로 또는 탭의 index로 해당 pane을 찾아낼 수 있으며 사용자가 탭을 마우스로 클릭하면 해당 pane이 전면에 나오도록 선택할 후 있다.
- 다음은 JTabbedPand의 주요 생성자이다.
- JTabbedPane()// 탭의 위치가 상단에 옴
- JTabbedPane(int) // 탭의 위치를 지정함
- 인자가 없는 생성자는 디폴트로 탭을 상단부에 만들며, 탭을 다른 곳에 두려면 JTabbedPane.BOTTOM, JTabbedPane.LEFT, JTabbedPane.RIGHT 등의 static 변수를 인자로 하여 두번째 생성자를 호출하면 된다.
- 다음은 JTabbedPane의 주요 메소드이다. 아래에서 탭을 추가하거나 삭제하는 메소드가 있고, 특정 index를 얻는 메소드, 그리고 선택된 탭을 화면에 나타나도록 하는 메소드가 있음을 알 수 있다.
- addTab(String s, Component c) // 이름이 s인 c 타입의 탭을 추가
- remove(Component c)// c와 관련된 탭을 삭제
- removeTabAt(int i) // index i의 탭을 삭제
- indexOfComponent(Component c)// c와 관련된 탭의 index를 리턴
- getSelectedIndex()// 현재 선택된 탭의 index를 리턴
- indexOfTab(String s)// 탭 이름이 s인 탭의 index를 리턴
- setSelectedIndex(int i)// index i의 탭을 선택
- setSelectedComponent(Component c) // c와 관련된 탭을 선택
- 아래의 코드는 위에 보인 그림을 얻는 프로그램인데 사용자가 특정 탭을 마우스로 선택하면 선택된 탭의 pane이 화면에 나타나며 자신의 인덱스 값을 하단의 텍스트필드에 출력하도록 하였다. 이벤트 처리를 위하여 ChangeListener를 연결하였으며 stateChanged() 메소드를 구현하였다.
- import java.awt.*;
- import javax.swing.*;
- import javax.swing.event.*;
- public class Test {
- JTabbedPane tabpane = new JTabbedPane();
- JPanel panel = new JPanel();
- JTextField text = new JTextField();
- public void go() {
- panel.setLayout(new BorderLayout());
- tabpane.addTab("First", // 탭 추가
- new Label("First Tab Pane",Label.CENTER));
- tabpane.addTab("Second",
- new Label("Second Tab Pane",Label.CENTER));
- tabpane.addTab("Third",
- new Label("Third Tab Pane",Label.CENTER));
- tabpane.setSelectedIndex(0);// 첫 탭 지정
- tabpane.addChangeListener(new ChangeListener() { // 리스너
- public void stateChanged(ChangeEvent e) {
- int index = tabpane.getSelectedIndex();
- text.setText("Current index = "+index);
- }
- });
- panel.add(tabpane,"Center");
- panel.add(text,"South");
- JFrame frame = new JFrame("Text Tabs Examples");
- frame.getContentPane().add(panel, "Center");
- frame.setSize(300,300);
- frame.setVisible(true);
- }
- public static void main(String args[]) {
-
- new Test().go();
- }
- }
JTree
- 스윙에서는 아래 그림과 같이 트리 구조로 항목들을 나열할 수 있는데 이것은 디렉토리 구조를 표현할 때 많이 사용된다. 트리에 관련된 메소드는 매우 많으나 기본적인 기능만 사용하여도 간단히 트리를 만들 수 있다.
- 위 그림과 같은 트리를 만드는 코드를 아래에 나타냈다. 먼저 트리의 각 항목을 담을 2차원 어레이 node[][]를 정의하고 초기값을 주었다. 트리는 루트(root) 노드와 서브루트 노드를 중심으로 구성되는데 DefaultMutableTreeNode 클래스를 사용해서 노드들을 만들고 트리의 기본 모델인 DefaultTreeModel을 만든 다음에 이것을 JTree() 생성자의 인자로 주었다.
- import javax.swing.*;
- import javax.swing.tree.*;
- import java.awt.*;
- import java.awt.event.*;
- import java.util.*;
- public class Test {
-
- DefaultTreeModel treeModel;// 트리의 디폴트 모델
- JTree tree;
- String subRoot[] = {"OS", "Language"};
- String node[][] = { // 트리의 각 항목 내용
- {"Linux", "Windows NT", "Unix"},
- {"Java", "C++", "BASIC"}
- };
- DefaultMutableTreeNode root, subRootNode;
- public void go() {
- JPanel panel = new JPanel();
- root = new DefaultMutableTreeNode("Root");
- for(int i =0; i
-
- subRootNode = new DefaultMutableTreeNode(subRoot[i]);
- root.add(subRootNode);
- for(int j =0; j < node[i].length; j++) {
- subRootNode.add(new DefaultMutableTreeNode(node[i][j]));
- }
- }
- treeModel = new DefaultTreeModel(root);// 트리 모델 생성
- tree = new JTree(treeModel);// JTree 생성자
- panel.setLayout(new BorderLayout());
- panel.add(new JLabel("Tree Example"));
- panel.add(new JScrollPane(tree), "Center");
- JFrame frame = new JFrame("Tree Example");
- frame.getContentPane().add(panel);
- frame.pack();
- frame.setVisible(true);
- }
- public static void main(String args[]) {
- new Test().go();
- }
- }
Swing의 Container와 Component
- Swing에서 Top-level container는 JFrame, JApplet, JDialog, JWindow이다.
- Swing에서 Light weight component는 앞에 설명한 JButton, JPanel, JMenu, 등등의 component 들이다.
- Top-level container는 lightweight component가 존재하는 framework을 제공한다. 다시 말해서 top-level Swing Container는 lightweight Swing Component가 그려질 수 잇는 영역을 제공하는 것이다.
- Top-level container는 container의 heavy weight AWT component의 Swing subclass 이다.
- 모든 Swing component들은 top-level Swing container를 가지고 있다. 예를 들어 , Swing component를 가지고 있는 모든 Applet은 JApplet( 이것은 java.applet.Applet의 subclass이다.) subclass이다. 비슷하게 Swing component를 가지고 있는 모든 main window는 JFrame으로부터 implement 되어 졌다.
- 일반적으로 Swing component를 사용하기 위해서는 Swing component 와 Swing Container를 같이 사용해야한다.
- Swing은 Top-level container에 바로 add 되어질 수가 없고, Top-level container와 연관되어 있는 content pane에 add할 수 있다.
- contenet pane은 JPanel과 같은 lightweight Swing component이다.
Swing GUI 예제
- import javax.swing.*;
- import java.awt.*;
- public class SwingGUI{
- JFrame topLevel;
- JPanel jPanel;
- JTextField jTextField;
- JList jList;
- JButton b1;
- JButton b2;
- Container contentPane;
- Object listData[] = {
- new String("First selection"),
- new String("Second selection"),
- new String("Third selection"),
- };
- public static void main(String args[]){
- SwingGUI swingGui =new SwingGUI();
- swingGui.go();
- }
- public void go(){
- topLevel = new JFrame("Swing GUI");
- jPanel = new JPanel();
- jTextField = new JTextField(20);
- jList = new JList(listData);
- contentPane = topLevel.getContentPane();
- contentPane.setLayout(new BorderLayout());
- b1 = new JButton("1");
- b2 = new JButton("2");
- contentPane.add(b1,BorderLayout.NORTH);
- contentPane.add(b2,BorderLayout.SOUTH);
- jPanel.setLayout(new FlowLayout());
- jPanel.add(jTextField);
- jPanel.add(jList);
- contentPane.add(jPanel,BorderLayout.CENTER);
- topLevel.pack();
- topLevel.setVisible(true);
- topLevel = new JFrame("Swing GUI");
- }
- }
실행결과
JComponent Class
- 모든 Swing component는 JComponent class의 subclass이다.
- JComponet는 Container class로부터 inherit 되었다. 그리고, Swing Component들을 JComponent의 다음의 기능을 inherit해서 가지고 있다.
- Borders - setBorder()를 사용하면, 앞에서 예를 들었듯이 component 주위의 edge를 좀더 다르게 나타낼 수 있다.
- Double Buffering - Swing은 Default로 DoubleBuffering 된다.
- Tool Tips - setToolTipText()를 사용하면, component의 사용자에게 help를 제공할 수 있다.
- KeyBoard navigation - registerKeyboardAction()을 사용하면, mouse 대신에 keyboard로 GUI 사이를 이동시킬 수 있다.
- Application-wide pluggable look and feel - 각각의 Java application runtime은 runtime's Swing의 look and feel을 결정하는 GUIManager object를 가지고 있다. UIManager.setLookAndFeel()를 사용해서 모든 Swing component에 의해서 사용되는 look and feel을 바꿀 수 있다. 그리고 JComponent Object는 ComponentGUI object와 연관되어서 모든 drawing과 event handling, size determination 등을 JComponent에 대해서 수행한다.
응용예제1
JFC를 이용한 WordPad를 만들기
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
- public class JWordPad extends WindowAdapter implements ActionListener {
-
- JFrame f;
- JMenuBar mb ;
- JMenu mFile;
- JMenuItem miNew,miLoad, miSave,miExit;
- JToolBar toolbar ;
- JButton bNew, bLoad, bSave;
- JTextArea ta;
- public JWordPad(){
-
- f = new JFrame("Word Pad");
- ta = new JTextArea();
- mb = new JMenuBar();
- mb.setForeground(Color.red);
- mFile = new JMenu("File");
- miNew = new JMenuItem("New",new ImageIcon("image/01.jpg"));
- miLoad = new JMenuItem("Open",new ImageIcon("image/02.jpg"));
- miSave = new JMenuItem("Save",new ImageIcon("image/03.jpg"));
- miExit = new JMenuItem("Close",new ImageIcon("image/04.jpg"));
- mFile.add(miNew);
- mFile.add(miLoad);
- mFile.add(miSave);
- mFile.addSeparator();
- mFile.add(miExit);
- mb.add(mFile);
- Container c = f.getContentPane();
- f.setJMenuBar(mb);
- toolbar = new JToolBar();
- toolbar.setLayout(new GridLayout(1,3));
- bNew = new JButton(new ImageIcon("image/04.jpg"));
- bLoad = new JButton(new ImageIcon("image/05.jpg"));
- bSave = new JButton(new ImageIcon("image/06.jpg"));
- bNew.setToolTipText("File New");
- bLoad.setToolTipText("File Loading");
- bSave.setToolTipText("File Saving");
- toolbar.add(bNew);
- toolbar.add(bLoad);
- toolbar.add(bSave);
- c.add(toolbar,"North");
- c.add(ta,"Center");
- f.setSize(400,400);
- f.setVisible(true);
- Listener();
- }
- public void Listener(){
- miLoad.addActionListener(this);
- miSave.addActionListener(this);
- miExit.addActionListener(this);
- f.addWindowListener(this);
- }
- public void windowClosing(WindowEvent e){
- f.dispose();// frame만 종료되고, process 는 종료되지 않는다. applet을 짤때, 좋다.
- System.exit(1);
- }
- public void actionPerformed(ActionEvent e){
- if(e.getSource() == miNew){
- ta.setText("New...");
- }else if(e.getSource() == miLoad){
- ta.setText("Load...");
- }
- else if(e.getSource() == miSave){
- ta.setText("Save...");
- }else if(e.getSource() == miExit){
- //f.dispose();
- System.exit(1);
- }
- if(e.getSource() == miNew){
- }
- public static void main(String args[]){
- JWordPad wp = new JWordPad();
- } // main end
- }// class end
Level 3 배경색 바꾸는 프로그램
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
- import javax.swing.event.*;
- public class ColorChange implements ChangeListener{
-
- JPanel panel = new JPanel();
- JTextField jtf = new JTextField(20);
- JSlider redSlider, blueSlider, greenSlider;
- Canvas can ;
- int R,G,B;
- void go(){
- JFrame f = new JFrame("Color Change");
- Container c = f.getContentPane();
- JPanel contPanel = new JPanel();
- contPanel.setLayout(new GridLayout(1,3));
- redSlider = new JSlider(JSlider.VERTICAL, 0, 255, 60);
- redSlider.setMajorTickSpacing(20);
- redSlider.setMinorTickSpacing(5);
- redSlider.setPaintTicks(true);
- redSlider.setPaintLabels(true);
- redSlider.addChangeListener(this);
- blueSlider = new JSlider(JSlider.VERTICAL, 0, 255, 60);
- blueSlider.setMajorTickSpacing(20);
- blueSlider.setMinorTickSpacing(5);
- blueSlider.setPaintTicks(true);
- blueSlider.setPaintLabels(true);
- blueSlider.addChangeListener(this);
- greenSlider =new JSlider(JSlider.VERTICAL, 0, 255, 60);
- greenSlider.setMajorTickSpacing(20);
- greenSlider.setMinorTickSpacing(5);
- greenSlider.setPaintTicks(true);
- greenSlider.setPaintLabels(true);
- greenSlider.addChangeListener(this);
- contPanel.add(redSlider);
- contPanel.add(blueSlider);
- contPanel.add(greenSlider);
- c.add(contPanel,"East");
- can = new Canvas();
- c.add(can,"Center");
- R=10;
- G=10;
- B=10;
- can.setBackground(new Color(R,G,B));
- f.setSize(400,400);
- f.setVisible(true);
- }
- public void stateChanged(ChangeEvent e) {
- if(e.getSource() == redSlider){
- R = redSlider.getValue();
- can.setBackground(new Color(R,G,B));
- can.repaint();
- }else if(e.getSource() == blueSlider){
- B = blueSlider.getValue();
- can.setBackground(new Color(R,G,B));
- can.repaint();
- }else if(e.getSource() == greenSlider){
- G = greenSlider.getValue();
- can.setBackground(new Color(R,G,B));
- can.repaint();
- }
- if(e.getSource() == redSlider){
- }
- public static void main(String args[]){
- new ColorChange().go();
- }
- }
'My work space > Java' 카테고리의 다른 글
AWT/SWING 성능 비교(기본 출력 기능) (0) | 2008.08.20 |
---|---|
소켓(Socket) (0) | 2008.08.20 |
AWT란 (0) | 2008.08.20 |
awt와 swing의 차이점 (0) | 2008.08.20 |
Basic Java - Swing (0) | 2008.08.14 |