728x90
마우스를 뗀시점에 그림이 완성되고
그후에 그림정보를 저장해야하기 때문에 
mouseReleased를 만들어 도형을 저장할
ShapeDTO타입의 변수 dto를 new 해준다
그림을 그리고 안없어지게 할려면 그렸던 도형의 좌표, 채우기, 도형의 정보들을 
그림이 사라지는 시점인 마우스를 다시 클릭하기 전에
(repaint 하기전에)
shapeDTO로 저장해야 한다.
도형을 선택하고 드래그해서 모양과 크기를 잡고 마우스를 떼는 동작 mouseReleased에 값들을 저장해야 하니깐
이곳에 new를 해주고
좌표값들을 dto에 입력(set)해준다.
getText()를 하면 string타입이오고 그걸
integer.parseInt로 int타입으로 변환한다.

그럼 드래그해서 그린 그림의 정보가 
마우스를 떼면 DTO에 저장된다.
도형1개의 정보를 담을 dto를 만들었는데 담을 배열을 안만들었다.
도형1개의 정보가 담긴 dto를 담을 list를 필드에 만들고
list라는 변수를 만든다.
정보를 list.add(dto)로 저장한다
이렇게 list에 그린 그림들의 값이 저장되야 한다.
list.size를 통해 list에 저장된 것들을 확인할 수 있다.

이제 저장되는게 확인되니깐 화면에 그림이 남게 만들어야 한다.

그림을 그리는 메소드는 MsPaint클래스가 아닌 DrCanvas에 있다.
거기에 list가 안지워지게 list에 저장된 정보들을 처음에 출력할 수 있게 만들어야 한다.
for를 이용
근데 private으로잡았기 떄문에 getter를 만들어서
DrCanvas클래스에서 list를 사용할 수 있게 만든다
그리고 불러올 값들을 선언한다.

근데 아직 그리기 버튼을 완성 안했다

지금상태는 그림을 그리고 그리기를 안눌러도 저장이 된다.
그리기 버튼을 눌렀을때 저장이 될 수 있도록 
mouseReleased에서 작업을 해야한다.
이거는 클릭은 했는데 드래그를 안했는데도 도형으로 인식되서 list에 담기는걸 막는 코드이다.
새로잡은 x1,y1과 마우스를 클릭해서 얻은 좌표값이 같으면
움직이지 않은거니까 return;을 해서 그 밑에 있는 
ShapeDTO dto = new ShapeDTO();를 
실행하지 못하게 만든다.

연필기능 작성

펜기능은 mouseDragged에서만 일어난다.
근데 지금 이상태는 드래그를 할때
그려지고
rqpaint하고
그려지고해서 선을 드래그하는게 안남는다.
ShapeDTO dto = new ShapeDTO();를 입력해서
드래그해서 그린 것들을 저장하는 부분을 만들어야지
지워지지 않고 드래그한 정보가 남는다
윗부분 끌어다쓰고
펜추가
이게 마우스가 조금이라도 움직여서 좌표가 1이라도 변경되면 첫번째 줄부터 add까지가고
그다음에 x1t,y1t에 x2t,y2t값을 넣고
다시 생성하고 
반복하면서 그전에 그린 기록을 남기면서 그려나간다.

add가 계속 되면서 list에 저장된 배열의 수가 계속 늘어난다.
 consol창을 확인해보면 펜으로 그리고 도형을 그려보면 
배열의 수가 몇백으로 늘어난걸 볼 수 있다.

여기까지 하면 펜이 동작하는데 움직일떄마다 repaint되서 번쩍거린다
그걸 잡는 과정

더블버퍼

지금까지 화면에다 직접 그려서 깜빡거린건데 지금부터 할거는 다른데다 그려서 옮기는 과정이다.
다 그리고 마지막에 옮기기 때문에 번쩍거리지 않는다.

똑같은 크기의 canvas를 버퍼에 만들고 그림을 그린다음에 
마지막에 원래의 canvas로 옮긴다.

좌표생성하고 그림그리고 뭐하고 한거를 
버퍼에 만든다. 
이건 콜백 메소드라서 repaint할때불린다.
update()-paint()순으로 호출한다.
근데 지금까지는 update클래스를 안만들었기 때문에
바로 paint()로 갔다.
작동 순서가 이렇게 된다.
bufferImage는 파란색 그림판이고
bufferG는 그위에 그린 이미지다
먼저 paint에 있던 것들을 전부 upate로 옮겼따
먼저 필드 설정
getSize는 기존의 그림판 사이즈를 그대로 가져온다.


기존의 g를 모두 bufferG로 바꾼다

 

paint()에 코드를작성하면
update에서 그린 이미지판을 그대로 paint에 붙여넣기한다. 

 

선을 그릴때 반짝임을 없앨려면 저렇게한다
근데 선은괜찮은데 도형을 만들때 잔상이 남는다.
잔상을 지우기 위해서 
일단 그림을 그리면 무수히 많은 잔상이 생기고
잔상 한개당 캔버스만한 바탕색의 이미지가 그위에 덮혀지고 
마지막 그림만 남겨진다.
   

지우는 과정은 그린걸 없애는게 아니라 바탕색으로 덧칠하는 과정이다.



IOExcetion

값을 저장하고 한번에 읽은건데
일단 data.txt에 있는 정보를 배열에 저장하고 읽을 거다
 
나온다
   


일단 창생성
이렇게 만들거다
창에 menu을 만들거다
새로운 클래스를 만들어 그림처럼 만든다


메인창에 코드를생성해서 연결하면
결과가 나온다
이렇게 하면
이렇게 생긴다

버튼에 동작을 넣자
implement하고
이벤트가 많아질거니까 따로 메소드를 만들고
메인메소드에 작업을 한다

이렇게 하면 종료가 먹힌다

근데 MenuPane에 각 메뉴들을 private로 만들었기 때문에 getter를 만들어야 한다.
각 버튼에 대한 이벤트를 만들거니까 다 만들어 준다.
메뉴에 맞는 메소드 구현
다 만들어져 있따
단축키는 이렇게 넣는다
외우자
ctrl을 사용하면 윈도우랑 겹쳐서 동작이 되는지 안되는지 모른다.
alt로 하자


종료 구현은 디폴트 값을 먼저 설정해야 한다.

JFrame은 종료버튼을 누르면 완전히 종료되는 것이 아니라 윈도우창은 숨겨지고  consol은 실행되는 중이다.

그래서 setDefaultCloseOperation()라는 메소드를 선언하고 종료에 대한 디폴트값을 설정해줘야 한다.

기본생성자에 선언을 하는데
EXIT_ON_CLOSE와 DO_NOTHING_ON_CLOSE 두가지가 있다.

EXIT_ON_CLOSE를 하면 무슨 버튼을 누르든 항상 종료가 되고

DO_NOTHING_ON_CLOSE를 하면 종료확인에만 종료가 되고 취소버튼에는 종료가 되지 않는다.


종료버튼 활성화

ActionListener의 메소드를 오버라이드 한 곳에서 exit를 찾는다

종료에 관한 메소드를 구현해준다.
YES_NO_CANCEL_OPTION이 enum으로 상수로 설정되어있는 메소드이다.
차례대로 yes는 0, no 는 1, cancel은 2으로
if문을 통해 각 상황에 맞게 구현한다.

이 부분은 메뉴에서 종료를 눌렀을때 나오는 팝업이고

 

이 부분이 윈도우에서 x창을 눌렀을 때 나오는 팝업이다.
728x90

+ Recent posts