JAVA2 - Day4 - GridBagLayout, Canvas

<기본적인 프레임 틀 복습하기>
package com.layout;

public class Main {

public static void main(String[] args) {
MyFrame my=new MyFrame("AWT",300,300);

my.setVisible(true);

}


}
------------------------------------------------------------------------------------
package com.layout;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class MyFrame extends Frame{
public MyFrame(String title, int width, int height) {
//title
setTitle(title);
//size 
setSize(width, height);
//window event
// - local inner class
/*
class MyWindow extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
MyWindow win=new MyWindow();
addWindowListener(win);
*/
// -anonymous class
/*
WindowAdapter win=new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
addWindowListener(win);
*/
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
<GridBagLayout을 이용한 Calculator 만들기>
package com.calc;

public class Main {

public static void main(String[] args) {
Myframe my = new Myframe("CALC",400,400);
my.setVisible(true);

}

}
------------------------------------------------------------------------------------
package com.calc;

import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.TextField;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Myframe extends Frame {

GridBagConstraints c;
TextField input; //계산기에서는 원래 결과창이 TextField 아닌데 편의상.
Button[] calc;
public Myframe(String title, int width, int height) {
//title
setTitle("title");
//size
setSize(width, height);
//x버튼 event (window event)
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//#1
//계산기 서식 만들기
init();
//#2
//계산기 기능 만들기
myEvent();
}

public void init() {
//LayoutManager
// - GridBagLayout
// - GridLayout을 일반화 한 레이아웃
// - GridLayout의 단점 : 모든 컴포넌트가 동일한 사이즈.
// - GridBagLayout은 이것을 보완했다.
// - 하나의 Component가 다수의 격자를 차지할 수 있다.
// - 자유도가 높을수록 복잡함... 이것도 복잡해!!
GridBagLayout grid = new GridBagLayout();
setLayout(grid);
//여태까지는 add(컴포넌트);를 하면 됐었다.
//그러나 GridBagLayout는 필요한 객체가 있다. >> GridBagConstraints c; 
//형식  : add(컴포넌트,c)
c = new GridBagConstraints();
//여백
c.weightx = 1.0; c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
/*
//위치
c.gridx = 0; c.gridy = 0;
//크기
c.gridwidth = 1; c.gridheight = 1;
Button bt1 = new Button("one");
add(bt1,c);
*/
//하나더 추가한다고 생각할떄 겹치는 부분이 있을 수 있다.
//변수는 변경/삭제하기 전까지는 유지된다.
//즉, 여백은 냅두고 위치와 크기만 바꾸는 식으로도 할 수 있다.
//일일이 다 바꾸기 귀찮으니까 메서드를 만들자. >>setComp
//위의 코드를 이렇게 바꿀 수 있다.
//setComp(0,0,1,1,new Button("one"));
//계산기를 만들어 보자.
input = new TextField();
calc = new Button[23];
//글자 정보를 String 배열로 넣어주자.
String  [] calcList = { //ㄷ한자 하면 수학 기호 나온다!
"<-", "CE", "C", "±", "√", 
"7", "8", "9", "/","%", 
"4", "5", "6", "*", "1/x", 
"1", "2", "3", "-","=",
"0", ".", "+"};
for(int i=0; i<calc.length; i++) {
calc[i] = new Button(calcList[i]);
}

//버튼 배치하기
setComp(0,0,5,1, input);
setComp(0,1,1,1,calc[0]);
setComp(1,1,1,1,calc[1]);
setComp(2,1,1,1,calc[2]);
setComp(3,1,1,1,calc[3]);
setComp(4,1,1,1,calc[4]);
setComp(0,2,1,1,calc[5]);
setComp(1,2,1,1,calc[6]);
setComp(2,2,1,1,calc[7]);
setComp(3,2,1,1,calc[8]);
setComp(4,2,1,1,calc[9]);
setComp(0,3,1,1,calc[10]);
setComp(1,3,1,1,calc[11]);
setComp(2,3,1,1,calc[12]);
setComp(3,3,1,1,calc[13]);
setComp(4,3,1,1,calc[14]);
setComp(0,4,1,1,calc[15]);
setComp(1,4,1,1,calc[16]);
setComp(2,4,1,1,calc[17]);
setComp(3,4,1,1,calc[18]);
setComp(4,4,1,2,calc[19]);
setComp(0,5,2,1,calc[20]);
setComp(2,5,1,1,calc[21]);
setComp(3,5,1,1,calc[22]);
}

public void setComp(int posX, int posY, int width, int height, Component comp) {
c.gridx = posX; c.gridy= posY;
c.gridwidth = width; c.gridheight=height;
add(comp, c);
//여기서 컴포넌트도 매개변수로 받아야하는데 어떻게 할까?
//이 컨테이너에 어떤 컴포넌트를 붙일지 다를 수 있다. (버튼, 라벨 etc..)
//컴포넌트 타입이라고 매개변수에 넣어주자.
//컴포넌트의 자손타입이면 뭐든 넣을 수 있다.
}

public void myEvent() {
//calc버튼에 마우스를 올리면 주황색으로 변경해주고,
//내리면 하얀색으로 변경해주기.
for(int i = 0 ; i<calc.length;i++) {
calc[i].addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
//마우스가 영역 안으로 들어갈 때 호출되는 메소드
//System.out.println("들어옴");
Button bt = (Button)e.getSource();
bt.setBackground(Color.orange);
}
@Override
public void mouseExited(MouseEvent e) {
//마우스가 영역 밖으로 나갈 때 호출되는 메소드
//System.out.println("나감");
Button bt = (Button)e.getSource();
bt.setBackground(Color.WHITE);
}
@Override
public void mouseClicked(MouseEvent e) {
//계산, 출력... etc
}
});
}
}
}
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
<Canvas>
package com.canvas;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;

//Component 클래스
// -Label, Button , TextField, TextArea, ... , Canvas

//Canvas
// - 그래픽적인 화면을 그리는 요소 객체
// - Panel - Component를 올릴 수 있음.
// - Canvas - 그림을 올릴 수 있음.

public class MyCanvas extends Canvas{
int posX = 50;
int posY = 50;
public MyCanvas() {
setBackground(Color.BLACK);
}
//그림을 그리려면 paint 메소드를 오버라이딩해야한다.
@Override
//메서드는 호출해야 실행이 되어야 하는데 paint는 자동으로 창이 켜질때마다 실행된다.
//즉, 프로그래머가 호출할 필요가 없다.
public void paint(Graphics g) {
//붓: g
/*
g.setColor(Color.YELLOW);
//시작점 좌표와 끝점 좌표를 픽셀단위로 지정해주기.
//그림은 순서대로 그려진다.
g.drawLine(50, 50, 100, 100);
g.drawRect(50, 50, 100, 100);
//원이 그려지는 방식은 사각형을 설정한 후, 그 사각형에 접하도록 그려진다.
g.setColor(Color.RED);
g.fillOval(100, 100, 100, 100);
*/
//Canvas의 키포인트는 이미지!!!!!!!
//image
//Toolkit t= new Toolkit();
//바로 객체생성하려면 에러난다.
//Toolkit은 추상클래스이기 때문.
//Toolkit의 추상클래스 말고 일반적 메서드를 이용하자
Toolkit t = Toolkit.getDefaultToolkit();
Image img = t.getImage("star.png");
//사진 파일이 같은폴더 안에 있으므로 이름만 써도 된다.
//절대 경로와 상대경로 차이!
//같은 폴더에 없다면 주소를 써주어야 한다.
//g.drawImage(/*이미지, 좌표, 크기, 위치*/img, 50, 50, 50, 50, this);
//별의 위치를 키보드를 눌러서 계속 바꿔보자.
//위의 좌표는 상수니까 instance변수를 만들어 보자.
g.drawImage(img, posX, posY, 50, 50, this);
}

}
------------------------------------------------------------------------------------
package com.canvas;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class MyFrame extends Frame {
Label sub;
MyCanvas can;
public MyFrame(String title, int width, int height) {
setTitle(title);
setSize(width, height);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
init();
}
public void init() {
BorderLayout border = new BorderLayout();
setLayout(border);
sub = new Label("Canvas");
add(sub,BorderLayout.NORTH);
can = new MyCanvas();
add(can,BorderLayout.CENTER);
}
}
------------------------------------------------------------------------------------
package com.canvas;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class Main {

public static void main(String[] args) {
MyFrame my= new MyFrame("Canvas",400,400);
my.setVisible(true);
//Canvas 크기??
// getWidth(), getHeight()
System.out.println(my.can.getWidth());
System.out.println(my.can.getHeight());
//Canvas에 접근할 수 있으면 어디서든 Event를 만들 수 있다.
my.can.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
//System.out.println(e.getKeyCode());
//방향키는 좌상우하 37,38,39,40임을 알 수 있다.
/*
switch(e.getKeyCode()) {
case 37: //왼쪽이동
my.can.posX -= 4.7;
break;
case 38:
my.can.posY -= 4.7;
break;
//Y좌표는 수학적 좌표와 반대임을 유의하자.
case 39:
my.can.posX += 4.7;
break;
case 40:
my.can.posY += 4.7;
break;
case 32: //spacebar
System.out.println("스페이스 바");
break;
//그러나 방향키만 누르면 위치가 바뀌지 않는다.
//다시 그려야 위치가 바뀌므로 창을 축소했다가 다시 띄워야 한다.
}
//이를 방지하기위해 다시그리도록 만들자.
my.can.repaint();
*/
//문제1
//대각선으로는 이동하지 못한다.
//둘다 참일 수는 없기 때문이다.
//스페이스바를 통해서도 알 수 있다.
//동시에 입력이 안되므로 걸으면서 점프라던지 점프하면서 공격하기 같은 행동을 할 수가 없다.
    //이를 해결하기 위해 멀티쓰레드를 이용한다.
    //한번에 한가지 작업만 하는 것을 싱글쓰레드라고 한다.
//문제2
//이미지가 움직이면서 자주 깜빡인다. 점멸현상.
//repaint하고 있기 때문이다.
//즉, 지우고 다시 그리는 순간이 깜빡이는 것처럼 보인다.
//이미지가 많을수록 이 효과가 더 심하다.
//이를 해소하기위해 doubleBuffering을 사용한다.
    //Swing 패키지에서는 자동으로  doubleBuffering작업을 해주기때문에 고려할 필요 없다.
//문제3
//별이 화면 밖으로 나간다.
//switch문에서 조건을 달아주자.
switch(e.getKeyCode()) {
case 37: /*왼쪽이동*/
if(my.can.posX>=4.7) {
my.can.posX -= 4.7;
}
break;
case 38:
if(my.can.posY>=4.7) {
my.can.posY-= 4.7;
}
break;
//Y좌표는 수학적 좌표와 반대임을 유의하자.
case 39:
if(my.can.posX <=350.6) {
my.can.posX+= 4.7;
}
break;
case 40:
if(my.can.posY<=350.6) {
my.can.posY+= 4.7;
}
break;
case 32: //spacebar
System.out.println("스페이스 바");
break;
}
my.can.repaint();
}
});
}

}

댓글

이 블로그의 인기 게시물

11 - Scanf

JAVA - Day3 - Scanner, if, if else

JAVA - Day5 - Array,Random