레이블이 class initialize인 게시물을 표시합니다. 모든 게시물 표시
레이블이 class initialize인 게시물을 표시합니다. 모든 게시물 표시

2013년 10월 13일 일요일

[자바교육]자바 싱글톤, 쓰레드 예제

자바 싱글톤, 쓰레드 예제

public class Singleton {
    private static Singleton singleton = new Singleton();
    private Singleton() {
        System.out.println("Sington Class의 인스턴스 생성!");                    
    }
    public static Singleton getInstance() {        
        return singleton;
    }                                         
}
 
public class Main extends Thread {
    public static void main(String[] args) {
        System.out.println("Start.");        
        Singleton obj1 = Singleton.getInstance();
  Singleton obj2 = Singleton.getInstance();
        if (obj1 == obj2){
   System.out.println("obj1 == obj2");
        }
  else {
   System.out.println("obj1 != obj2");
  }
    }
}
 
=======================================
 
 
public class Singleton {
    private static Singleton singleton = null;
    private Singleton() {
        System.out.println("인스턴스 생성...");
        slowdown();                             
    }
    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
    private void slowdown() {                   
        try {                                   
            Thread.sleep(10);                 
        } catch (InterruptedException e) {      
        }                                       
    }                                           
}
 
 
public class Main extends Thread {
    public static void main(String[] args) {
        System.out.println("Start.");
        new Main("A").start();
        new Main("B").start();
        new Main("C").start();
        System.out.println("End.");
    }
    public void run() {
        Singleton obj = Singleton.getInstance();
        System.out.println(getName() + ": obj = " + obj);
    }
    public Main(String name) {
        super(name);
    }
}
 
 

오라클자바커뮤니티에서 설립한 개발자교육6년차 오엔제이프로그래밍 실무교육센터(오라클SQL,튜닝,힌트,자바프레임워크,안드로이드,아이폰,닷넷 실무개발강의)  



2013년 8월 9일 금요일

오라클의 각 Table은 내부적으로 ROWID 라는 의사 열을 가진다. 보통 SELECT등으로 Table을 질의하면 출력되지 않으나 컬럼 명으로 ROWID라는 예약어를 사용하면 읽어 들일 수 있다.  

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  


ROWID에는 Table의 각 행에 대해 물리적인 주소라고 이해 하면 될 것이다. 오라클7에서 ROWID에는 파일번호, 블록번호, 블록 내 ROW번호 3가지 정보를 가지고 있었지만 오라클8 이상부터 ROWID에는 객체의 고유번호를 포함하고 있다는 것은 참고로 알아두자. 데이터를 검색할 때 ROWID를 이용하여 검색 한 다면 가장 빨리 원하는 자료를 검색하는 것이 가능하다.
아래를 보면 앞의 중복된 데이터를 지우는 질의가 이해 될 것이다. 같은 주민등록번호 와 이름을 가지더라도 rowid는 틀리다. 이 특징을 이용하여 중복 데이터를 찾는 것이다.

SQL> select rowid, jumin, name from addrbook;
ROWID              JUMIN          NAME
------------------ -------------- ------------
AAAJMZAABAAAPEKAAA 111111-2222222 홍길동
AAAJMZAABAAAPEKAAB 333333-4444444 가길동
AAAJMZAABAAAPEKAAC 111111-2222222 홍길동

2013년 8월 8일 목요일

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터, 진정한 퍼블리셔가 되기 위한 실무교육, 웹퍼블리싱 마스터

진정한 퍼블리셔가 되기 위한 실무교육, 웹퍼블리싱 마스터


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  

강좌명웹퍼블리싱 마스터(평일야간)
교재자체교재 무료 제공
강좌 일정08월16일(금) ~ 09월04일(수)((평일야간) 19:00~22:00, 14일) 총 42시간
강의 장소[C강의장]구로디지털단지역2번 출구-> 미니스톱끼고 우회전 -> 100m 직진 후 골목길 끝에서 이마트방향 우회전 -> 50m 직진 후 우체국 옆골목으로 길건너서 직진 -> 150미터 직진 후 JnK 타워에서 우회전 -> 50미터 직진 후 우측에 코오롱빌란트2차 803호 (구로구 구로3동 222-8 코오롱디지털타워 빌란트2차 803호)
[약도보기]
수강절차- 강좌내용 확인
- 전화 또는 홈페이지(www.onjprogramming.co.kr)를 통한 수강지원 및 수강료 결제(무통장입금, 온라인 카드결제)
- 고용보험 가입자(재직자)인 경우 고용보험환급 관련 서류 제출
- 수강전 : 커리큘럼 및 장소에 대해 다시 한번 공지
- 교육 전 설문 작성(간단한 개발 경력, 수강 목적, 강좌진행방식 등)
- 강좌 수강
- 수강후 : 교육 후 설문 작성
수강료550,000원
고용보험 환급(50~80% 환급)
[고용주환급]대기업:17만원 전후,중소기업:216,968원
[개인수강지원(개인환급)]정규직 440,000원 환급 ,비정규직:전액환급

재직자 내일배움카드 : 정부지원금 80% 자기부담금 20%
(구 능력개발카드 명칭이 내일배움카드로 변경 / 연간 총한도 200만원)


* 휴강 :법정공휴일 
수강료
입금안내
- 온/오프라인 카드결제, 계좌이체(수강안내->입금안내 참조)
문의사항02-851-4790 번으로 연락 부탁 드립니다.
교육개요HTML과 CSS를 주로 다루면서 웹 사이트의 사용자 화면을 설계하는 사람들을 주로 웹 퍼블리셔라고 하며 다양한 스마트폰, 다양한 브라우저에서 웹화면이 깨지지 않도록 웹페이지를 제작하는 역할을 한다고 보시면 됩니다. 현재 웹 생태계에서 최근에 각광을 받고 있는 직업이 있다면 단연 웹 퍼블리셔죠.

본 과정에서는 HTML, HTML5, CSS3, JavaScript, jQuery등을 활용하여 어떠한 브라우저 환경에서도 깨지지 않는 웹페이지 제작 기술과 노하우를 학습하실 수 있을 것 입니다.

같이 동참하시기 바랍니다!
교육목표- HTML의 이해 및 활용
- HTML5의 이해 및 활용
- CSS3에 대한 이해 및 활용
- JavaScript의 이해 및 활용
- jQuery에 대한 이해 및 활용
교육대상- 웹퍼블리셔가 되기위한 사람
- HTML및CSS를 배울려는 초보개발자
- 웹표준에 대한 이해가 부족한 개발자
- Ajax, jQuery능력이 부족한 개발자
선수학습- HTML의 이해
- 웹에 대한 이해
 


웹표준/웹접근성- 웹표준/웹접근성의 정의
- 웹접근성 준수하기
- W3C의 표준 문법
- 웹접근성 의무화를 준비하자!
HTML/HTML5- HTML 구성요소
- HTML 문서작성법
- 텍스트 관련 태그
- 표제(Heading)
- 링크(Link)
- 배경(background)
- 테이블(table)
- 색(color)
- 레이아웃(Layout)
- 이미지맵(image map)
- 아이프레임(iframe)
- HTML과 XHTML
- 입력양식(form)
- 마퀴(Marquee)
- 오브젝트(Object)
- HTML5 개요
- HTML History
- HTML5 특징/장점
- HTML4 & HTML5
- 스마트폰용 HTML5의 기본 형태
- 동영상 & 이미지 다루기
- 그래픽 처리 ~ 캔버스
JavaScriptJavaScript 개요, 사용방법
반복문
함수
이벤트처리
내장객체(Number, Data, String, Mat, Array, Screen)
웹브라우저 내장객체(Window, Frame, Document, History 등)
입력양식(Form, text, textarea, password, button, submit, checkbox, radio,  select)
JavaScript오 DOM 다루기
JavaScript 응용 Application 작성
CSS3- CSS3 개요
- CSS와 HTML의 상호 작용에 대한 이해
- 레이아웃, 글꼴, 텍스트
- 테이블, 리스트, 폼
jQuery왜 jQuery인가?
jQuery 문법
jQuery 라이브러리
selector, property, attribute
jQuery Grid, UI, Code Assist, Blog, API
실전 퍼블리싱- 웹표준 및 웹접근성의 이해
- HTML, CSS, jQuery를 이용한 실전 퍼블리싱 실습
 

(오라클자바커뮤니티jquery 강좌)jQuery를 통한 키보드 이벤트, keydown, keyup, keypress , ORACLEJAVA CONNUNITY

jQuery를 통한 키보드 이벤트


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  



keydown : 키 눌러질때,   keypress:글자가입력될때
keyup : 키보드가 떨어질 때

<script type="text/javascript">
$(document).ready(function() {
//keydown 이벤트가발생한순간에는글자가입력되어있지않음
//입력한글자수를표시해야하므로keyup 이벤트사용
$("textarea").keyup(function () {
//남은 글자수 구합니다.
var inputLength = $(this).val().length;
var remain = 50 ? inputLength;
//남은 글자수 display
$("h1").html(remain);
//문서객체 색상 변경
if (remain >= 0) {
$("h1").css("color","Blue");
} else {
$("h1").css("color","red")
}
});
});
</script>
<body><div>
<p>지금 내 생각을</p>
<h1>50</h1>
<textarea cols="40" rows="5"></textarea>
</div>
</body>

[오라클자바닷넷커뮤니티자바교육케이쿼리강좌] jQuery 기본 효과 메소드, show, hide, toggle, fadein, fadeout, slidedown, slideup

jQuery 기본 효과 메소드 이론및 실습입니다. 참조하세요


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  

show() : 크게 하면서 보여 줌                          hide() : 작게하면서 사라지게 함
toggle() : show, hide 번갈아 실행                   slideDown() : 슬라이드효과와 함께 보여줌
slideUp() : 슬라이드 효과와 함게 사라지게        slideToggle() : slideDown, slideUp을 번갈아
fadeIn() : 선면하게 하면서 보여 줌                   fadeOut() : 흐리게하면서 사라지게
fadeToggle() : fadeIn, fadeOut을 번갈아

jQuery 기본 효과 메소드 사용방법

$(selector).method();                                  $(selector).method(speed);
$(selector).method(speed, callback) ;             $(selector).method(speed, easing, callback);
speed : 효과를 진행 할 속도, 밀리초 단위 숫자 or slow, normal, fast 입력
callback : 효과를 다 진행한 후 실행할 함수
easing : 애니메이션의 easing 속성 지정, 별도 플러그인 사용안하면 문자열 linear, swing 만  입력 가능

[예제]

H1 태그 클릭 시 문서 객체의 바로 다음 위치 객체에  toggle 메소드 적용,
-->  사라졌다 보였다를 반복
<script type="text/javascript">
$(document).ready(function() {
$("h1").click(function() {
$(this).next().toggle("slow", function() {
alert("toggle");
});
});
});
</script>
<body>
<!-- h1태그 클릭  다음 div 태그 토글되어 사라졌다 보였다 반복 -->
<h1>실무개발교육 오엔제이프로그래밍실무학원</h1>
<div>
<h1>오라클자바</h1>
<p>닷넷, 스마트폰 개발교육</p>
</div>
<h1><font color=blue>OnjProgramming.co.kr</font></h1>
<div>
<h1>오라클자바</h1>
<p>닷넷, 스마트폰 개발교육</p>
</div>
</body>


[오라클자바커뮤니티강좌,자바교육]Struts에서의 예외처리-2

Struts에서의 예외처리(2)



오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  




스트럿츠가 제공 하는 예외 처리

스트럿츠 1.1. 이후에는 작지만 효율적인 예외처리 프레임워크를 추가 했습니다. 또한 org.apache.struts.util.AppException 클래스는 ActionError를 포함하며 java.lang.Exception을 확장한 클래스 입니다.

아래와 같이 스트럿츠에서 사용하면 되는데

throw new AppException(“error.password.invalid”);

생성자의 “error.password.invalid”는 리소스 번들의 key 이며 프레임웍에서는 자동적으로 예외의 ActionError 객체를 생성하고 적절한 scope에 저장 합니다. 물론 애플리케이션에서 AppException에 대해 확장이 가능 합니다.

----------------------------------------------------
선언적 예외 처리와 프로그램적 예외처리
----------------------------------------------------

선언적 예외처리는 struts-config.xml등에 예외에 대해서 정의 하는 것 입니다. 이에 반해 프로그램적 예외 처리는 선언적 예외 처리와 정반대되는 개념으로 애플리케이션에서 정의한 내부 코드를 통해 예외를 처리하는 전통적인 방법 입니다.

아래는 login Action에서 발생하는 세가지 예외를 정의한 것 입니다.

<action-mappings>
                <action
                        path="/login"
                        type="com.oreilly.struts.storefront.security.LoginAction"
                        name="loginForm"
                        scope="request"
                        input="/login.jsp">
               
                <!--The following exceptions can be thrown during the login action -->
                <exception
                        key="security.error.changepassword"
                        path="/changePassword.jsp"
        type="com.oreilly.struts.framework.exceptions.ExpiredPasswordException"/>

                <exception
                        key=" security.error.loginfailed"
                type="com.oreilly.struts.framework.exceptions.InvalidLoginException"
                        path="/login.jsp"/>

                <exception
                        key="security.error.accountlocked"
        type="com.oreilly.struts.framework.exceptions.AccountLockedException"
                        path="/accountLocked.jsp"/>
        </action>
</action-mappings>


위에서 exception 요소는 정의한 예외가 발생 할 경우 포워드할 경로를 액션 매핑이나 전역 예외에 정의 합니다. Login Action이 실행하는 동안 ExpiredPasswordException이 발생 한다면 컨트롤러의 제어를 changePassword.jsp로 포워드 됩니다.

예외를 Action 클래스에 프로그램 코드를 통해 코딩을 하지 않았다면 RequestProcessor는 정의한 예외 타입을 설정한 exception 요소가 있는지 확인 하며 만약 exception 요소가 있다면 컨트롤러는 exception 요소의 path 속성에 지정된 자원으로 포워드 합니다.

아래는 RequestProcessor 클래스의 processException() 메소드 입니다. 메소드의 시작 시점에 findException() 메소드가 ExceptionConfig 객체를 반환 하는데 ExceptionConfig 객체는 설정 파일에 기술된 exception 요소가 메모리에 있는 것으로 생각하면 됩니다.

만약 findException() 메소드가 발생한 예외와 대응하는 exception 요소를 찾지 못하면 스트럿츠 프레임워크에서의 예외 처리 없이 클라이언트에 반환 됩니다. 발생한 예외가 IOException이나 IOException 클래스의 서브 클래스가 아니면 ServletException 인스턴스로 감싸서 다시 던집니다.

만약 특정한 예외를 정의한 Action Mapping이 있다면 findException() 메소드를 통해 ExceptionConfig 객체를 반환 합니다.

getHandler() 메소드는 ExceptionConfig 객체를 추출하고 추출한 핸들러를 예외를 처리하는데 사용 합니다.

--------------------------------------------------------
protected ActionForward processException(HttpServletRequest        request,
                                        HttpServletResponse response,
                                        Exception exception,
                                        ActionForm form,
                                        ActionMapping mapping)
                                        throws IOException, ServletException {
        // Is there a defined handler for this exception?
        ExceptionConfig config =mapping.findException(exception.getClass( ));

        if (config == null){
                if (log.isDebugEnabled( )){
                        log.debug(getInternal().getMessage("unhandledException",exception.getClass( )));
                }

        if (exception instanceof IOException){
                throw (IOException) exception;
        }
        else if (exception instanceof ServletException){
                throw (ServletException) exception;
        }
        else{
                throw new ServletException(exception);
        }


        // Use the configured exception handling
        try {
                Class handlerClass = Class.forName(config.getHandler( ));
                ExceptionHandler handler =(ExceptionHandler)handlerClass.newInstance( );
                return (handler.execute(exception, config, mapping,        form,request, response));
        }
        catch (Exception e){
                throw new ServletException(e);
        }
}


---------------------------------------------------------

스트럿츠 프레임워크에서는 예외 처리에 관한 환경 설정이 되어 있지 않은 경우 사용 가능한 기본 예외 처리 클래스를 포함 하고 있는데. org.apache.struts.action.ExceptionHandler가 기본 핸들러 입니다.

기본 핸들러의 execute() 메소드는 ActionError를 생성하고 적절한 scope에 저장한 다음 exception 요소의 path 속성에 할당 되어 있는 ActionForward 객체를 반환 합니다. 결국 Actionforward의 경로로 제어를 넘기게 됩니다.

예외가 발생 했을 때 다른 처리를 원한다면 exception 요소는 핸들러 클래스에 대한 오버라이드를 허용 합니다. 즉 struts-config.xml 파일에 exception 요소 안에서 handler 속성에 org.apache.struts.action.ExceptionHandler 클래스를 상속하는 클래스를 명시 함으로서 가능 합니다. Handler 클래스의 execute() 메소드를 오버라이드 함으로서 각각의 애플리케이션들은 기본 예외에서 확장된 예외 처리를 할 수 있습니다.



------------------------------------------------------------

import java.util.List;
import java.util.ArrayList;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* 이 클래스는 애플리케이션 예외의 공통 슈퍼 클래스 입니다.
* 이 클래스와 이 클래스의 서브 클래스는 chained exception 기능을 제공
* chained exception 기능은 원래 문제를 이 클래스나 이 클래스의 서브 클래스로
* 감싸서 다시 실행 할 수 있습니다.
* 이 클래스는 exception을 List로 관리 함으로서 다중 예외 처리가 가능 합니다.
*/
public class BaseException extends Exception{
        protected Throwable rootCause = null;
       
        //예외를 여러 개 관리하고 나중에 ActionError를 만들 때도 반영
        private List exceptions = new ArrayList( );

        private String messageKey = null;
        private Object[] messageArgs = null;

        public BaseException( ){
                super( );
        }
       
        //생성자
        public BaseException( Throwable rootCause ) {
                this.rootCause = rootCause;
        }

        public List getExceptions( ) {
                return exceptions;
        }

        public void addException( BaseException ex ){
                exceptions.add( ex );
        }

        public void setMessageKey( String key ){
                this.messageKey = key;
        }

        public String getMessageKey( ){
                return messageKey;
        }
       
        //어떤 메시지는 아규먼트가 여러 개 일 수 있습니다.
        // 예를들면 나이는 0 ~ 99 사이의 수가 들어와야 합니다.
        public void setMessageArgs( Object[] args ){
                this.messageArgs = args;
        }

        public Object[] getMessageArgs( ){
                return messageArgs;
        }

        public void setRootCause(Throwable anException) {
                rootCause = anException;
        }

        public Throwable getRootCause( ) {
                return rootCause;
        }

        public void printStackTrace( ) {
                printStackTrace(System.err);
        }

        public void printStackTrace(PrintStream outStream) {
                printStackTrace(new PrintWriter(outStream));
        }

        public void printStackTrace(PrintWriter writer) {
                super.printStackTrace(writer);
                if ( getRootCause( ) != null ) {
                        getRootCause( ).printStackTrace(writer);
                }
                writer.flush( );
        }
}



-------------------------------------------------------------

아래에서 messageKey는 ActionError 클래스의 생성자에 전달되고 스트럿츠 프레임웍에서는 키와 리소스 번들의 메시지를 대응 시킵니다. 또한 클래스는 생성된 예외들을 추가 할 수 있는 객체 배열을 포함합니다.

객체 배열에 있는 예외 객체들은 MessageFormat을 기반으로 파라미터에 따라 리소스 번들의 메시지를 교환 할 수 있습니다. 번들 안에 있는 메시지는 다음과 같습니다.

global.error.invalid.price=The price must be between {0} and {1}.

아래는 기본 예외 핸들러 클래스를 확장 하고 ActionError 생성자 내부의 인자를 동적으로 생성하는 기능을 제공 합니다.

-----------------------------------------------------------------

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ExceptionHandler;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionError;
import org.apache.struts.util.AppException;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.config.ExceptionConfig;
import com.oreilly.struts.framework.exceptions.BaseException;

public class SpecialExceptionHandler extends ExceptionHandler
{
        protected ActionForward execute(Exception ex,
                        ExceptionConfig config,
                        ActionMapping mapping,
                        ActionForm formInstance,
                        HttpServletRequest request,
                        HttpServletResponse response)
                                        throws ServletException {
                ActionForward forward = null;
                ActionError error = null;
                String property = null;

                /* input 속성이나 exception 요소에서 포워드할 path를 가져옴 */
                String path = null;
                if (config.getPath( ) != null) {
                        path = config.getPath( );
                }
                else{
                        path = mapping.getInput( );
                }

                // Construct the forward object
                forward = new ActionForward(path);

                /* Figure out what type of exception has been thrown.The Struts
                * AppException is not being used in this example.
                */
                if( ex instanceof BaseException) {
                        // ********* 특화된 처리 부분
                        BaseException baseException = (BaseException)ex;
                        String messageKey = baseException.getMessageKey( );
                        Object[] exArgs = baseException.getMessageArgs( );
                        if ( exArgs != null && exArgs.length > 0 ){
                        // If there were args provided, use them in the       
ActionError
                                error = new ActionError( messageKey, exArgs );
                        }
                        else{
                                // Create an ActionError without any arguments
                                error = new ActionError( messageKey );
                        }
                }
                else{
                        error = new ActionError(config.getKey( ));
                        property = error.getKey( );
                }

                // Store the ActionError into the proper scope
                // The storeException method is defined in the parent        class
                storeException(request, property, error, forward,
                config.getScope( ));
                return forward;
        }
}


스트럿츠의 예외 처리에 대해 정리해보면 Action에서 execute() 메소드를 실행 시 예외처리를 위해 try-catch로 쌉니다. 예외가 발생 했다면 RequestProcessor 클래스의 findException이 호출되어 ExceptioConfig 객체를 반환 합니다. 다음으로 getHandler() 메소드가 호출 되어 핸들러를 얻습니다. 다음으로 기본 핸들러만 정의되어 있다고 보면 핸들러 클래스의 execute() 메소드가 호출되고 여기에서 ActionError를 생성 후 적절한 scope에 저장 후 path 속성에 정의된 리소스로 제어를 넘깁니다.

 


-------------------------------
프로그램에서 오류 처리하기
-------------------------------

Action 클래스에서 예외가 발생 했을 때 만약 발생한 예외가 애플리케이션 예외 인 경우 로그를 남기고 ActionError를 생성하여 해당 스코프에 저장한 후 ActionForward를 통해 제어를 넘기는 식으로 처리 합니다.

예외의 효과적인 관리를 위해 최상위 래퍼 클래스(BaseException)를 하나 만들고 애플리케이션 예외를 모두 그 안에 두는 것 입니다. 이렇게 하면 catch 문에서 BaseException만 받아내면 될 것 입니다. (BaseException이 아니면 시스템 예외라고 가정 할 수 있으며 이렇게 처리 해야 합니다.)

시스템 예외 처리 방법은 예외를 로그로 남기고 시스템 에러 페이지를 만들어 그곳으로 포워드 시키면 됩니다.

아래는 Action안에서의 처리 입니다.

try{
        // Peform some work that may cause an application or system        exception
}
catch( BaseException ex ){
        // Log the exception
        // Create and store the action error
        ActionErrors errors = new ActionErrors( );
        ActionError newError = new ActionError( ex.getErrorCode(),ex.getArgs( ) );
        errors.add( ActionErrors.GLOBAL_ERROR, newError );
        saveErrors( request, errors );

        // Return an ActionForward for the Failure resource
        return mapping.findForward( "Failure" )
}
catch( Throwable ex ){
        // Log the exception
        // Create and store the action error
        ActionError newError = new        ActionError( "error.systemfailure" );
        ActionErrors errors = new ActionErrors( );
        errors.add( ActionErrors.GLOBAL_ERROR, newError );
        saveErrors( request, errors );
        // Return an ActionForward for the system error resource
        return mapping.findForward( IConstants.SYSTEM_FAILURE_PAGE );
}

Action마다 이렇게 한다는 것은 중복되는 코드가 발생 할 수 있는데 앞에서 설명 드린 선언적 접근 방법을 이용한다면 해결 할 수 있지만 Action의 최상위인 BaseAction을 하나 만들어 이를 해결 할 수 있습니다.

모든 action에 공통적으로 들어가야 할 기능이 있다면 (로그인 체크,접속/비 접속 체크,쇼핑 카트 등) 그것을 구현해 놓고(추상 클래스로), 다른 action들이 struts의 action을 상속받지 않고, 이 공통 action을 상속받게 합니다. 이것은 필수요소가 아니라 선택사항입니다. 공통사항이 없다면 하지 않아도 상관 없습니다.

아래에 최상위 Action에 관련된 예문이 있으니 참고 바랍니다.
 
//execute( ) method of the BaseAction(Action의 최상위 클래스로서 추상클래스 입니다.)
//아래의 경우 예외 발생시 execute 메소드의 catch에 의해 잡힙니다.
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws Exception {
ActionForward forwardPage = null;
        try{
                UserContainer userContainer = getUserContainer( request );
                // 이부분에 필요하다면 모든 액션들이 공통으로 확인해야 되는 사항이
                //있다면 처리 합니다.(로그인 여부, 장바구니 확인 등)

        // 별도로 선언된 executeAction을 실행 시킵니다.
        // executeAction은 서브 액션의 입맛에 맞게 적절히 구현해서 사용 합니다.
        //예를들면 게시판 기능이라면 게시물을 읽는 기능, 쓰는 기능, 삭제 기능, 수정 기능 등이  될 수 있습니다.
                forwardPage = executeAction(mapping, form, request,        response, userContainer);
        }
        //아래의 catch문이 모든 Action에 있어야 하는 겁니다.
        catch (BaseException ex){
                // Log the application exception using your logging        framework
                // Call the generic exception handler routine
                forwardPage = processExceptions( request, mapping,        ex );
        }catch (Throwable ex){
                // Log the system exception using your logging framework
                // Make the exception available to the system error page
                request.setAttribute( Action.EXCEPTION_KEY, ex );

                // Treat all other exceptions as system errors
                forwardPage =mapping.findForward( IConstants.SYSTEM_FAILURE_KEY );
        }
        return forwardPage;
}

//추상메소드로 선언하고 이 최상위 액션을 상속 받는 하위 액션들의 입맛에 맞게 구현토록 합니다.
abstract public ActionForward executeAction( ActionMapping mapping,
                                                                                        ActionForm form,
                                                                                        HttpServletRequest request,
                                                                                        HttpServletResponse response,
                                                                                        UserContainer userContainer )
throws BaseException;


다음은 execute() 메소드에서 예외가 발생 되었을 때 이것을 처리하기 위한 BaseAction의processException() 메소드를 보도록 합니다.

-----------------------------------------------------------

Action안에 정의 되어 있습니다. 이 메소드는 여러 개일지 모르는 예외를 찾아 예외의 수 만큼 processBaseException 이라는 메소드를 다시 불러 그곳에서 ActionError등에 저장 하는 기능 등을 수행하도록 합니다.

protected ActionForward processExceptions( HttpServletRequest request,
                                        ActionMapping mapping,
                                        BaseException ex )
{
        ActionErrors errors = new ActionErrors( );
        ActionForward forward = null;

        // 사용자의 지역 설정을 가지고 옵니다.
        Locale locale = getUserContainer( request ).getLocale( );
        if (locale == null){
                        // 지역이 설정되지 않았다면 기본 지역을 사용
                        environment locale = Locale.getDefault( );
        }

        processBaseException(errors, (FieldException) ex, locale);

        // 입력된 리소스와 failure 포워드를 반환 합니다.
        String inputStr = mapping.getInput( );
        String failureForward = mapping.findForward(IConstants.FAILURE_KEY);

        if ( inputStr != null) {
                forward = new ActionForward( inputStr );
        }
        else if (failureForward != null){
                forward = failureForward;
        }

        // 예외가 하위 예외를 포함하고 있는지 확인
        List exceptions = ex.getExceptions( );

        if (exceptions != null && !exceptions.isEmpty( ) ){
                int size = exceptions.size( );
                Iterator iter = exceptions.iterator( );

                while( iter.hasNext( ) ){
                        // 모든 하위예외들은 BaseException이어야 합니다.
                        BaseException subException =(BaseException)iter.next( );
                        processBaseException(errors, subException, locale);
                }
        }

        // Tell the Struts framework to save the errors into the request
        saveErrors( request, errors );

        // Return the ActionForward
        return forward;
}


------------------------------------------------------------

processException 메소드의 수행 과정은 다음과 같습니다.

1.        사용자의 지역 확인
2.        Top레벨 예외의 processBaseException() 메소드를 수행
3.        다른 서브 예외가 있다면 각각의 예외를 수행
4.        생성한 모든 ActionError를 저장
5.        제어를 input 속성에 있는 리소스나 액션에 설정된 “Failure” Actionforward에 넘김


아래는 BaseAction의 processBaseException 메소드 입니다.


protected void processBaseException( ActionErrors errors,
                                                                        BaseException ex,
                                                                        Locale locale)
{

        // 추가될 ActionError의 레퍼런스 저장
        ActionError newActionError = null;

        // 에러 코드는 리소스 번들의 키값
        String errorCode = ex.getMessageKey( );

        /*MessageFormat 객체가 사용하는 추가적인 인자가 있다면
        * args에 예외를 추가
        */
        Object[] args = ex.getMessageArgs( );

       
        // ACtionError 클래스의 인스턴스 생성자
        if ( args != null && args.length > 0 ){
                // Use the arguments that were provided in the exception
                newActionError = new ActionError( errorCode, args );
        }
        else{
                newActionError = new ActionError( errorCode );
        }

        errors.add( ActionErrors.GLOBAL_ERROR, newActionError );

[오라클자바닷넷강의, ORACLEJAVA]스트럿츠에서의 예외처리

Struts에서의 예외처리 방법입니다. 참고하세요

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  

자바의 예외는 애플리케이션에서 비정상적인 상황이 발생 할 때 생성되는 객체 입니다. 자바에서 예외가 발생하면 java.lang.Throwable  객체를 상속한 객체를 생성하는 것입니다. Throwable 아래에는 java.lang.Error와 java.lang.Exception등이 있습니다.

 

일반적으로 Exception의 경우 Application에서 처리 가능한 예외이며 스트럿츠에서의 모든 예외는 Exception 클래스의 서브 클래스로 생성하고 발생해야 합니다.

Exception을 제외한 Error 부분은 심각한 문제들을 위해 예약되어 있습니다. 예를 들어 애플리케이션에서 사용 할 시스템 메모리가 부족한 에러 등이 해당 합니다. 그러므로 일반적으로 Error클래스의 서브 클래스의 경우는 애플리케이션에서 예외를 처리하기는 어려우며 대부분 JVM 자체에서 Error또는 Error클래스의 서브 클래스의 인스턴스를 발생 시킵니다.

JVM은 각 스레드의 호출 순서를 추적하는데 사용하기 위해 호출 스택(Call Stack)이라고 부르는 메소드 호출 스택(Method Invocation Stack)을 사용 합니다. main()에서부터 출발하여 각각의 메소드가 호출 될 때 마다 메소드 호출 스택의 상단에 추가되고 새롭게 추가된 메소드 스택이 현재 실행할 메소드가 되는 것 이며 각 메소드 필드 상태는 해당하는 스택 프레임에 저장됩니다.

JVM은 자바 메소드가 정상적으로 종료하면 최상단의 현재 메소드의 스택 프레임을 꺼내고 다음 스택 프레임을 실행 합니다. 그러나 예외가 발생 한다면 예외 핸들러를 찾는데 우선 현재 메소드에서 try-catch 구문이 있는지 확인을 합니다. 만약 현재 예외가 발생 한 곳에 try-catch 구문이 없다면 JVM은 발생한 예외 혹은 그 예외의 상위 예외를 처리하는 구문을 찾을 때 까지 호출 스택에서 메소드 프레임을 하나씩 꺼냅니다.

만약 JVM이 모든 스택 프레임을 꺼냈는데도 해당 예외를 처리하는 구문이 없을 경우 예외가 발생 한 쓰레드는 종료하게 됩니다. 만약 종료한 쓰레드가 메인 쓰레드이고 다른 비데몬 쓰레드가 없다면 애플리케이션 자체가 종료하게 됩니다.

이와는 달리 JVM이 예외를 처리하는 구문을 만난다면 그 구문이 있는 스택 프레임을 스택의 맨 위에 위치 시키고 다시 실행을 재개 하게 됩니다.

 




--------------------------
Checked와 Unchecked
--------------------------

자바의 예외는 checked 예외와 unchecked 예외로 구분해 볼 수 있습니다. Checked 예외는 클라이언트가 반드시 처리해야 하는 것이며 이에 대한 처리를 위해 메소드에서는 try-catch로 처리하거나 throws을 이용하여 예외를 던져 버려야 합니다.

JVM은 컴파일 시 checked 예외를 검사하지만 unchecked 예외에 대해서는 무시 합니다. Unchecked 예외로는 java.lang.ClassCastException등과 같은 예외가 있는데 일반적으로 부정확한 로직이나 프로그래밍의 오류로 인해 발생 되는 오류들 입니다.

또한 checked와 unchecked 예외는 예외 계층에서의 위치로도 결정 되는데 RuntimeException의 서브 클래스를 제외한 java.lang.Exception 클래스의 자식 클래스는 모두 checked 예외 입니다. 즉 이 예외는 try-catch로 처리 하든지 아니면 throw 절에 의해 처리되는 것이 보장 되어야 합니다.

Runtime 클래스와 그 자식 예외들은 unchecked 예외인데 이 예외는 try-catch 또는 throws 절에 위해 처리 되지 않아도 프로그램은 컴파일 되고 수행이 됩니다. 그러므로  unchecked라고 하는 겁니다.

보통 자바에서 try-carch문을 이용하는 것은 애플리케이션의 성능에 큰 영향을 주지 않습니다. 실제 예외가 발생 했을 때만  영향을 미치는데 이러한 이유는 JVM이 예외를 처리할 핸들러를 찾기 때문 입니다. 만약 예외를 처리 할 catch 문이 예외가 발생 한 메소드안에 있으면 성능에는 문제가 없지만 예외를 처리하기 위해 아래의 스택 프레임을 뒤진다면 성능에 영향을 줄 수 있습니다.

따라서 try-catch문은 오류에 대한 처리 조건으로 이용되어야 하며 프로그램의 흐름을 컨트롤 하기 위해서 사용 되어져서는 안됩니다. 아래는 잘못 사용된 예 입니다.

Double basePrice = null;
String basePriceStr =request.getParameter( "BASE_PRICE_AMOUNT" );

// Use a try/catch to make sure the value is a number
try{
basePrice = Double.valueOf( basePriceStr );
}
catch( NumberFormatException ex )
{
// The value could not be converted to a valid Double; set the default
basePrice = ApplicationDefaults.DEFAULT_BASE_PRICE;
}


--------------------------
Chained 예외 사용하기
--------------------------

때에 따라서는 특정 타입의 예외를 catch한 후 다른 유형의 예외를 발생하는 경우가 있습니다. 예를 들어 스트럿츠에서 애플리케이션의 Action 클래스를 호출해서 데이터베이스에 이미지를 저장 하는 경우라고 했을 때 Action 클래스에서는 다음과 같은 update  메소드를 호출 합니다.

public void updateImageFile( String imagePath ) throws UploadException;

메소드를 호출하면 이미지 파일을 업로드 하고 예외가 발생하면 UploadException이 발생 합니다. 에러가 발생하는 실제 오류를 보면 데이터베이스에 저장 공간이 없을 수도 있고 여러 가지 오류의 경우가 나올 수 있습니다. 아마도 최초 발생 하는 예외는 IOException이나 SQLException등이 될 것 입니다.

그러나 사용자는 이 레벨의 오류를 알 필요가 없습니다. 단지 필요한 것은 이미지의 업로드기 실패 했다는 것이 됩니다. 이런 경우 추후 개발자가 확인을 위해 시스템에 로깅을 통해 SQLExceptio이나 IOException은 기록을 하고 사용자에게는 “입력 실패 입니다”와 같은 오류 메시지를 보여 주어야 할 것 입니다.

--------------------------------------------------------

Example 10-1. An exception class that supports chained exceptions
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* 이 클래스는 애플리케이션 예외의 슈퍼 클래스 입니다.
* 이 클래스와 이 클래스의 서브 클래스는 chained 예외 기능을 제공 합니다.
* chained 예외기능 이란 원래의 문제를 이 클래스나 이 클래스의 서브
* 클래스로 감싸서 다시 예외를 발생 시키는 것 입니다.
*/
public class BaseException extends Exception {
        protected Throwable rootCause = null;
        protected BaseException( Throwable rootCause ) {
                this.rootCause = rootCause;
        }

        public void setRootCause(Throwable anException) {
                rootCause = anException;
        }

        public Throwable getRootCause( ) {
                return rootCause;
        }

        public void printStackTrace( ) {
                printStackTrace(System.err);
        }

        public void printStackTrace(PrintStream outStream) {
                printStackTrace(new PrintWriter(outStream));
        }

        public void printStackTrace(PrintWriter writer) {
                super.printStackTrace(writer);
                if ( getRootCause( ) != null ) {
                        getRootCause( ).printStackTrace(writer);
                }
                writer.flush( );
        }
}

-----------------------------------------------------

위 예제는 원래의 Throwable을 감싸고 있으며 이러한 경우의 장점은 저 수준 예외에 대한 자세한 부분들을 추상화 할 수 있다는 것입니다. 동시에 예외의 자세한 사항을 로그에 기록하고 게발자가 사용 할 수 있도록 할 수 있습니다. 이러한 예외들을 계속 연결 할 수 있기 때문에 chained 예외라고 합니다.

“exception chaining”은 JDBC같은 저 수준의 오류를 사용자에게 전달하는 것을 막을 수 있습니다.


----------------------------
다중 예외
----------------------------

한 메소드에서 여러 예외가 발생 한다는 개념으로 “exception chaining”을 약간 변형 한 것입니다.

인터넷을 통해 회원가입을 하려고 합니다. 비밀번호와 비밀번호 확인이 잘못 되었으며 주소도 입력하지 않았고 전화번호도 기입하지 않았습니다. 이 경우 여러 항목들을 입력하고 “저장” 버튼을 누르면 오류가 차례차례로 하나씩 나타나 사용자를 불편하게 할 것입니다.

닷넷인 경우 Validation Check를 위한 객체를 지원하여 이러한 부분이 해결 가능 하지만 자바에서는 기본적으로 지원하지 않습니다. 불행이도 자바에서는 오직 하나의 Throwable만 던질 수 있습니다.

다중 예외를 처리하는 한가지 방법은 예외 클래스가 다른 예외들의 컬렉션을 지원하는 기본 예외를 갖도록 하는 것입니다. 아래의 예문에서는 메소드가 실행 하는 동안 예외가 하나 이산 발생 하면 추가적인 예외들을 추가하여 클라이언트에 반환 합니다.

import java.util.List;
import java.util.ArrayList;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* exceptions라는 인스턴스 변수에서 여러 예외를 지원 합니다.
*/
public class BaseException extends Exception{
        protected Throwable rootCause = null;
        private List exceptions = new ArrayList( );

        public BaseException( ){
                super( );
        }

        public BaseException( Throwable rootCause ) {
                this.rootCause = rootCause;
        }

        public List getExceptions( ) {
                return exceptions;
       

        public void addException( BaseException ex ){
                exceptions.add( ex );
        }

        public void setRootCause(Throwable anException) {
                rootCause = anException;
        }

        public Throwable getRootCause( ) {
                return rootCause;
        }

        public void printStackTrace( ) {
                printStackTrace(System.err);
        }

        public void printStackTrace(PrintStream outStream) {
                printStackTrace(new PrintWriter(outStream));
        }

        public void printStackTrace(PrintWriter writer) {
                super.printStackTrace(writer);

                if ( getRootCause( ) != null ) {
                        getRootCause( ).printStackTrace(writer);
                }
                writer.flush( );
        }

2013년 8월 6일 화요일

[오라클자바닷넷커뮤니티, ORACLEJAVA]환영인사(Welcome)를 struts의 Action으로 설정하기 , 스트럿츠 교육

환영인사(Welcome)를 struts의 Action으로 설정하기 


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  




web.xml에서 welcome-file-list는 사용자가 URI의 일부만 입력을 했을 때 기본적으로 보여 줄 자원을 정하기 위해 사용 합니다.

예를들어 다음과 같이 설정 했다면…(Login 이라는 웹 애플리케이션을 만들었다고 가정)

<welcome-file-list>
            <welcome-file>main.jsp</welcome-file>
    </welcome-file-list>

브라우저에서 http://localhost/Login/ 이라고 입력하면 main.jsp 가 로딩 된다는 이야기 입니다. 즉 http://localhost/Login/main.jsp 와 같은 기능을 수행 하는 것 입니다.

몰론 welcome-file-list에 여러 개의 welcome-file을 선언 하는 것 역시 가능 합니다.

이렇게 하면 컨테이너는 사용자가 요청한 URI와 일치하는 환영파일을 찾을 때 까지(기술된 순서대로) 찾는 과정을 반복 합니다.

Welcome-file의 속성 값은 ‘/’로 시작하거나 뒤쪽에 ‘/’이 붙을 수 없으니 주의 하세요~

----------------------------------------------------------
환영 파일 내에서 struts의 Action을 사용 하기
----------------------------------------------------------

컨테이너는 welcome-file-list 요소 내에 서블릿 매핑을 지원하지 않으므로 struts의 Action을 사용하기 위해 welcome-file 요소를 직접 만질 수는 없습니다.

그대신 다음과 같은 방법을 이용하면 가능 합니다.

1.        web.xml에서 welcome-file을 설정 합니다.

<welcome-file-list>
            <welcome-file>welcome.jsp</welcome-file>
    </welcome-file-list>

2.        welcome.jsp를 만듭니다.

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html>
        <body>
                <logic:forward name="welcome"/>
        </body>
</html>

3.        welcome.jsp에서 사용한 global-forward를 만듭니다.(struts-config.xml)

<global-forwards>
<forward name="welcome" path="welcome.do"/>
    </global-forwards>

4.        global-forward에서 정의 한 Action에 대한 매핑을 합니다.(struts-config.xml)

<action-mappings>                   
        <!-- welcome Action정의 -->
        <action
                path="/welcome"
                type="login2.Welcome"
                validate="false"
        />           
    </action-mappings>

5.        테스트를 위해 간단한 Action 파일을 만듭니다.

package login2;

import org.apache.struts.action.Action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import login2.Constants;

public class Welcome extends Action {       
       
        public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
                               
                //성공적으로 처리 되었음을 알림, main.jsp로 보내버림...
                //결국 환영인사를 하게 되면 main.jsp가 불리는 것입니다.
                return (mapping.findForward(Constants.SUCCESS));
               
        }
}


결과를 확인 하기 위해 http://localhost/Login/ 이라고 입력 하면 main.jsp가 실행 됩니다. 혹시 main.jsp를 만들지 않으신 분은 이전 강좌에 있는 main.jsp를 이용하세요~

[ORACLE SGA Tuning, 오라클자바커뮤니티]X$KSMLRU

X$KSMLRU 에 대해 알아봅니다.


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  


 X$KSMLRU는 Shared Pool 영역에서 다른 오브젝트를 age out 시키고 연속된 공간을 할당 받은 Object에 대한 정보를 담고 있어 많은 양의 메모리를 사용하는 Object에 대한 Flush 상태를 확인 할 수 있습니다. SYS 사용자만 질의 가능 합니다.

 많은 Object를 Flush 시키고 할당이 되는 객체들이 자주 변한다면 Response Time이 나빠지며 Flush 되었던 객체가 다시 로드 됨으로서 Library Cache Latch Contention을 일으킬 수 있습니다.

 그러므로 많은 Object들을 Flush 시키며 로드되는 Object들이 자주 사용 된다면 Memory에 KEEP 시키도록 하는 것이 유리 합니다. 이 Fixed Table(X$KSMLRU)에서 한번 조회된 ROW는 테이블에서 없어 집니다.

아래는 Object의 할당으로 인해 Flush 된 Object 수가 0보다 큰 것을 조회하는 겁니다. 즉 여기에 나타나는 것이 큰 Object이죠… 이놈을 Shared Pool에 올리려니 크기가 크니까 다른 Object를 쫓아 보리는 겁니다. 물론 그러한 새션의 아이디도 확인 할 수 있습니다.

SQL> select * from x$ksmlru where ksmlrnum > 0;

ADDR          INDX    INST_ID  KSMLRIDX  KSMLRDUR KSMLRCOM
-------- ---------- ---------- ---------- ---------- --------------------
  KSMLRSIZ  KSMLRNUM KSMLRHON                          KSMLROHV KSMLRSES
---------- ---------- -------------------------------- ---------- --------
02EE6B54          0          1          1          0 work area tabl
      4216          8                                          0 799FC2D8

02EE6B00          1          1          1          0 BAMIMA: Bam Buffer
      4132          8 BEGIN dbms_shared_pool.sizes...  335996982 799FC2D8


SQL> select * from x$ksmlru where ksmlrsiz > 5000;

선택된 레코드가 없습니다.

SQL> select * from x$ksmlru where ksmlrnum > 0;

선택된 레코드가 없습니다.   위에서 조회 했으므로 데이터가 사라 졌다.

Columns Desc

KSMLRSIZ : allocate된 연속된 memory size, 이 크기가 5K 넘으면 문제의 소지가 있으며 10K가 넘으면 심각, 20K가 넘으면 심각한 문제를 야기 시킬 가능성이 있습니다.

KSMLRNUM : 이 Object의 할당으로 인해 Flush 된 Object 수
KSMLRHON : Load되고 있는 Object의 이름(PL/SQL or Cursor)
KSMLROHV : Load되고 있는 Object의 Hash Value
KSMLRSES : 이 Object를 Load한 Session의 SADDR 값 

2013년 8월 5일 월요일

JAVA Swing JLABEL 예제 입니다.

JAVA Swing JLabel Example 입니다.


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의) 

 www.onjprogramming.co.kr 



///////////////////////////////////////////////// 
 //  JLabel예제
 //  displayedMnemonic, setLabelFor등...
 ///////////////////////////////////////////////// 

 import java.awt.*;
 import javax.swing.*;
 import java.awt.event.*;
 public class MNemonicLabels {
 public static void main(String args[]) {
        //Create labels and text fields
        JLabel lastName =new JLabel("Last Name",JLabel.RIGHT);
        JLabel middleName =new JLabel("Middle Name",JLabel.RIGHT);
        JLabel firstName =new JLabel("First Name",JLabel.RIGHT);
        JTextField lastField =new JTextField(10);
        JTextField middleField =new JTextField(10);
        JTextField firstField =new JTextField(10); //Add displayedMnemonic and label For property values
       
                  lastName.setDisplayedMnemonic('L');
        middleName.setDisplayedMnemonic('M');
        firstName.setDisplayedMnemonic('F');
        lastName.setLabelFor(lastField);
        middleName.setLabelFor(middleField);
        firstName.setLabelFor(firstField); //Layout and Display

        JPanel p =new JPanel();
        p.setLayout(new GridLayout(3, 2, 5, 5));
        p.add(lastName);
        p.add(lastField);
        p.add(middleName);
        p.add(middleField);
        p.add(firstName);
        p.add(firstField);

                JFrame f =new JFrame();
        f.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                        System.exit(0); }
                }
        );
        f.setContentPane(p);
        f.pack();
        f.setVisible(true);
        }
 }