패키지02 MyFrame
package frame02;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MyFrame extends JFrame{
//생성자
public MyFrame(String title) {
super(title);
setBounds(100,100,500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//흐르듯이 배치하는 레이아웃
setLayout(new FlowLayout(FlowLayout.LEFT));
JButton btn1=new JButton("버튼1");
add(btn1); //프레임에 btn1 추가하기
JButton btn2=new JButton("버튼2");
add(btn2);
JButton btn3=new JButton("버튼3");
add(btn3);
setVisible(true);
}
public static void main(String[] args) {
new MyFrame("나의 프레임2");
}
}
.setBounds(x,y,w,h) : x,y축 위치와 너비,높이 값을 받아 그 크기의 창을 생성
.setLayout(); : 레이아웃매니저 타입을 받아 해당 레이아웃으로 객체를 생성
- 메인메소드에서 new MyFrame("나의 프레임2") 에 이름넣으면 상단의 title로 전달된다.
- run해보면 버튼 3개가 생성되었다.
- 위에서부터 물 흐르듯이 배치되는 것을 flowLayout이라 한다.
- 창 크기를줄이면 알아서 좁게 배치되고, 기본은 가운데정렬이다.
- new FlowLayout(FlowLayout.LEFT); 하면 좌측정렬시킬 수도 있다.
- 들어갈 수 있는 타입이 LayoutManager 타입인데, new FlowLayout이 들어가진다는 것은,
FlowLayout은 상속받는 부모타입중에 LayoutManager가 있다는 뜻!
* FlowLayout 설명 : 링크
패키지03 MyFrame
package frame03;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MyFrame extends JFrame{
//생성자
public MyFrame(String title) {
super(title);
setBounds(100,100,500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//격자모양으로 배치하는 레이아웃
setLayout(new GridLayout(2,2));
JButton btn1=new JButton("버튼1");
add(btn1); //프레임에 btn1 추가하기
JButton btn2=new JButton("버튼2");
add(btn2);
JButton btn3=new JButton("버튼3");
add(btn3);
JButton btn4=new JButton("버튼4");
add(btn4);
setVisible(true);
}
public static void main(String[] args) {
new MyFrame("나의 프레임3");
}
}
- GridLayout
GridLayout(); : 격자형 레이아웃 (기본형태)
setLayout(new GridLayout(2,2));
- 위와 같은 형태로 입력하면 2*2 의 격자 모양으로 배치된다.
패키지04 MyFrame
package frame04;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MyFrame extends JFrame{
//생성자
public MyFrame(String title) {
super(title);
setBounds(100,100,500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//경계선을 따라 배치하는 레이아웃
setLayout(new BorderLayout());
JButton btn1=new JButton("버튼1");
add(btn1, BorderLayout.NORTH);
JButton btn2=new JButton("버튼2");
add(btn2, BorderLayout.EAST);
JButton btn3=new JButton("버튼3");
add(btn3, BorderLayout.SOUTH);
JButton btn4=new JButton("버튼4");
add(btn4, BorderLayout.WEST);
setVisible(true);
}
public static void main(String[] args) {
new MyFrame("나의 프레임4");
}
}
- Border Layout
- 상하좌우의 경계선(border)을 따라 배치한다!
- 다중정의된 add 중에서 Component, Object 인자를 받는 메소드로 사용
add(btn1, "North");
- 어느 쪽 border를 기준으로 할 것인지 옵션값을 따로 지정할 수도 있다.
- 이런 값은 미리 상수로도 만들어져 있다.
BorderLayout.NORTH(EAST/SOUTH/WEST) 로 입력해도 결과는 같다.
→ (상수화하는 이유) 잘 기억하고 쉽게 사용할 수 있도록 복잡한 문자열에 이름을 부여해주는 것!
패키지05 MyFrame
package frame05;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class MyFrame extends JFrame{
//생성자
public MyFrame(String title) {
super(title);
//this 예약어를 이용해서 MyFrame 객체의 다형성 확인!
MyFrame a=this;
JFrame b=this;
Component c=this;
Object d=this;
setBounds(100,100,500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JButton sendBtn=new JButton("전송");
add(sendBtn);
//ActionListener 인터페이스 type의 참조값 얻어내서
ActionListener listener=new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("전송 버튼을 눌렀네?");
JOptionPane.showMessageDialog(MyFrame.this, "전송합니다");
ActionListener f=this;
//Component f=this; (X)
Component g=MyFrame.this;
}
};
//전송버튼에 등록하기
sendBtn.addActionListener(listener);
/*
* 삭제 버튼도 프레임에 배치하고, 해당 버튼을 눌렀을 때 "삭제 버튼을 눌렀네?"라는
* 메세지를 콘솔창에 출력되도록 프로그래밍 해보세요.
*/
JButton deleteBtn=new JButton("삭제");
add(deleteBtn);
ActionListener listener2=new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("삭제 버튼을 눌렀네?");
JOptionPane.showMessageDialog(MyFrame.this, "삭제합니다");
}
};
/* deleteBtn.addActionListener((msg)->
* System.out.println("삭제 버튼을 눌렀네?"));
*/
deleteBtn.addActionListener(listener2);
}
public static void main(String[] args) {
MyFrame f=new MyFrame("나의 프레임5");
f.setVisible(true);
}
}
- 메인 메소드 안에서 setVisible 을 실행하고 싶다면?
- 메인메소드 안에서 선언한 f 라는 변수 안에 참조값을 넣어주면
f는 myFrame 메소드 안의 this와 같은 기능을 가질 수 있다.
- static 영역에 클래스가 올라가고(메인메소드에서 생성), heap영역에 객체가 생기는데(new로 생성)
f 에 참조값(24)이 들어가므로 f. 과 this. 는 같은 역할로 사용될 수 있다!
- 버튼을 클릭할 때마다 어떤 메소드가 실행되도록 하고 싶다면?
* javascript
<button id="one">
<script>
document.querySelector("#one").addEventListner("click", Function(){});
</script>
→ document.querySelector 으로 참조값을 얻어내고, 버튼을 클릭할 때마다 함수가 호출된다.
- 함수를 등록해뒀다가 call 되도록 하는데, 함수가 단독으로 존재할 수 있기 때문에 이게 가능한 것이다.
* java
- java에서는 특정 객체에 있는 특정 메소드가 호출되도록 해야 한다.
- JButton을 눌렀을 때 단순히 메소드가 호출되는 게 아니라 특정 객체에있는 메소드가 필요함!
→ JButton에 어떤일이 일어났을 때 호출될 메소드를 갖고있는 객체를 등록해야 한다.
약속된 메소드가 호출될 수 있도록!
- 이때 객체의 타입은 이미 설계되어 있음
.addActionListener( ); : 호출될 객체를 등록하는 메소드!
- () 안에는 반드시 호출될 메소드를 갖고 있는 객체 타입이 들어가야 한다.
- addActionListener 안에 들어갈 인자인 ActionListener의 타입을 확인해보니 인터페이스 타입이다.
- 참조값을 얻어내서 전송버튼의 인자로 전달할 수 있도록 하는 것.
- new ActionListener이라고 쓰면 오류가 발생한다.
인터페이스 타입은 단독 객체를 생성하지 못하기 때문에!
→ 이름 없는 익명클래스로 만들어주고 override하면 된다.
- 추상메소드 한개이므로 람다식으로도 작성할 수 있다.
- 이제 버튼을 클릭할 때마다 actionPerformed 메소드가 실행된다.
- 클릭시 실행시키고 싶은 기능이 있다면 저 메소드 안에 넣으면 된다!
[ MyFrame의 다형성 ]
MyFrame a=this;
JFrame b=this;
Component c=this;
Object d=this;
- 위 this는 MyFrame의 참조값을 가리키는 것이고
아래 this는 익명클래스안에서 생성한 객체의 참조값을 가리키는 것!
- innerclass 안에서 this 사용하기
ActionListener f=this; (O) → ActionListener 타입을 가리킨다.
Component f=this; (X) → ActionListener 타입, 외부클래스 MyFrame을 의미하지 않는다.
Component g=MyFrame.this; (O) → MyFrame을 가리킨다.
- inner class 안에서 밖에 있는 outer class의 객체의 참조값을 가리키고 싶다면 outerclass.this 형태로 쓰면 된다.
→ 바깥클래스명.this ex) Myframe.this
.showMessageDialog( , ) : Frame 위에 메시지 창를 띄우는 메소드이고, 2개의 인자를 받는다.
- Component 타입 : 어느 Component에 띄울 것인지(MyFrame의 참조값)
- String 타입: 어떤 내용을 띄울 것인지
JOptionPane.showMessageDialog(MyFrame.this, "전송합니다");
- 그냥 this라고 쓰면 받아지지 않는다. Component 타입을 넣어야 하기 때문에!
- 그래서 Myframe.this 라고 써준다.
분홍: 어떤 작업을 할 것인지(알림창 띄우기)
초록: 알림 메세지를 어느 프레임에다가 띄울 것인지
빨강: 알림창에 어떤 내용을 띄울 것인지
- 각각의 코드가 의미하는 바를 제대로 이해하기!
- 버튼의 동작을 구현하는 데 익명클래스를 사용한 예제
패키지06 MyFrame
- 똑같이 버튼의 동작을 구현하는데, 05와 다른 방법 사용하기!
package frame06;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class MyFrame extends JFrame implements ActionListener{
//필드
JButton sendBtn;
JButton deleteBtn;
//생성자
public MyFrame(String title) {
super(title);
setBounds(100,100,500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
//객체 생성해서 참조값을 필드에 저장
sendBtn=new JButton("전송");
add(sendBtn);
deleteBtn=new JButton("삭제");
add(deleteBtn);
sendBtn.addActionListener(this);
deleteBtn.addActionListener(this);
}
public static void main(String[] args) {
MyFrame f=new MyFrame("나의 프레임6");
f.setVisible(true);
}
/*
* 전송버튼, 삭제버튼을 누르면 호출되는 메소드
* 메소드 안에서 어떤 버튼을 눌렀는지 확인해서 분기해야한다.
* 메소드에 선언된 매개변수 ActionEvent e에 눌러진 버튼에 대한 정보갸 담겨 있다.
* 해당 객체를 활용해서 분기를 하면 된다.
*/
@Override
public void actionPerformed(ActionEvent e) {
//눌러진 버튼의 참조값 얻어내기
Object which=e.getSource();
if (which == sendBtn) {
JOptionPane.showMessageDialog(this, "전송합니다");
}else if(which == deleteBtn) {
JOptionPane.showMessageDialog(this, "삭제합니다");
}
}
}
먼저 sendBtn 을 구현하는데,
sendBtn.addActionListener(this);
- () 에 ActionListener 타입을 넣어야하는데, this가 Frame타입이라서 안 받아준다.
→ 그렇다면 Frame에 ActionListener(인터페이스)를 구현하면 된다.
구현한 후에 미완성 메소드를 @override 해주면 ActionListener 타입으로 받아들여준다.
- 인터페이스를 구현해서 사용하니 익명클래스를 사용하는것보다 좀더 간단하고 단순하다.
- 하지만 delete 버튼까지 같이 구현하려면? 아래와 같이 버튼 이름만 바꾼 같은 코드로는 사용할 수 없다.
deleteBtn.addActionListener(this);
JOptionPane.showMessageDialog(this, "삭제합니다");
- 분기를 나누어야 한다. 특정 버튼이 눌러졌을 때 각각 다른 분기로 실행되도록!
- 어떤 버튼이 눌러졌는지 확인할 수 있는 수단이 필요.
.getSource() : 어떤 액션이 일어난 ui(눌러진 버튼)의 참조값이 object타입으로 반환된다.
- 이렇게 분기를 나눠서 작동할 수 있도록 버튼값을 참조해야 하는데,
sendBtn, deleteBtn은 local변수라서 오류가 발생한다. 포함된 메소드 밖에서는 참조할 수 없다.
- MyFrame 안에 있는 변수인 sendBtn을 참조하려면 어떻게 해야 하는가?
→ 이렇게 객체 안의 다른 메소드에서 필요한 값은 지역변수가 아닌 필드에 담는 것이 좋다.
JButton sendBtn=new JButton("전송"); → sendBtn 지역변수를 선언하고 안에 참조값을 넣는 것
this.sendBtn=new JButton("전송"); → sendBtn 필드에 참조값을 넣는 것(this. 은 생략가능)
- 이와 같이 필드에 값을 넣어놓으면 객체 안에서 어디서든 참조해서 쓸 수 있다.
- 이렇게 하면 어떤버튼을 눌렀는지 알아내고 분기시켜서 사용할 수 있다!
- ActionEvent e 액션이벤트 객체는 우리가 생성하는 것이 아니다.
알아서 생성되어서 전달될 것이라는 걸 기대하고 작성하면 된다.
'국비교육(22-23)' 카테고리의 다른 글
20일차(3)/java 퀴즈 : Frame객체로 계산기 만들기 (0) | 2022.11.02 |
---|---|
20일차(2)/java(27) : Frame(3) (0) | 2022.11.02 |
19일차(4)/java(25) : Frame(1) (0) | 2022.11.01 |
19일차(3)/java(24) : Exception (0) | 2022.11.01 |
19일차(2)/java(23) : UtilClass (HashSet, Iterator) / While문 (0) | 2022.11.01 |