package swing;
import java.awt.FlowLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import event.WindowExit;
public class SwingTest1 extends JFrame{
private JButton btn; //버튼인스턴스변수 생성
private ImageIcon icon; //이미지를 저장하는 창고
private ImageIcon icon2; //이미지를 저장하는 창고
public SwingTest1() { //생성자
setLayout(new FlowLayout()); // 자동정렬
//addWindowListener(new WindowExit(this)); // x를 끄면 꺼진다.(awt에서 클래스를 만들어 사용)
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //x를 끄면 꺼진다.(Swing에서 사용)
btn = new JButton("버튼"); //버튼 인스턴스 생성
icon = new ImageIcon(getClass().getResource("/images/duke (1).gif")); //이미지를 불러온다.
icon2 = new ImageIcon(getClass().getResource("/images/duke (2).gif")); //이미지를 불러온다.
//경로가 /로 시작하면 절재로 경로가 바뀌지 않는 절대경로이다.
// /는 프로젝트의 처음 시작위치이다.
btn.setIcon(icon); //버튼을 누르면 이미지를 호출한다. JIcon의 메서드.
btn.setPressedIcon(icon2); //눌렀을 때 이미지가 바뀐다.
add(btn); //버튼을 Frame 추가
}
public static void main(String[] args) {
SwingTest1 test = new SwingTest1(); //클래스 인스턴스 생성
test.setSize(300, 400); //사이즈를 정함
test.setVisible(true); //창이 보여지게 함 창을 끄면 false 상태가 됨.
}
}
버튼이 바뀐다.
스윙은 테두리를 내가 원하는 테투리로 갈아 끼울 수 있다.
라벨에 테두리를 갈아 끼워보자.
java.desktop > javax.swing.boader
테두리를 모아놓은 패키지.
package swing;
import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.BevelBorder;
public class SwingTest2 extends JFrame{
private JButton btn;
private ImageIcon icon;
private JLabel lab;
public SwingTest2() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
btn = new JButton("버튼");
icon = new ImageIcon(getClass().getResource("/images/duke (3).gif"));
lab = new JLabel("스윙 라벨입니다.", icon, JLabel.CENTER);
//lab.setBorder(new EtchedBorder(Color.BLUE, Color.RED));//프레임의 틀을 바꾸자
lab.setBorder(new BevelBorder(BevelBorder.LOWERED));//프레임의 틀을 바꾸자
add(btn);
add(lab);
}
public static void main(String[] args) {
SwingTest2 test = new SwingTest2(); //클래스 인스턴스 생성
test.setSize(300, 400); //사이즈를 정함
test.setVisible(true); //창이 보여지게 함 창을 끄면 false 상태가 됨.
}
}
package swing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
//확인버튼이 떴을 때 글자가 그대로
public class SwingTest3 extends JFrame implements ActionListener, KeyListener{
private JTextField field;
private JButton btnOk;
private JLabel lab;
public SwingTest3(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
field = new JTextField(30);
btnOk = new JButton("확인");
lab = new JLabel("안녕하세요.");
add("Center", field);
add("East", btnOk);
add("South", lab);
btnOk.addActionListener(this);
field.addKeyListener(this);
}
@Override
public void actionPerformed(ActionEvent arg0) {
if(field.getText().isEmpty()) { //만약 값이 비어있다면
//값이 비어 있다면 확인하고 값을 넣어달라고 창을 띄운다.
//JOptionPane.showMessageDialog(null, "반드시 데이터를 입력하시오");
//값이 비어있다면 확인하고 값을 입력하기 위해 창을 띄움
//String name = JOptionPane.showInputDialog("이름을 입력하세요.");
//lab.setText(name);
//값이 비어있다면 선택한다. 앞의 null은 주소값인데 별 의미는 없다.
int result = JOptionPane.showConfirmDialog(null, "예/아니오 선택");
lab.setText(new String().valueOf(result)); //주소값이 나오게 한다.
}else {
lab.setText(field.getText());
}
}
@Override
public void keyPressed(KeyEvent e) { //엔터키를 치면 입력된다.
if(e.getKeyChar() == KeyEvent.VK_ENTER) {
lab.setText(field.getText());
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
SwingTest3 test = new SwingTest3(); //클래스 인스턴스 생성
test.setSize(300, 100); //사이즈를 정함
test.setVisible(true); //창이 보여지게 함 창을 끄면 false 상태가 됨.
}
}
<Swing에서 트리구조 만들기>
tree
'트리'를 보여줄 수 있게 해주는 하나의 공간을 '트리'라고 한다.
실제로 트리 안에 아이템을 만들어주는 클래스는 따로 있다.
DefaultMutableTreeNode
이 클래스는 트리구조의 아이템을 만들수 있도록 해준다.
트리에 어떻게 값을 넣을 수 있을까?
마우스 리스너의 기능 중 일부를 쓰기 위해 마우스 리스너를 상속받는 마우스 어댑터를 사용한다.
마우스를 눌렀을 때 이벤트가 발생하는 메소드 오버라이드해보자.
여기에 값을 넣으려면 두 개의 메서드를 이용하여 활용한다.
java.desktop > JTree
.getRowForLocation() 행의 위치를 알고 싶을 때 사용
.getPathForLocation() 경로와 위치를 알고 싶을 때 사용
final JTree tree = ...;
MouseListener ml = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int selRow = tree.getRowForLocation(e.getX(), e.getY());
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
if(selRow != -1) {
if(e.getClickCount() == 1) {
mySingleClick(selRow, selPath);
}
else if(e.getClickCount() == 2) {
myDoubleClick(selRow, selPath);
}
}
}
};
tree.addMouseListener(ml);
getRowForLocation(e.getX(), e.getY())
getRowForLocation 행의 위치를 알려줄 때 사용
(MouseEvent e)의 x좌표 y좌표는 (e.getX(), e.getY())
이렇게 행의 위치를 알려준다.
getPathForLocation 은 경로와 위치를 알고 싶을 때 사용
package swing;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
public class SwingTest4 extends JFrame{
private JLabel lab; // 레이블 변수를 만든다.
private JTree tree; // 트리구조의 구조공간 변수 생성
private JScrollPane scroll; // 비어있는 스크롤이 달려있는 판을 준비하고
// 트리구조를 담을 수 있도록 한다.
public SwingTest4() {
//트리구조의 아이템을 만들어 준다.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode root =
new DefaultMutableTreeNode("커피");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode step1 =
new DefaultMutableTreeNode("자바 커피");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode step2 =
new DefaultMutableTreeNode("원두 커피");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode step2_1 =
new DefaultMutableTreeNode("아메리카노");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode step2_2 =
new DefaultMutableTreeNode("헤이즐넛");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode step2_3 =
new DefaultMutableTreeNode("라떼");
root.add(step1); //root에 step1,2 를 담는다.
root.add(step2);
step2.add(step2_1); // step2에 step2_1,2,3을 담는다.
step2.add(step2_2);
step2.add(step2_3);
tree = new JTree(root); //트리의 인스턴스를 생성하고
scroll = new JScrollPane(tree); //스크롤바 판에 트리를 붙여 인스턴스 생성
lab = new JLabel("여기에 선택한 항목이 나타납니다."); //라벨을 붙힌다.
add(scroll); //트리 붙은 스크롤바 판을 프레임에 더한다.
add("South", lab); //아래쪽에 라벨을 프레임에 더한다.
tree.addMouseListener(new TreeMouseHandler()); //핸들러를 만든다.
}
class TreeMouseHandler extends MouseAdapter{
//마우스 리스너의 기능 중 일부를 쓰기 위해 마우스 리스너를 상속받는 마우스 어댑터를 사용한다.
@Override //마우스를 눌렀을 때 이벤트가 발생하는 메소드 오버라이드
public void mousePressed(MouseEvent e) {
//System.out.println(tree.getRowForLocation(e.getX(), e.getY())); //행의 위치를 알고 싶을 때 사용
//System.out.println(tree.getPathForLocation(e.getX(), e.getY())); //경로와 위치를 알고 싶을 때 사용
int row = tree.getRowForLocation(e.getX(), e.getY()); //행의 위치값을 row변수에 담는다.
TreePath path = tree.getPathForLocation(e.getX(), e.getY());//path라는 리턴값에 경로와 위치를 담는다.
//누르면 누른 값이 마지막 값으로 나온다.
if(row != -1) { //선택했을 때만 결과가 나올 수 있도록 처리한다.
lab.setText(path.getLastPathComponent().toString());
//lab변수안에
//.setText()안의 문자를 넣어라.
//path.getLastPathComponent().toString()의 문자를 넣어라
//path.getLastPathComponent()는 행의 마지막 값을 아래에 출력
}
}
}
public static void main(String[] args) {
SwingTest4 test = new SwingTest4(); //클래스 인스턴스 생성
test.setSize(300, 400); //사이즈를 정함
test.setVisible(true); //창이 보여지게 함 창을 끄면 false 상태가 됨.
}
}
2) MVC(Model View Controller) 패턴 설계
- 쉽게 말하면 역할분담이다.
- 데이터는 별도로 따로 처리하자
- 하나의 데이터로 다양하게 활용하자.
mvc는 역할이다.
- M 데이터, 자료이다.
- C 모델과 뷰의 관계의 소통이 원활 할 수 있도록 제어, swing에서는 내장되어 있다.
- V 뷰는 보여지는 것, 디자인
- mvc를 기반으로 다양한 모델들이 파생된다.
- 데이터와 테이블은 분리되어 있다. 테이블은 뷰의 역할이다.
- 뷰는 데이터의 주로를 가지고 있다.
package swing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;
public class SwingTest5 extends JFrame implements ActionListener{
private JTable table;
private JButton btnDisplay;
private String title[] = {"이름", "나이", "성별"}; //타이틀 데이터 준비
private String data[][] = { //테이블에 들어갈 데이터 준비
{"홍길동", "20", "남자"},
{"임꺽정", "22", "남자"},
{"신사임당", "25", "여자"}
};
private JScrollPane scroll;
public SwingTest5() {
//x버튼 누르면 끝남
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//인스턴스 생성
table = new JTable(data, title);
scroll = new JScrollPane(table);
btnDisplay = new JButton("콘솔에 출력");
//fram에 붙여줌
add("Center", scroll); //스크롤 바를 넣으면 없던 제목이 생긴다.
add("South", btnDisplay); //제목을 보고 싶으면 스크롤 바를 넣어야한다.
btnDisplay.addActionListener(this); //액션 리스너를 만들어 준다.
}
@Override
public void actionPerformed(ActionEvent e) {
TableModel model = table.getModel(); // 뷰인 테이블이 가리키는 데이터의 주소를 가져온다.
for(int i=0; i<model.getColumnCount(); i++) { //열의 개수
System.out.print(model.getColumnName(i) + "\t"); //제목을 출력한다.
}
System.out.println();
System.out.println("----------------------------------");
for(int i=0; i<model.getRowCount(); i++) { //행의 개수만큼 출력할 수 있게
for(int j=0; j<model.getColumnCount(); j++) { //열의 개수만큼 출력할 수 있게
System.out.print(model.getValueAt(i, j) + "\t"); //.getValueAt(i, j) 행과 열의 데이터를 출력하겠다.
}
System.out.println();
}
}
public static void main(String[] args) {
SwingTest5 test = new SwingTest5(); //클래스 인스턴스 생성
test.setSize(300, 400); //사이즈를 정함
test.setVisible(true); //창이 보여지게 함 창을 끄면 false 상태가 됨.
}
}
출력하면 이클립스에 결과가 나온다.
※ 콘솔 출력 값
이름 나이 성별
----------------------------------
홍길동 20 남자
임꺽정 22 남자
신사임당 25 여자
package swing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.MouseInputListener;
import javax.swing.table.DefaultTableModel;
//https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html 참조
public class SwingTest6 extends JFrame implements ActionListener, FocusListener{
private JTable table; //인스턴스 변수 생성
private JScrollPane scroll;
private String title[] = {"이름", "나이", "성별"};
private JButton btnAdd, btnDel;
private JPanel panel;
private JTextField tfName, tfAge, tfGender;
public SwingTest6() {//////////////////////////////////////생성자
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
///////////////////////////////////////////////////////인스턴스 변수생성
btnAdd = new JButton("추가");
btnDel = new JButton("삭제");
tfName = new JTextField("이름", 6);
tfAge = new JTextField("나이", 3);
tfGender = new JTextField("성별", 2);
panel = new JPanel();
//데이터의 실체가 없기 때문에 데이터가 있는 모델객체를 따로 만들어야 데이터를 가져올 수 있다.
DefaultTableModel model = new DefaultTableModel(title, 0);
//데이터를 보관할 수 있는 model 객체를 만들어 준다.
table = new JTable(model); //데이터를 모델객체에 담아준다.
scroll = new JScrollPane(table);//스크롤바에 테이블을 담아준다.
add("Center", scroll); //프레임 가운데에 스크롤바와 테이블을 담아준다.
panel.add(tfName); //패널에 이름을 담아준다.
panel.add(tfAge); //패널에 이름을 담아준다.
panel.add(tfGender); //패널에 이름을 담아준다.
panel.add(btnAdd); //패널에 이름을 담아준다.
panel.add(btnDel); //패널에 이름을 담아준다.
add("South", panel); //프레임 아래에 패널을 담아준다.
btnAdd.addActionListener(this);//addActionListener 핸들러를 만들어 준다.
btnDel.addActionListener(this);
tfGender.addFocusListener(this);//addFocusListener 핸들러를 만들어준다
tfAge.addFocusListener(this);
tfName.addFocusListener(this);
}
@Override //액션 오버라이드 메서드를 만든다.
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("추가")) { //"추가"를 눌렀을 때
//연관된 데이터이므로 배열로 3개를 준비한다.
String[] data = new String[3];
data[0] = tfName.getText();
data[1] = tfAge.getText();
data[2] = tfGender.getText();
//table의 자식클래스인 DefaultTableModel에 모델의 주소를 테이블에 물어본다.
DefaultTableModel model = (DefaultTableModel)table.getModel();
//모델에 한 행에 데이터를 추가한다.
model.addRow(data);
}
else {
//System.out.println(table.getSelectedRow());//삭제 버튼을 누르면 선택 행 주소가 출력됨
int row = table.getSelectedRow();
if(row == -1) { //로우 값이 없다면 -1이라면
JOptionPane.showMessageDialog(null, "반드시 선택해야합니다.");
return; //현재위치에서 즉시 원위치로 돌아간다. 메서드 종료.
//actionPerformed를 호출한 놈에게 돌아감 -> 시스템으로 돌아감 = 종료
}
else {
//table의 자식클래스인 DefaultTableModel에 모델의 주소를 테이블에 물어본다.
DefaultTableModel model = (DefaultTableModel)table.getModel();
//모델에 선택된 현재 행에 데이터를 삭제한다.
model.removeRow(row);
}
}
}
@Override//클릭하면 이름이 지워지고 입력이 가능하도록 포커스 리스너를 만든다.
public void focusGained(FocusEvent arg0) {
JTextField add = (JTextField)arg0.getComponent();
//add.setText("");
add.setText(add.getSelectedText());
//.setText() 수정하는 메소드
//.getSelectedText() 이 TextComponent에 격납되어있는 선택된 텍스트를 돌려줍니다.
//선택 범위가 null이거나 문서가 비어 있으면 null을 반환합니다.
}
@Override
public void focusLost(FocusEvent arg0) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
SwingTest6 test = new SwingTest6(); //클래스 인스턴스 생성
test.setSize(300, 400); //사이즈를 정함
test.setVisible(true); //창이 보여지게 함 창을 끄면 false 상태가 됨.
}
}
'개발 > Java' 카테고리의 다른 글
[java] 네트워크 Network (0) | 2017.11.09 |
---|---|
[java] Swing으로 만들어진 Demo파일 받아보기 (0) | 2017.11.09 |
[java] 윈도우 프로그래밍 Window Programming (1) | 2017.11.05 |
[java] 스레드 Thread (0) | 2017.11.02 |
[java] 이클립스에서 자바 파일 압축하기! (0) | 2017.10.31 |