[펌] Swing

Programming/JAVA 2005. 6. 17. 03:58
 

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);

                }

            }

        });

    }


    public static void main(String args[]) {

        BorderWindow window = new BorderWindow();

        window.inAnApplet = false;


        window.setTitle("BorderLayout");

        window.pack();

        window.setVisible(true);

    }

}


사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지



BoxLayout


BoxLayout은 가로나 세로로 컴포넌트를 하나씩 더해간다.

생성자는 아래와 같다.

BoxLayout(Container target, int axis)

target : 레이아웃이 필요한 컨테이너

axis : BoxLayout.X_AXIS, BoxLayout.Y_AXIS


import java.awt.*;

import java.awt.event.*;

import javax.swing.*;


public class BoxWindow extends JFrame {

    boolean inAnApplet = true;

    

    public BoxWindow() {

        Container contentPane = getContentPane();

        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));

//        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS));

  

        addAButton("Button 1", contentPane);

        addAButton("2", contentPane);

        addAButton("Button 3", contentPane);

        addAButton("Long-Named Button 4", contentPane);

        addAButton("Button 5", contentPane);


        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                if (inAnApplet) {

                    dispose();

                } else {

                    System.exit(0);

                }

            }

        });

    }


    private void addAButton(String text, Container container) {

        JButton button = new JButton(text);

        button.setAlignmentX(Component.CENTER_ALIGNMENT);

//        button.setAlignmentX(Component.LEFT_ALIGNMENT);

//       button.setAlignmentX(Component.BOTTOM_ALIGNMENT);

        container.add(button);

    }


    public static void main(String args[]) {

        BoxWindow window = new BoxWindow();

        window.inAnApplet = false;


        window.setTitle("BoxLayout");

        window.pack();

        window.setVisible(true);

    }

}

사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

사용자 삽입 이미지


기타기능


CardLayout


CardLayout은 둘 이상의 컴포넌트들이 같은 공간에 하나씩 보이도록 한다. 여러 카드를 쌓아놓고 한 장씩 보는 것과 같다.

CardLayout을 사용하는 컨테이너에 컴포넌트를 추가할 때는 아래와 같이 컴포넌트를 구분하는데 사용되는 문자열을 포함해야 한다.

public void Container.add(Component comp, Object constraints);

constraints : 컴포넌트를 구분하는 문자열


아래는 CardLayout 클래스의 주요 메서드다.

자료형

메서드 / 설명

생성자

 

CardLayout()

자료형

메서드 / 설명

기타

void

void

void

void

void

first(Container parent)

last(Container parent)

previous(Container parent)

next(Container parent)

show(Container parent, String name)

parent : CardLayout을 갖는 컨테이너

name : 보여질 컴포넌트 이름


import java.awt.*;

import java.awt.event.*;

import javax.swing.*;


public class CardWindow extends JFrame

                        implements ItemListener {

    boolean inAnApplet = true;

    

    JPanel cards;

    final static String BUTTONPANEL = "JPanel with JButtons";

    final static String TEXTPANEL = "JPanel with JTextField";


    public CardWindow() {

        Container contentPane = getContentPane();


        //Put the JComboBox in a JPanel to get a nicer look.

        String comboBoxItems[] = { BUTTONPANEL, TEXTPANEL };

        JPanel cbp = new JPanel();

        JComboBox c = new JComboBox(comboBoxItems);

        c.setEditable(false);

        c.addItemListener(this);

        cbp.add(c);


        //Use the default layout manager, BorderLayout

        contentPane.add(cbp, BorderLayout.NORTH);


        cards = new JPanel();

        cards.setLayout(new CardLayout());

  

        JPanel p1 = new JPanel();

        p1.add(new JButton("Button 1"));

        p1.add(new JButton("Button 2"));

        p1.add(new JButton("Button 3"));


        JPanel p2 = new JPanel();

        p2.add(new JTextField("TextField", 20));


        cards.add(p1, BUTTONPANEL);

        cards.add(p2, TEXTPANEL);

        contentPane.add(cards, BorderLayout.CENTER);

       

        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                if (inAnApplet) {

                    dispose();

                } else {

                    System.exit(0);

                }

            }

        });

    }


    public void itemStateChanged(ItemEvent evt) {

        CardLayout cl = (CardLayout)(cards.getLayout());

        cl.show(cards, (String)evt.getItem());

    }


    public static void main(String args[]) {

        CardWindow window = new CardWindow();

        window.inAnApplet = false;


        window.setTitle("CardLayout");

        window.pack();

        window.setVisible(true);

    }

}

사용자 삽입 이미지
사용자 삽입 이미지


FlowLayout

JPanel의 기본 레이아웃 관리자다

FlowLayout은 가로로 컴포넌트를 배치하고 컨테이너의 크기를 넘어서면 다음 줄에 배치한다.


import java.awt.*;

import java.awt.event.*;

import javax.swing.*;


public class FlowWindow extends JFrame {

    boolean inAnApplet = true;

    

    public FlowWindow() {

        Container contentPane = getContentPane();

        contentPane.setLayout(new FlowLayout());

  

        contentPane.add(new JButton("Button 1"));

        contentPane.add(new JButton("2"));

        contentPane.add(new JButton("Button 3"));

        contentPane.add(new JButton("Long-Named Button 4"));

        contentPane.add(new JButton("Button 5"));


        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                if (inAnApplet) {

                    dispose();

                } else {

                    System.exit(0);

                }

            }

        });

    }


    public static void main(String args[]) {

        FlowWindow window = new FlowWindow();

        window.inAnApplet = false;


        window.setTitle("FlowLayout");

        window.pack();

        window.setVisible(true);

    }

}

사용자 삽입 이미지
사용자 삽입 이미지


GridLayout

컴포넌트를 셀들로 이루어진 격자에 배치한다. 컴포넌트는 셀의 공간을 전부 차지하고, 모든 셀은 같은 크기다.


아래는 GridLayout 클래스의 주요 메서드다.

자료형

메서드 / 설명

생성자

 

GridLayout(int rows, int cols)

rows : 행 셀 개수, 0는 무제한

cols : 열 셀 개수, 0는 무제한


import java.awt.*;

import java.awt.event.*;

import javax.swing.*;


public class GridWindow extends JFrame {

    boolean inAnApplet = true;


    public GridWindow() {

        Container contentPane = getContentPane();


        contentPane.setLayout(new GridLayout(0,2));

  

        contentPane.add(new JButton("Button 1"));

        contentPane.add(new JButton("2"));

        contentPane.add(new JButton("Button 3"));

        contentPane.add(new JButton("Long-Named Button 4"));

        contentPane.add(new JButton("Button 5"));


        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                if (inAnApplet) {

                    dispose();

                } else {

                    System.exit(0);

                }

            }

        });

    }


    public static void main(String args[]) {

        GridWindow window = new GridWindow();

        window.inAnApplet = false;


        window.setTitle("GridLayout");

        window.pack();

        window.setVisible(true);

    }

}

사용자 삽입 이미지
사용자 삽입 이미지


GridBagLayout

IDE를 통한 GUI 설계


11.3.3커스텀 레이아웃


레이아웃 매니저를 사용하지 않고 직접 픽셀 단위로 컴포넌트의 위치를 지정한다.

        Container contentPane = getContentPane();

        contentPane.setLayout(null);

        Component.setBounds(Rectangle);


// NoLayout.java

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;


public class NoLayout extends JFrame {

    private JButton b1, b2, b3;


    public NoLayout() {

        Container contentPane = getContentPane();

        contentPane.setLayout(null);


        b1 = new JButton("one");

        contentPane.add(b1);

        b2 = new JButton("two");

        contentPane.add(b2);

        b3 = new JButton("three");

        contentPane.add(b3);


        Insets insets = contentPane.getInsets();

        b1.setBounds(25 + insets.left, 5 + insets.top, 75, 20);

        b2.setBounds(55 + insets.left, 35 + insets.top, 75, 20);

        b3.setBounds(150 + insets.left, 15 + insets.top, 75, 30);

    }


    public static void main(String[] args) {

        JFrame frame = new NoLayout();


        frame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                System.exit(0);

            }

        });


//              frame.pack(); Layout Manager를 사용하지 않으므로 적정 크기를 계산 못함

                frame.setSize(new Dimension(300, 200));

        frame.setVisible(true);

    }


}


읽기전용 속성을 디렉토리 단위로 제거

attrib -r *.* /s


11.4중간 단계 컨테이너


11.4.1패널(JPanel)

javax.swing.JComponent

   |

   +--javax.swing.JPanel


패널은 레이아웃을 쉽게할 목적으로 컴포넌트들을 그룹화 시킬 때 사용한다. 패널의 기본 레이아웃은 FlowLayout이다. 프로그램에 사용될 컴포넌트들을 여러 그룹으로 나누고 각 그룹을 패널에 넣는다. 또한, 여러 패널을 하나의 패널로 관리할 수 있다.

CardLayout 예에서처럼 내용창을 패널들로 구성하고 각 패널에 여러 컴포넌트를 배치할 수 있다.


아래는 JPanel 클래스의 주요 메서드다.

자료형

메서드 / 설명

생성자

 

JPanel() 더블버퍼링 기본

JPanel(boolean isDoubleBuffered)

JPanel(LayoutManager layout)

자료형

메서드 / 설명

기타

Component

void

Container.add(Component comp)

Container.setLayout(LayoutManager layout)


패널은 컴포넌트를 추가, 삭제하거나 레이아웃을 설정할 때 JComponent의 메서드를 그대로 사용한다.


아래는 CardLayout 예를 수정하여 패널의 구성을 보여준다.

/*

CardPanel.java

*/


import java.awt.*;

import java.awt.event.*;

import javax.swing.*;


public class CardPanel extends JFrame

                        implements ItemListener {

    boolean inAnApplet = true;

    

    JPanel cards;

    final static String BUTTONPANEL = "JPanel with JButtons";

    final static String TEXTPANEL = "JPanel with JTextField";


    public CardPanel() {

        Container contentPane = getContentPane();


        //Put the JComboBox in a JPanel to get a nicer look.

        String comboBoxItems[] = { BUTTONPANEL, TEXTPANEL };

        JPanel cbp = new JPanel();

        cbp.setBackground(Color.cyan);

        JComboBox c = new JComboBox(comboBoxItems);

        c.setEditable(false);

        c.addItemListener(this);

        cbp.add(c);


        //Use the default layout manager, BorderLayout

        contentPane.add(cbp, BorderLayout.NORTH);


        cards = new JPanel();

        cards.setBackground(Color.orange);

        cards.setLayout(new CardLayout());

  

        JPanel p1 = new JPanel();

//      p1.setOpaque(false); //투명하게 하면 cards의 배경이 보인다

        p1.setBackground(Color.magenta);

        p1.add(new JButton("Button 1"));

        p1.add(new JButton("Button 2"));

        p1.add(new JButton("Button 3"));


        JPanel p2 = new JPanel();

        p2.setBackground(Color.pink);

        p2.add(new JTextField("TextField", 20));


        cards.add(p1, BUTTONPANEL);

        cards.add(p2, TEXTPANEL);

        contentPane.add(cards, BorderLayout.CENTER);

       

        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                if (inAnApplet) {

                    dispose();

                } else {

                    System.exit(0);

                }

            }

        });

    }


    public void itemStateChanged(ItemEvent evt) {

        CardLayout cl = (CardLayout)(cards.getLayout());

        cl.show(cards, (String)evt.getItem());

    }


    public static void main(String args[]) {

        CardPanel window = new CardPanel();

        window.inAnApplet = false;


        window.setTitle("CardLayout");

        window.pack();

        window.setVisible(true);

    }

}

사용자 삽입 이미지
사용자 삽입 이미지

사용자 삽입 이미지


GUI 연습

1. 성적입력

2. 채팅 창

사용자 삽입 이미지

* 각 컴포넌트 생성 및 변경의 도움말 참조



11.4.2스크롤창(JScrollPane)

컴포넌트가 컨테이너의 크기보다 크거나 가변적인 크기를 갖을 때 스크롤창을 사용한다.


사용자 삽입 이미지


아래는 JScrollPane 클래스의 주요 메서드다.

자료형

메서드 / 설명

생성자

 

JScrollPane(Component view)

JScrollPane(Component view, int vsbPolicy, int hsbPolicy)

view : 스크롤창의 보임창(viewport)에서 보여질 컴포넌트

vsbPolicy :

        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED(기본)

        , JScrollPane.VERTICAL_SCROLLBAR_NEVER

        , JScrollPane.VERTICAL_SCROLLBAR_ALWAYS

hsbPolicy :

        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED(기본)

        , JScrollPane.HORIZONTAL_SCROLLBAR_NEVER

        , JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS

자료형

메서드 / 설명

기타

void

void

void

setColumnHeader(JViewport columnHeader)

setRowHeader(JViewport rowHeader)

setCorner(String key, Component corner)

key :

        JScrollPane.LOWER_LEFT_CORNER

        JScrollPane.LOWER_RIGHT_CORNER

        JScrollPane.UPPER_LEFT_CORNER

        JScrollPane.UPPER_RIGHT_CORNER


/*

ScrollPaneDemo.java

*/

import javax.swing.JFrame;

import javax.swing.JTextArea;

import javax.swing.JScrollPane;

import javax.swing.JPanel;


import java.awt.*;

import java.awt.event.*;


public class ScrollPaneDemo extends JFrame {

    protected JTextArea textArea;

    protected String newline = "\n";


    public ScrollPaneDemo() {

        //Do frame stuff.

        super("ScrollPaneDemo");

        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                System.exit(0);

            }

        });


        //Create the text area used for output.

        textArea = new JTextArea(5, 10);

                for(int i=0; i<10; i++)

                        textArea.append("반갑습니다. 스크롤패인 연습입니다.\n")

;

        JScrollPane scrollPane = new JScrollPane(textArea);


        //Lay out the content pane.

        JPanel contentPane = new JPanel();

        contentPane.setLayout(new BorderLayout());

        contentPane.add(scrollPane, BorderLayout.CENTER);

        setContentPane(contentPane);

    }


    public static void main(String[] args) {

        ScrollPaneDemo frame = new ScrollPaneDemo();

        frame.pack();

        frame.setVisible(true);

    }

}

사용자 삽입 이미지
사용자 삽입 이미지


11.4.3스플릿창(JSplitPane)

스플릿창은 두 개의 컴포넌트를 상하나 좌우로 나란히 보여준다. 분리바를 조정하여 두 컴포넌트의 영역을 조정할 수 있다.


아래는 JSplitPane 클래스의 주요 메서드다.

자료형

메서드 / 설명

생성자

 

JSplitPane()

JSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent)

orientation :

        JSplitPane.HORIZONTAL_SPLIT(기본값)

        JSplitPane.VERTICAL_SPLIT

newLeftComponent : Top/Left 컴포넌트

newRightComponent : Bottom/Right 컴포넌트

자료형

메서드 / 설명

기타

void

void

void

void

void

setOrientation(int orientation)

setOneTouchExpandable(boolean newValue)

스플릿창 분리바위에 확장/숨김 화살표시 여부 설정

setDividerSize(int pixel)

setDividerLocation(double percent)

setDividerLocation(int pixel)


ResourceBundle

ResourceBundle은 Properties와 비슷한 용도로 사용된다.


아래는 ResourceBundle 클래스의 주요 메서드다.

자료형

메서드 / 설명

기타

static ResourceBundle

String

getBundle(String baseName)

baseName : 파일명이 baseName + ".properties"

baseName + ".properties" 파일로부터 ResourceBundle 객체생성

getString(String key)

ResourceBundle 객체로부터 key에 해당하는 값을 반환


"imagenames.properties"의 내용 예

images=Bird.gif Cat.gif Dog.gif Rabbit.gif Pig.gif


/*

SplitPaneDemo.java

*/


import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.event.*;


import java.util.*;


//SplitPaneDemo itself is not a visible component.

public class SplitPaneDemo implements ListSelectionListener {

    private Vector imageNames;

    private JLabel picture;

    private JList list;

    private JSplitPane splitPane;


    public SplitPaneDemo() {

        //Read image names from a properties file

        ResourceBundle imageResource;

        try {

            imageResource = ResourceBundle.getBundle("imagenames");

            String imageNamesString = imageResource.getString("images");

            imageNames = parseList(imageNamesString);

        } catch (MissingResourceException e) {

            System.err.println();

            System.err.println("Can't find the properties file " +

                               "that contains the image names.");

            System.err.println("Its name should be imagenames.properties, " +

                               "and it should");

            System.err.println("contain a single line that specifies " +

                              "one or more image");

            System.err.println("files to be found in a directory " +

                               "named images.  Example:");

            System.err.println();

            System.err.println("    images=Bird.gif Cat.gif Dog.gif");

            System.err.println();

            System.exit(1);

        }


        //Create the list of images and put it in a scroll pane

        list = new JList(imageNames);

        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        list.setSelectedIndex(0);

        list.addListSelectionListener(this);

        JScrollPane listScrollPane = new JScrollPane(list);


        //Set up the picture label and put it in a scroll pane

        ImageIcon firstImage = new ImageIcon("images/" +

                                     (String)imageNames.firstElement());

        picture = new JLabel(firstImage);

        picture.setPreferredSize(new Dimension(firstImage.getIconWidth(),

                                               firstImage.getIconHeight()));

        JScrollPane pictureScrollPane = new JScrollPane(picture);


        //Create a split pane with the two scroll panes in it

        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,

                                   listScrollPane, pictureScrollPane);

        splitPane.setOneTouchExpandable(true);

        splitPane.setDividerLocation(150);


        //Provide minimum sizes for the two components in the split pane

        Dimension minimumSize = new Dimension(100, 50);

        listScrollPane.setMinimumSize(minimumSize);

        pictureScrollPane.setMinimumSize(minimumSize);


        //Provide a preferred size for the split pane

        splitPane.setPreferredSize(new Dimension(400, 200));

    }


    //Used by SplitPaneDemo2

    public JList getImageList() {

        return list;

    }


    public JSplitPane getSplitPane() {

        return splitPane;

    }


    public void valueChanged(ListSelectionEvent e) {

        if (e.getValueIsAdjusting())

            return;


        JList theList = (JList)e.getSource();

        if (theList.isSelectionEmpty()) {

            picture.setIcon(null);

        } else {

            int index = theList.getSelectedIndex();

            ImageIcon newImage = new ImageIcon("images/" +

                                     (String)imageNames.elementAt(index));

            picture.setIcon(newImage);

            picture.setPreferredSize(new Dimension(newImage.getIconWidth(),

                                               newImage.getIconHeight() ));

            picture.revalidate();

        }

    }


    protected static Vector parseList(String theStringList) {

        Vector v = new Vector(10);

        StringTokenizer tokenizer = new StringTokenizer(theStringList, " ");

        while (tokenizer.hasMoreTokens()) {

            String image = tokenizer.nextToken();

            v.addElement(image);

        }

        return v;

    }


    public static void main(String s[]) {

        JFrame frame = new JFrame("SplitPaneDemo");


        frame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {System.exit(0);}

        });


        SplitPaneDemo splitPaneDemo = new SplitPaneDemo();

        frame.getContentPane().add(splitPaneDemo.getSplitPane());

        frame.pack();

        frame.setVisible(true);

    }

}

사용자 삽입 이미지



11.4.4탭창(JTabbedPane)

탭창은 같은 형태의 여러 컴포넌트들을 동일한 공간에 하나씩 보이게 하는데 사용한다. CardLayout과 비슷한 효과를 나타낸다.


아래는 JTabbedPane 클래스의 주요 메서드다.

자료형

메서드 / 설명

생성자

 

JTabbedPane()

JTabbedPane(int tabPlacement)

tabPlacement :

        SwingConstants.TOP

        SwingConstants.BOTTOM

        SwingConstants.LEFT

        SwingConstants.RIGHT

자료형

메서드 / 설명

기타

void

void

void

Component

int

void

addTab(String title, Component component)

addTab(String title, Icon icon, Component component)

addTab(String title, Icon icon, Component component, String tip)

getSelectedComponent()

getSelectedIndex()

setSelectedIndex(int index)


/*

TabbedPaneDemo.java

*/


import javax.swing.JTabbedPane;

import javax.swing.ImageIcon;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JFrame;


import java.awt.*;

import java.awt.event.*;


public class TabbedPaneDemo extends JPanel {

    public TabbedPaneDemo() {

        ImageIcon icon = new ImageIcon("images/middle.gif");

        JTabbedPane tabbedPane = new JTabbedPane();


        Component panel1 = makeTextPanel("Blah");

        tabbedPane.addTab("One", icon, panel1, "Does nothing");

        tabbedPane.setSelectedIndex(0);


        Component panel2 = makeTextPanel("Blah blah");

        tabbedPane.addTab("Two", icon, panel2, "Does twice as much nothing");


        Component panel3 = makeTextPanel("Blah blah blah");

        tabbedPane.addTab("Three", icon, panel3, "Still does nothing");


        Component panel4 = makeTextPanel("Blah blah blah blah");

        tabbedPane.addTab("Four", icon, panel4, "Does nothing at all");


        //Add the tabbed pane to this panel.

        setLayout(new GridLayout(1, 1));

        add(tabbedPane);

    }


    protected Component makeTextPanel(String text) {

        JPanel panel = new JPanel(false);

        JLabel filler = new JLabel(text);

        filler.setHorizontalAlignment(JLabel.CENTER);

        panel.setLayout(new GridLayout(1, 1));

        panel.add(filler);

        return panel;

    }


    public static void main(String[] args) {

        JFrame frame = new JFrame("TabbedPaneDemo");

        frame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {System.exit(0);}

        });


        frame.getContentPane().add(new TabbedPaneDemo(),

                                   BorderLayout.CENTER);

        frame.setSize(400, 125);

        frame.setVisible(true);

    }

}

사용자 삽입 이미지


11.4.5툴바(JToolBar)

툴바는 주로 메뉴 항목들에 해당하는 아이콘화된 버튼들을 한 줄로 그룹화한다. BoxLayout을 기본으로 사용한다. 메뉴 항목과의 연결은 메뉴에서 설명한다.


아래는 JToolBar 클래스의 주요 메서드다.

자료형

메서드 / 설명

생성자

 

JToolBar()

JToolBar(int orientation)

orientation :

        SwingConstants.HORIZONTAL

        SwingConstants.VERTICAL

자료형

메서드 / 설명

기타

Component

void

void

Container.add(Component comp)

addSeparator()

setFloatable(boolean aFlag)

aFlag : true이면 툴바를 드래그하여 컨테이너내의 상하좌우나(컨테이너의 레이아웃이 BorderLayout일 경우) 컨테이너 밖으로 이동할 수 있다.


import javax.swing.JToolBar;

import javax.swing.JButton;

import javax.swing.ImageIcon;


import javax.swing.JFrame;

import javax.swing.JTextArea;

/*

ToolBarDemo.java

*/


import javax.swing.JScrollPane;

import javax.swing.JPanel;


import java.awt.*;

import java.awt.event.*;


public class ToolBarDemo extends JFrame {

    protected JTextArea textArea;

    protected String newline = "\n";


    public ToolBarDemo() {

        //Do frame stuff.

        super("ToolBarDemo");

        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                System.exit(0);

            }

        });


        //Create the toolbar.

        JToolBar toolBar = new JToolBar();

        addButtons(toolBar);


        //Create the text area used for output.

        textArea = new JTextArea(5, 30);

        JScrollPane scrollPane = new JScrollPane(textArea);


        //Lay out the content pane.

                JPanel contentPane = new JPanel();

        contentPane.setLayout(new BorderLayout());


                contentPane.setPreferredSize(new Dimension(400, 100));

        contentPane.add(toolBar, BorderLayout.NORTH);

        contentPane.add(scrollPane, BorderLayout.CENTER);


                setContentPane(contentPane);

    }


    protected void addButtons(JToolBar toolBar) {

        JButton button = null;


        //first button

        button = new JButton(new ImageIcon("images/left.gif"));

        button.setToolTipText("This is the left button");

        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                displayResult("Action for first button");

            }

        });

        toolBar.add(button);


        //second button

        button = new JButton(new ImageIcon("images/middle.gif"));

        button.setToolTipText("This is the middle button");

        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                displayResult("Action for second button");

            }

        });

        toolBar.add(button);


        //third button

        button = new JButton(new ImageIcon("images/right.gif"));

        button.setToolTipText("This is the right button");

        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                displayResult("Action for third button");

            }

        });

        toolBar.add(button);

    }


    protected void displayResult(String actionDescription) {

        textArea.append(actionDescription + newline);

    }


    public static void main(String[] args) {

        ToolBarDemo frame = new ToolBarDemo();

        frame.pack();

        frame.setVisible(true);

    }

}

사용자 삽입 이미지

사용자 삽입 이미지


11.4.6내부 프레임(JInternalFrame)

내부 프레임의 컨테이너는 다층창(특히 JDesktopPane)만 가능하다. JDesktopPane은 다층창에 내부 프레임을 위한 API가 추가된 클래스다. 보통 JFrame은 JDesktopPane을 내용창으로 사용하고, JDesktopPane에 내부 프레임들이 추가된다.


javax.swing.JLayeredPane

   |

   +--javax.swing.JDesktopPane

  

아래는 JDesktopPane 클래스의 주요 메서드다.

자료형

메서드 / 설명

생성자

 

JDesktopPane()

자료형

메서드 / 설명

기타

Component

Container.add(Component comp)


내부 프렘임은 프레임과 생성 및 설정 메서드가 비슷하지만 최상위 컨테이너가 아니고, 윈도우 이벤트가 아닌 내부 프레임 이벤트를 발생시킨다.


아래는 내부 프레임을 사용할 때 주의할 사항이다.

1)크기를 명시적으로 설정. pack(), setSize(), setBounds()

2)위치 설정

3)컴포넌트는 내부 프레임의 내용창에 추가

4)대화상자는 JOptionPane사용

5)내부 프레임은 JDesktopPane과 같은 컨테이너에 추가

6)show()나 setVisible(true)를 호출

7)내부 프렘임 이벤트 발생


아래는 JInternalFrame 클래스의 주요 메서드다.

자료형

메서드 / 설명

생성자

 

JInternalFrame()

JInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable)

자료형

메서드 / 설명

기타

Component

void

void

void

void

Container.add(Component comp)

pack()

Component.setBounds(Rectangle bounds)

Component.setSize(Dimension size)

크기를 명시하지 않으면 화면에 보이지 않음

Component.setLocation(Point)

위치를 명시하지 않으면 컨테이너의 좌측상단(0, 0)에 위치


/*

MyInternalFrame.java

*/


import javax.swing.JInternalFrame;


import java.awt.event.*;

import java.awt.*;


public class MyInternalFrame extends JInternalFrame {

    static int openFrameCount = 0;

    static final int xOffset = 30, yOffset = 30;


    public MyInternalFrame() {

        super("Document #" + (++openFrameCount),

              true, //resizable

              true, //closable

              true, //maximizable

              true);//iconifiable


        //...Create the GUI and put it in the window...


        //...Then set the window size or call pack...

        setSize(200,100);


        //Set the window's location.

        setLocation(xOffset*openFrameCount, yOffset*openFrameCount);

    }

}



/*

InternalFrameDemo.java

*/


import javax.swing.JInternalFrame;

import javax.swing.JDesktopPane;

import javax.swing.JMenu;

import javax.swing.JMenuItem;

import javax.swing.JMenuBar;

import javax.swing.JFrame;


import java.awt.event.*;

import java.awt.*;


public class InternalFrameDemo extends JFrame {

    JDesktopPane desktop;


    public InternalFrameDemo() {

        super("InternalFrameDemo");


        //Make the big window be indented 50 pixels from each edge

        //of the screen.

        int inset = 50;

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

        setBounds(inset, inset,

                  screenSize.width / 3,

                  screenSize.height / 3);


        //Quit this app when the big window closes.

        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                System.exit(0);

            }

        });


        //Set up the GUI.

        desktop = new JDesktopPane(); //a specialized layered pane

        createFrame(); //Create first window

        setContentPane(desktop);

        setJMenuBar(createMenuBar());


        //Make dragging faster:

        desktop.putClientProperty("JDesktopPane.dragMode", "outline");

    }


    protected JMenuBar createMenuBar() {

        JMenuBar menuBar = new JMenuBar();


        JMenu menu = new JMenu("Document");

        menu.setMnemonic(KeyEvent.VK_D);

        JMenuItem menuItem = new JMenuItem("New");

        menuItem.setMnemonic(KeyEvent.VK_N);

        menuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                createFrame();

            }

        });

        menu.add(menuItem);

        menuBar.add(menu);


        return menuBar;

    }


    protected void createFrame() {

        MyInternalFrame frame = new MyInternalFrame();

        frame.setVisible(true); //necessary as of kestrel

        desktop.add(frame);

        try {

            frame.setSelected(true);

        } catch (java.beans.PropertyVetoException e) {}

    }


    public static void main(String[] args) {

        InternalFrameDemo frame = new InternalFrameDemo();

        frame.setVisible(true);

    }

}

사용자 삽입 이미지
사용자 삽입 이미지


11.4.7루트창

루트창은 네 개의 요소를 갖는다.

투명창, 다층창, 내용창, 메뉴바


사용자 삽입 이미지


11.4.7.1투명창(GlassPane)

투명창은 루트창에 대한 입력 이벤트를 가로채거나 그 영역위에 무언가를 그릴 때 사용한다.

// GlassPaneDemo


import javax.swing.*;

import javax.swing.event.MouseInputAdapter;

import java.awt.*;

import java.awt.event.*;


public class GlassPaneDemo {

    static private MyGlassPane myGlassPane;


    public static void main(String[] args) {

        JFrame frame = new JFrame("GlassPaneDemo");

        frame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                System.exit(0);

            }

        });


        JCheckBox changeButton =

                new JCheckBox("Glass pane \"visible\"");

        changeButton.setSelected(false);

        changeButton.addItemListener(new ItemListener() {

            public void itemStateChanged(ItemEvent e) {

                myGlassPane.setVisible(e.getStateChange()

                                       == ItemEvent.SELECTED);

            }

        });


        //Set up the content pane, where the "main GUI" lives.

        Container contentPane = frame.getContentPane();

        contentPane.setLayout(new FlowLayout());

        contentPane.add(changeButton);

        contentPane.add(new JButton("Button 1"));

        contentPane.add(new JButton("Button 2"));


        //Set up the menu bar, which appears above the content pane.

        JMenuBar menuBar = new JMenuBar();

        JMenu menu = new JMenu("Menu");

        menu.add(new JMenuItem("Do nothing"));

        menuBar.add(menu);

        frame.setJMenuBar(menuBar);


        //Set up the glass pane, which appears over both menu bar

        //and content pane.

        myGlassPane = new MyGlassPane(changeButton, menuBar,

                                      frame.getContentPane());

        frame.setGlassPane(myGlassPane);


        frame.pack();

        frame.setVisible(true);

    }

}


/**

* We have to provide our own glass pane so that it can paint.

*/

class MyGlassPane extends JComponent {

    Point point;


    public void paint(Graphics g) {

        if (point != null) {

            g.setColor(Color.red);

            g.fillOval(point.x - 10, point.y - 10, 20, 20);

        }

    }


    public void setPoint(Point p) {

        point = p;

    }


    public MyGlassPane(AbstractButton aButton,

                       JMenuBar menuBar,

                       Container contentPane) {

        CBListener listener = new CBListener(aButton, menuBar,

                                             this, contentPane);

        addMouseListener(listener);

        addMouseMotionListener(listener);

    }

}


/**

* Listen for all events that our check box is likely to be

* interested in.  Redispatch them to the check box.

*/

class CBListener extends MouseInputAdapter {

    Toolkit toolkit;

    Component liveButton;

    JMenuBar menuBar;

    MyGlassPane glassPane;

    Container contentPane;

    boolean inDrag = false;


    public CBListener(Component liveButton, JMenuBar menuBar,

                      MyGlassPane glassPane, Container contentPane) {

        toolkit = Toolkit.getDefaultToolkit();

        this.liveButton = liveButton;

        this.menuBar = menuBar;

        this.glassPane = glassPane;

        this.contentPane = contentPane;

    }


    public void mouseMoved(MouseEvent e) {

        redispatchMouseEvent(e, false);

    }


    /*

     * We must forward at least the mouse drags that started

     * with mouse presses over the check box.  Otherwise,

     * when the user presses the check box then drags off,

     * the check box isn't disarmed -- it keeps its dark

     * gray background or whatever its L&F uses to indicate

     * that the button is currently being pressed.

     */

    public void mouseDragged(MouseEvent e) {

        redispatchMouseEvent(e, false);

    }


    public void mouseClicked(MouseEvent e) {

        redispatchMouseEvent(e, false);

    }


    public void mouseEntered(MouseEvent e) {

        redispatchMouseEvent(e, false);

    }


    public void mouseExited(MouseEvent e) {

        redispatchMouseEvent(e, false);

    }


    public void mousePressed(MouseEvent e) {

        redispatchMouseEvent(e, false);

    }


    public void mouseReleased(MouseEvent e) {

        redispatchMouseEvent(e, true);

        inDrag = false;

    }


    private void redispatchMouseEvent(MouseEvent e,

                                      boolean repaint) {

        boolean inButton = false;

        boolean inMenuBar = false;

        Point glassPanePoint = e.getPoint();

        Component component = null;

        Container container = contentPane;

        Point containerPoint = SwingUtilities.convertPoint(

                                        glassPane,

                                        glassPanePoint,

                                        contentPane);

        int eventID = e.getID();


        if (containerPoint.y < 0) {

            inMenuBar = true;

            container = menuBar;

            containerPoint = SwingUtilities.convertPoint(

                                        glassPane,

                                        glassPanePoint,

                                        menuBar);

            testForDrag(eventID);

        }


        //XXX: If the event is from a component in a popped-up menu,

        //XXX: then the container should probably be the menu's

        //XXX: JPopupMenu, and containerPoint should be adjusted

        //XXX: accordingly.

        component = SwingUtilities.getDeepestComponentAt(

                                        container,

                                        containerPoint.x,

                                        containerPoint.y);


        if (component == null) {

            return;

        }


        if (component.equals(liveButton)) {

            inButton = true;

            testForDrag(eventID);

        }


        if (inMenuBar || inButton || inDrag) {

            Point componentPoint = SwingUtilities.convertPoint(

                                        glassPane,

                                        glassPanePoint,

                                        component);

            component.dispatchEvent(new MouseEvent(component,

                                                 eventID,

                                                 e.getWhen(),

                                                 e.getModifiers(),

                                                 componentPoint.x,

                                                 componentPoint.y,

                                                 e.getClickCount(),

                                                 e.isPopupTrigger()));

        }


        if (repaint) {

            toolkit.beep();

            glassPane.setPoint(glassPanePoint);

            glassPane.repaint();

        }

    }


    private void testForDrag(int eventID) {

        if (eventID == MouseEvent.MOUSE_PRESSED) {

            inDrag = true;

        }

    }

}


사용자 삽입 이미지


11.4.7.2다층창(JLayeredPane)

다층창은 컨테이너에 포함된 컴포넌트의 전후관계(Z-오더)를 설정할 수 있다. 즉, 한 컴포넌트를 다른 컴포넌트 위에 겹쳐 놓을 수 있다.

최상위 컨테이너는 기본으로 루트층에 다층창을 갖는다. 다층창에는 특정한 용도로 쓰이기 위해 정의된 기능층이 존재하고, 일반적으로 이 기능층을 이용한다.


사용자 삽입 이미지

다층창의 기능층


/*

LayeredPaneDemo.java

*/


import javax.swing.*;

import javax.swing.border.*;


import java.awt.*;

import java.awt.event.*;


public class LayeredPaneDemo extends JFrame {

    private String[] layerStrings = { "Yellow (0)", "Magenta (1)",

                                      "Cyan (2)", "Red (3)",

                                      "Green (4)" };

    private Color[] layerColors = { Color.yellow, Color.magenta,

                                    Color.cyan, Color.red,

                                    Color.green };


    private JLayeredPane layeredPane;

    private JLabel dukeLabel;


    public LayeredPaneDemo()    {

        super("LayeredPaneDemo");


        //Create and load the duke icon.

        final ImageIcon icon = new ImageIcon("images/dukeWaveRed.gif");


        //Create and set up the layered pane.

        layeredPane = new JLayeredPane();

        layeredPane.setPreferredSize(new Dimension(300, 310));

        layeredPane.setBorder(BorderFactory.createTitledBorder(

                                    "Move the Mouse to Move Duke"));

        layeredPane.addMouseMotionListener(new MouseMotionAdapter() {

            final int XFUDGE = 40;

            final int YFUDGE = 57;

            public void mouseEntered(MouseEvent e) {

                dukeLabel.setLocation(e.getX()-XFUDGE, e.getY()-YFUDGE);

            }

            public void mouseMoved(MouseEvent e) {

                dukeLabel.setLocation(e.getX()-XFUDGE, e.getY()-YFUDGE);

            }

        });


        //This is the origin of the first label added.

        Point origin = new Point(10, 20);


        //This is the offset for computing the origin for the next label.

        int offset = 35;


        //Add several overlapping, colored labels to the layered pane

        //using absolute positioning/sizing.

        for (int i = 0; i < layerStrings.length; i++) {

            JLabel label = createColoredLabel(layerStrings[i],

                                              layerColors[i], origin);

            layeredPane.add(label, new Integer(i)); 

            origin.x += offset;

            origin.y += offset;

        }


        //Create and add the Duke label to the layered pane.

        dukeLabel = new JLabel(icon);

        dukeLabel.setBounds(15, 225,

                            icon.getIconWidth(),

                            icon.getIconHeight());

        layeredPane.add(dukeLabel, new Integer(2), 0);


        //Add control pane and layered pane to frame.

        Container contentPane = getContentPane();

        contentPane.setLayout(new BoxLayout(contentPane,

                                            BoxLayout.Y_AXIS));

        contentPane.add(Box.createRigidArea(new Dimension(0, 10)));

        contentPane.add(createControlPanel());

        contentPane.add(Box.createRigidArea(new Dimension(0, 10)));

        contentPane.add(layeredPane);

    }


    //Create and set up a colored label.

    private JLabel createColoredLabel(String text,

                                      Color color,

                                      Point origin) {

        JLabel label = new JLabel(text);

        label.setVerticalAlignment(JLabel.TOP);

        label.setHorizontalAlignment(JLabel.CENTER);

        label.setOpaque(true);

        label.setBackground(color);

        label.setForeground(Color.black);

        label.setBorder(BorderFactory.createLineBorder(Color.black));

        label.setBounds(origin.x, origin.y, 140, 140);

        return label;

    }


    //Create the control pane for the top of the frame.

    private JPanel createControlPanel() {

        final JCheckBox onTop = new JCheckBox("Top Position in Layer");

        onTop.setSelected(true);

        onTop.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                if (onTop.isSelected())

                    layeredPane.moveToFront(dukeLabel);

                else

                    layeredPane.moveToBack(dukeLabel);

            }

        });


        final JComboBox layerList = new JComboBox(layerStrings);

        layerList.setSelectedIndex(2);    //Cyan layer

        layerList.addActionListener(new ActionListener () {

            public void actionPerformed(ActionEvent e) {

                int position = onTop.isSelected() ? 0 : 1;

                layeredPane.setLayer(dukeLabel,

                                     layerList.getSelectedIndex(),

                                     position);

            }

        });

       

        JPanel controls = new JPanel();

        controls.add(layerList);

        controls.add(onTop);

        controls.setBorder(BorderFactory.createTitledBorder(

                                 "Choose Duke's Layer and Position"));

        return controls;

    }


    public static void main(String[] args) {

        JFrame frame = new LayeredPaneDemo();


        frame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                System.exit(0);

            }

        });


        frame.pack();

        frame.setVisible(true);

    }

}


사용자 삽입 이미지


11.4.7.3메뉴바(JMenuBar)

메뉴바는 메뉴를 관리하는 컴포넌트다.

여러 가지 메뉴가 메뉴바에 추가될 수 있고, 메뉴바는 프레임이나 루트창에 설정될 수 있다.


메뉴를 사용하기 위해서는 메뉴바를 생성하여 애플릿, 다이얼로그, 프레임, 내부프레임, 루트창에 설정한다.

JApplet.setJMenuBar(JMenuBar)

JDialog.setJMenuBar(JMenuBar)

JFrame.setJMenuBar(JMenuBar)

JInternalFrame.setJMenuBar(JMenuBar)

JRootPane.setJMenuBar(JMenuBar)


메뉴를 생성하여 메뉴바에 추가한다.

public JMenu JMenuBar.add(JMenu c);


// MenuLookDemo.java


import java.awt.*;

import java.awt.event.*;

import javax.swing.JMenu;

import javax.swing.JMenuItem;

import javax.swing.JCheckBoxMenuItem;

import javax.swing.JRadioButtonMenuItem;

import javax.swing.ButtonGroup;

import javax.swing.JMenuBar;

import javax.swing.KeyStroke;

import javax.swing.ImageIcon;


import javax.swing.JTextArea;

import javax.swing.JScrollPane;

import javax.swing.JFrame;


/*

* This class exists solely to show you what menus look like.

* It has no menu-related event handling.

*/

public class MenuLookDemo extends JFrame {

    JTextArea output;

    JScrollPane scrollPane;


    public MenuLookDemo() {

        JMenuBar menuBar;

        JMenu menu, submenu;

        JMenuItem menuItem;

        JCheckBoxMenuItem cbMenuItem;

        JRadioButtonMenuItem rbMenuItem;


        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                System.exit(0);

            }

        });


        //Add regular components to the window, using the default BorderLayout.

        Container contentPane = getContentPane();

        output = new JTextArea(5, 30);

        output.setEditable(false);

        scrollPane = new JScrollPane(output);

        contentPane.add(scrollPane, BorderLayout.CENTER);


        //Create the menu bar.

        menuBar = new JMenuBar();

        setJMenuBar(menuBar);

선택된 option을 반환

        //Build the first menu.

        menu = new JMenu("A Menu");

        menu.setMnemonic(KeyEvent.VK_A);

        menu.getAccessibleContext().setAccessibleDescription(

                "The only menu in this program that has menu items");

        menuBar.add(menu);


        //a group of JMenuItems

        menuItem = new JMenuItem("A text-only menu item",

                                 KeyEvent.VK_T);

        //menuItem.setMnemonic(KeyEvent.VK_T); //used constructor instead

        menuItem.setAccelerator(KeyStroke.getKeyStroke(

                KeyEvent.VK_1, ActionEvent.ALT_MASK));

        menuItem.getAccessibleContext().setAccessibleDescription(

                "This doesn't really do anything");

        menu.add(menuItem);


        menuItem = new JMenuItem("Both text and icon",

                                 new ImageIcon("images/middle.gif"));

        menuItem.setMnemonic(KeyEvent.VK_B);

        menu.add(menuItem);


        menuItem = new JMenuItem(new ImageIcon("images/middle.gif"));

        menuItem.setMnemonic(KeyEvent.VK_D);

        menu.add(menuItem);


        //a group of radio button menu items

        menu.addSeparator();

        ButtonGroup group = new ButtonGroup();


        rbMenuItem = new JRadioButtonMenuItem("A radio button menu item");

        rbMenuItem.setSelected(true);

        rbMenuItem.setMnemonic(KeyEvent.VK_R);

        group.add(rbMenuItem);

        menu.add(rbMenuItem);


        rbMenuItem = new JRadioButtonMenuItem("Another one");

        rbMenuItem.setMnemonic(KeyEvent.VK_O);

        group.add(rbMenuItem);

        menu.add(rbMenuItem);


        //a group of check box menu items

        menu.addSeparator();

        cbMenuItem = new JCheckBoxMenuItem("A check box menu item");

        cbMenuItem.setMnemonic(KeyEvent.VK_C);

        menu.add(cbMenuItem);


        cbMenuItem = new JCheckBoxMenuItem("Another one");

        cbMenuItem.setMnemonic(KeyEvent.VK_H);

        menu.add(cbMenuItem);


        //a submenu

        menu.addSeparator();

        submenu = new JMenu("A submenu");

        submenu.setMnemonic(KeyEvent.VK_S);


        menuItem = new JMenuItem("An item in the submenu");

        menuItem.setAccelerator(KeyStroke.getKeyStroke(

                KeyEvent.VK_2, ActionEvent.ALT_MASK));

        submenu.add(menuItem);


        menuItem = new JMenuItem("Another item");

        submenu.add(menuItem);

        menu.add(submenu);


        //Build second menu in the menu bar.

        menu = new JMenu("Another Menu");

        menu.setMnemonic(KeyEvent.VK_N);

        menu.getAccessibleContext().setAccessibleDescription(

                "This menu does nothing");

        menuBar.add(menu);

    }


    public static void main(String[] args) {

        MenuLookDemo window = new MenuLookDemo();


        window.setTitle("MenuLookDemo");

        window.setSize(450, 260);

        window.setVisible(true);

    }

}


사용자 삽입 이미지



11.5Event Model

11.5.1Delegation Model

1)용어

이벤트 : 마우스, 키보드 입력 등과 같은 사용자 입력, 기타 시스템 이벤트 등

이벤트 소스 : 이벤트를 발생시키는 컴포넌트

이벤트 종류 : 로우레벨 이벤트, 시멘틱 이벤트

이벤트 타켓 : 이벤트의 처리를 담당하는 클래스의 객체

                리스너 구현 또은 아답터 상속

                컨테이너, 내부클래스, 익명 내부클래스가 된다

이벤트 리스너 : 이벤트 종류에 따라 수행해야 할 메서드를 선언한 인터페이스

이벤트 아답터 : 이벤트 리스너를 구현한 비어있는 클래스 : {}

이벤트 핸들러 : 이벤트가 발생되면 수행되어야 할 메서드

                이벤트 종류에 따라 리스너에 선언됨

                이벤트 타겟 클래스에서 구현

                이벤트 소스 얻기(getSource(), getActionCommand())

                처리 절차 기술



2)이벤트 소스와 종류

로우레벨 이벤트 : 윈도우 시스템에서 발생하거나 사용자 입력에 의해 발생되는 이벤트

                윈도우, 마우스, 키보드 등

시멘틱 이벤트 : 로우레벨 이벤트 외의 모든 이벤트

                버튼 선택, 메뉴 아이템 선택 등


각 컴포넌트(소스)의 addXXXListener()를 확인하여 XXX에 해당되는 이벤트가 발생 가능함을 알 수 있다.

Component

(이벤트 소스)

Listener(이벤트 종류)

action

caret

change

document,undoable edit

item

list

selection

window

other

button

X

X

X

check box

X

X

X

color chooser

X

combo box

X

X

dialog

X

editor pane

X

X

hyperlink

file chooser

X

frame

X

internal frame

internal frame

list

X

list data

menu

menu

menu item

X

X

X

menu keymenu drag mouse

option pane

password field

X

X

X

popup menu

popup menu

progress bar

X

radio button

X

X

X

slider

X

tabbed pane

X

table

X

table modeltable column modelcell editor

text area

X

X

text field

X

X

 

X

text pane

X

X

hyperlink

toggle button

X

X

X

tree

tree expansiontree will expandtree modeltree selection

viewport (used byscrollpane)

X

'Programming > JAVA' 카테고리의 다른 글

[펌] [SWING]JFileChooser  (0) 2005.06.29
[펌] 서버 소켓 예제  (0) 2005.06.24
[펌] 클라이언트 소켓  (0) 2005.06.24
[펌] 13. 쓰레드(Thread)  (0) 2005.06.23
[펌] 통신을 위한 THREAD 프로그래밍  (0) 2005.06.23

Posted by 영웅기삼
,