[4th Seoul Workshop]사용자 interface의 구현(B15)

강대웅
서울 영등포구 여의도동 11-11 한서오피스텔 916호
나무소프트
E-mail : gothic@star.elim.net
URL : http://www.namusoft.com/gothic.html
Abstract:
대화형 프로그램의 작성시 필요한 사용자 interface를 예제 Applet의 Source를 근간으로 설명함.
다룰 내용은 정보의 입력에 필요한 event, 정보의 출력에 필요한 Control, Panel, Layout등임
Keywords:
Java, Awt, Interface, Workshop, 나무소프트, 강대웅

1. 개요

1.1 AWT(Abstract Window Tool Kit)

사용자 interface를 위한 event, componet등의 class로 구성된 Package

1.2 구성

  1. Component : 그림 1 참조
  2. Panel Manager
  3. 도형
  4. 기타

component picture

그림 1 : Component구성

2. Graphics

2.1 Component 의 Graphic 관련 Event

  1. paint : resize, restore, page변경등으로 화면이 다시 그려 져야 될 때 불리워짐
  2. resize : window의 크기가 변경될 때 불리워 진다.(Scale의 구현시 사용하면 유용)
  3. layout : Layout의 변화가 있을 때 불리워짐
  4. update: repaint함수가 수행되면 이 함수가 불리워 진다.
  5. repaint: 사용자가 화면을 update하고 싶을 때 이 함수를 부름

2.2 Applet 수행시 event 발생 순서

  1. layout
  2. resize
  3. init
  4. resize
  5. layout
  6. paint

2.1 화면표시의 일반적 구현

실지로 화면을 그리는 부분을 update method에 구현하고 paint함수는 update함수만 부르게 함으로써 system에서 화면을 그리는 부분과 사용자가 repaint를 사용하여 화면을 그리는 부분을 동일시 한다.

2.2 Offscreen Image의 구현

  1. 문제 : 도형자료 수가 가 많아 질수록 화면 재생시 그리는 과정이 눈에 보여 지저분한 느낌을 준다.
  2. 해결 : Graphics를 하나 더 만들어 새로 만든 Graphics에 그리기 작업을 하고 이를 화면 Graphics에 복사한다
  3. 사용예
Dimension dm = size();
offImage = createImage(dm.width, dm.height);
offGraphics = offImage.getGraphics();
....
public void paint(Graphics g)
{ update(g); }
public void update(Graphics g) {
}

2.3 createImage Bug

    Windows95 환경에서 GDI Resource를 Free시켜줄 방법이 없다.

3. Event

3.1 기능:사용자의 input을 받는다

3.2 Event Method in Component

  1. handleEvent : 모든 event를 관리한다.
  2. mouse 관련
    1. mouseDown
    2. mouseDrag
    3. mouseEnter
    4. mouseDrag
    5. mouseMove
    6. mouseUp
  3. keyboard관련
    1. keyDown
    2. keyUp
  4. focus관련
    1. gotFocus
    2. lostFocus
  5. action : component dependent한 event를 받는다
  6. deliverEvent : sub componet에게 event를 넘긴다.
  7. postEvent : handle event를 수행하게 한다.

3.3 Event Routing

Event Routing Picture

그림 2

3.4 handleEvent사용시 주의 사항

3.5 Source in Component

    public boolean handleEvent(Event evt){
      switch (evt.id) {
      case Event.MOUSE_ENTER: return mouseEnter(evt, evt.x, evt.y);
      case Event.MOUSE_EXIT: return mouseExit(evt, evt.x, evt.y);
      case Event.MOUSE_MOVE: return mouseMove(evt, evt.x, evt.y);
      case Event.MOUSE_DOWN: return mouseDown(evt, evt.x, evt.y);
      case Event.MOUSE_DRAG: return mouseDrag(evt, evt.x, evt.y);
      case Event.MOUSE_UP: return mouseUp(evt, evt.x, evt.y);
      case Event.KEY_PRESS: case Event.KEY_ACTION: return keyDown(evt, evt.key);
      case Event.KEY_RELEASE: case Event.KEY_ACTION_RELEASE: return keyUp(evt, evt.key);
      case Event.ACTION_EVENT: return action(evt, evt.arg);
      case Event.GOT_FOCUS: return gotFocus(evt, evt.arg);
      case Event.LOST_FOCUS: return lostFocus(evt, evt.arg);
      }
      return false;
    }

4.LayoutManager

4.1 기능:Container안에 Component를 배치하는 방법을 정한다.

4.2 종류

참고 : http://www.javasoft.com/books/Series/Tutorial/ui/layout/using.html

  1. BorderLayout : 컴포넌트를 중심과 상하좌우에 배치
  2. CardLayout : 한 컨테이너에 컴퍼넌트 셋이 여러개 일때 사용
  3. FlowLayout: Component를 좌우로 길게 배치
  4. GridLayout: 컴포넌트를 일정한 크기로 바둑판 식으로 배치
  5. GridBagLayout(GridBagConstraints)
  6. null : layout manager를 사용하지 않을 때, componet를 원하는 위치에 배치 시킬수 있다.

4.3 LayoutManager Source

4.4 LayoutManger의 구현

class를 implement Layout형태로 만들고 LayoutManager에 있는 5가지 method를 구현해 준다.

4.5 LayoutManger의 사용

Container에 component를 add하기전에 setLayout함수를 이용하여 Layoutmanager를 설정한다.

5.Dialog

5.1 문제: Applet은 Frame이로 부터 상속을 받아 Dialog를 사용할 수 없다.

5.2 해결: Dialog대신 Frame일 사용하고 Frame 을 사용하는동안 Applet을 Disable한다.

5.3 예제

      SetSizeFrame frm = new SetSizeFrame(this, applet);
        frm.tfWidth.setText(Integer.toString(dimension.width));
        frm.tfHeight.setText(Integer.toString(dimension.height));
        frm.tfComment.setText(comment);
        frm.pack();
        frm.show();
        applet.disable();







6.응용(Scroll Panel)

6.1 기능:Scroll이 가능한 Panel

6.2 구현

/**
 * A container class that can scroll area with scrollbar
 *
 * @version     1.0 03/24/96
 * @author          Kang, Dae Woong (namu@star.elim.net)
 */

class ScrollPanel extends Panel
{
    /**
     * The target panel that will be scrolled
     */
        WorkPanel target;
    /**
     * Scrollbars that will be displayed in south, east.
     */
        Scrollbar scbVertical, scbHorizontal;

    /**
     * Constructs a ScrollPanel with a WorkPanel
     * @param target that will be scrolled
     */
        public ScrollPanel(WorkPanel target)
        {
                this.target = target;
                setLayout(new BorderLayout());

                add("Center", target);
                add("South", scbHorizontal = new Scrollbar(Scrollbar.HORIZONTAL,
                    0, 100, 0, 200));
                add("East", scbVertical = new Scrollbar(Scrollbar.VERTICAL));
        }

    /**
     * set Scrollbar values
     */
        public void layout()
        {

                Dimension dm;
                super.layout();
                dm = target.size();

                if (dm.height < target.dimension.height)
                {
                        scbVertical.enable();
                        scbVertical.setValues(scbVertical.getValue(), dm.height, 0, 
                                              target.dimension.height);
                }
                else
                {
                        scbVertical.disable();
                }

                if (dm.width < target.dimension.width)
                {
                        scbHorizontal.enable();
                        scbHorizontal.setValues(scbHorizontal.getValue(), dm.width, 0, 
                                                target.dimension.width);
                }
                else
                {
                        scbHorizontal.disable();
                }
        }

    /**
     * handle Scrollbar event
     */
        public boolean handleEvent(Event e)
        {
                if (e.target == scbVertical || e.target == scbHorizontal)
                {
                        Scrollbar scr = (Scrollbar) e.target;
                        int val = 0;
                        int tmp;
                        boolean isDefault = false;
                        switch (e.id)
                        {
                        case e.SCROLL_ABSOLUTE:
                                val = ((Integer)e.arg).intValue();
                                break;
                        case e.SCROLL_LINE_DOWN:
                                tmp = scr.getValue() + scr.getVisible()/10;
                                scr.setValue((tmp  + scr.getVisible() > 
                                              scr.getMaximum()) ? scr.getMaximum()
                                                         - scr.getVisible() : tmp);
                                val = scr.getValue();
                                break;
                        case e.SCROLL_LINE_UP:
                                scr.setValue(scr.getValue() - scr.getVisible()/10);
                                val = scr.getValue();
                                break;
                        case e.SCROLL_PAGE_DOWN:
                                tmp = scr.getValue() + scr.getVisible();
                                scr.setValue((tmp + scr.getVisible() > 
                                              scr.getMaximum()) ? 
                                              scr.getMaximum()  - scr.getVisible() : tmp);
                                val = scr.getValue();
                                break;
                        case e.SCROLL_PAGE_UP:
                                scr.setValue(scr.getValue() - scr.getVisible());
                                val = scr.getValue();
                                break;
                        default:
                                isDefault = true;
                        }
                        if (!isDefault)
                        {
                                if (e.target == scbVertical)
                                        target.ptScroll.y = val;
                                else
                                        target.ptScroll.x = val;
                                target.repaint();
                                return true;
                        }
                }

                return super.handleEvent(e);
        }
} 


/**
 * A class where draw the drawing
 *
 * @version     1.0 03/24/96
 * @author          Kang, Dae Woong (namu@star.elim.net)
 */
class WorkPanel extends Panel
{
        Point ptScroll = new Point(0, 0);
        Dimension dm = size();                  

        public boolean handleEvent(Event e)
        {
                e.translate(ptScroll.x, ptScroll.y);

                return super.handleEvent(e);
        }

        public void paint(Graphics g)
        {
                update(g);
        }

        public void update(Graphics g)
        {
                Rectangle clipRect;

                g.clipRect(0, 0, dimension.width, dimension.height);
                clipRect = g.getClipRect();

                clipRect.translate(ptScroll.x, ptScroll.y);
                offGraphics.translate(-ptScroll.x, -ptScroll.y);

                offGraphics.setColor(getBackground());
                offGraphics.fillRect(clipRect.x, clipRect.y, clipRect.width, 
                                     clipRect.height);
                ....
        }
        .....
}

7.미해결 Awt기능

7.1 How to Print ?

7.2 How to Scaling (Viewpoint, Window) ?

7.3 Set Line Width

7.4 한글 입력


참고문헌

[WebDraw Source]
(http://www.namusoft.com/java/)

Last-Modified : Tuesday, 09-Dec-2014 17:26:16 UTC