소고기무국 맛있게 끓이는 법! 맛보장 황금 레시피!

카테고리 없음|2022. 3. 22. 19:47
반응형

요즘처럼 추운 날씨엔 뜨끈한 국이 최고죠?

제철인 무 듬뿍 넣고, 구수하게 끓여낸 소고기무국 한 그릇이면

밥 한공기 뚝딱!

고기를 볶지 말고, 푹 끓여내 진하고 구수하게!

맛보장 레시피 알려드릴테니 맛있게 끓여 드세요 :)

 

-준비재료

국거리소고기 300g, 물 2L

다시마2장, 대파뿌리1개, 후추

무1/5개, 대파1대

국간장 2큰술, 다진 마늘 1큰술, 천일염 1/3큰술

 

-레시피

1. 국거리용 소고기를 물에 한 번 씻어 핏물을 제거해준 뒤 키친 타올로 핏물을 제거해줍니다.

2. 대파와 무를를 썰어서 준비해주세요.

3. 끓는 물 2L에 소고기를 넣고 끓여줍니다.

반응형

4. 물이 끓어오르면 불순물 거품을 걷어내 줍니다.

5. 다시마와 대파 뿌리, 후추를 넣고 약불에서 30분 간 푹 끓여주세요.

6. 중간에 끓어오르면 다시마는 건져내고, 30분 뒤 대파뿌리도 건져냅니다.

7. 썰어둔 무를 넣고, 국간장과 천일염, 다진마늘로 간을 합니다.

8. 무가 어느정도 익으면 대파를 넣고 5분간 더 끓여주세요.

9. 부족한 간은 소금으로 맞춰줍니다.

맛있는 소고기무국 완성~!

다른 레시피 보러가기

 

 

'황금레시피' 카테고리의 글 목록

황금 레시피를 알아봐요!

programmingworld1.tistory.com

 

유튜브에서 보기

https://www.youtube.com/watch?v=-xBDCsG0qc0

출처 : 햇살한스푼

반응형

무생채 만드는 법

황금레시피|2022. 3. 22. 19:45
반응형

이맘때 절대절대 빠질 수 없는 반찬 한가지!

바로 그냥 먹어도 맛있는 무를 새콤달콤 무쳐먹는

무생채가 그 주인공이죠^^

 

무를 절여서 만들면 오래 보관할 수 있다는 장점이 있고

절이지 않고 바로 만들면 아주 간단하면서도 입맛 돋구는 훌륭한 반찬이 된다는 장점이 있지요!

 

이번엔 백종원 무생채 스타일로~

절이지 않고 만들어 보았는데요,

몇가지 양념만 제 입맛에 맞춰 가감했답니다 :)

10분반찬! 훌륭한 밥도둑입니다~

무생채무침 만드는법은 영상으로 자세히 만나보세요 :)

 

* 준비재료 

무1/2개, 쪽파 조금 

고춧가루4, 액젓2, 설탕2(또는 물엿3), 식초2, 다진마늘0.5 

전 여기에 매실액2 + 소금 두꼬집 추가요~ 

통깨, 참기름 (취향껏) 

* 레시피 

1. 무의 껍질을 깎고 깨끗이 씻어 길이 방향으로 채를 썰어 줍니다.

2. 그릇에 채썬 무를 담아 고춧가루로 버무려 색을 입혀줍니다. 

반응형

3. 액젓, 설탕 또는 물엿, 식초, 다진마늘을 넣고 버무려줍니다. 

4. 간을 보고 싱거우면 소금을 조금 넣어 간을 맞춰주세요.

마지막으로 쪽파, 참기름, 통깨를 넣어 마무리해 줍니다. 

다른 레시피 보러가기

 

'황금레시피' 카테고리의 글 목록

황금 레시피를 알아봐요!

programmingworld1.tistory.com

 

유튜브에서 보기

https://www.youtube.com/watch?v=4H6vbCXl35E

출처 : 햇살한스푼

반응형

안드로이드 : 액션바 제목설정, 뒤로가기 버튼 만들고 리스너 달기

안드로이드|2018. 12. 18. 10:54
반응형


@Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_third);


        ActionBar actionBar = getSupportActionBar();  //제목줄 객체 얻어오기

        actionBar.setTitle("안녕하세요");  //액션바 제목설정


        actionBar.setDisplayHomeAsUpEnabled(true);   //업버튼 <- 만들기

        //업버튼이 되려면 눌렀을 때 돌아갈 Activity를 지정해줘야 함

        //이 작업은 매니패스트에서 함

    }


매니패스트

<activity android:name=".ThirdActivity" android:parentActivityName=".MainActivity"></activity>

※ 뒤로가기를 하려면 백스택에 그 액티비티가 살아있어야 함


반응형

안드로이드 : 클릭 리스너 Long클릭시 Short 클릭 인식 안되게 하기

안드로이드|2018. 12. 14. 11:09
반응형

아래와 같이 한개의 버튼에 클릭 리스너를 두개 달 경우 롱 클릭 이후 숏클릭이 인식되는 문제가 있습니다.


이럴 경우엔 아래 Long클릭 리스너에서 리턴값을 true로 주면 되는데 여기서 리턴은 여기서 메시지를 모두 소비하고 끝낼것인지를 묻는 것입니다.



listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

    @Override               

    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        

        Toast.makeText(MainActivity.this, "안녕", Toast.LENGTH_SHORT).show();

    }

});

listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

    @Override

    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

        Toast.makeText(MainActivity.this, "long click", Toast.LENGTH_SHORT).show();

        return true

    }

});



반응형

안드로이드 : 다이얼로그(Single / MultipleChoice)

안드로이드|2018. 12. 12. 15:32
반응형



clickBtn 메소드는 xml에서 onClick 속성을 이용한 것입니다.



public class MainActivity extends AppCompatActivity {

    String[] items = new String[] {"Apple", "Banana", "Orange", "Grape"};

    boolean[] checked = new boolean[] {true, false, true, false};

    int a = 0;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

    }


    public void clickBtn(View view) {

        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        //AlertDialog안에 static 이너 클래스인 Builder를 생성한 것임

        builder.setTitle("다이얼 로그");  //건축가에게 다이얼로그의 모양 설계 의뢰

        builder.setIcon(android.R.drawable.ic_dialog_alert);

        builder.setMessage("다이얼로그 테스트입니다.");

        builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

                Toast.makeText(MainActivity.this, "OK", Toast.LENGTH_SHORT).show();

            }

        });

        builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

                Toast.makeText(MainActivity.this, "CANCEL", Toast.LENGTH_SHORT).show();

            }

        });

        AlertDialog dialog = builder.create();


        //다이얼로그 밖 터치시 기본 취소되는 걸 안닫히게 하기

        dialog.setCancelable(false);

        dialog.setCanceledOnTouchOutside(false);

        dialog.show();

    }


    public void clickBtn2(View view) {

        //리스트형

        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        builder.setTitle("목록 다이얼로그");

        builder.setItems(items, new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

                Toast.makeText(MainActivity.this, items[which], Toast.LENGTH_SHORT).show();

            }

        });

        builder.create().show();

    }


    public void clickBtn3(View view) {

        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        builder.setTitle("Single Choice 다이얼로그");

        builder.setSingleChoiceItems(items, a, new DialogInterface.OnClickListener() {

            @Override                                 //1은 기본 선택 할것의 index 번호

            public void onClick(DialogInterface dialog, int which) {

                Toast.makeText(MainActivity.this, items[which], Toast.LENGTH_SHORT).show();

                a = which;

            }

        });

        builder.setPositiveButton("확인", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

            }

        });

        builder.create().show();

    }


    public void clickBtn4(View view) {

        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        builder.setTitle("Multiple choice Item");

        builder.setMultiChoiceItems(items, checked, new DialogInterface.OnMultiChoiceClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which, boolean isChecked) {

                checked[which] = isChecked; //눌러서 바뀌었을때 값이 옴

            }

        });

        builder.setPositiveButton("확인", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

                String s = "";

                for(int i = 0; i < checked.length; i++) {

                    s += checked[i] + " ";

                }

                Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();

            }

        });

        builder.create().show();

    }

}

반응형

안드로이드 : 이미지와 텍스트가 포함된 토스트 띄우기

안드로이드|2018. 12. 12. 13:55
반응형

clickBtn은 xml에 버튼에서 onClick을 통해 만든 메소드입니다.


public void clickBtn(View view) {



        //기본 토스트 띄우기

        //Toast.makeText(this, R.string.toastMsg , Toast.LENGTH_SHORT).show();


        //전에 뜨는 토스트 취소하기 뜨게 하기

        /*if( t != null ) {

            t.cancel();

            t = null;

        }

        //Toast객체 생성

        t = Toast.makeText(this, "안녕하세요", Toast.LENGTH_SHORT);

        t.show();*/


        //토스트 뜨는 위치 조정

        /*Toast t = Toast.makeText(this,"aaaa",Toast.LENGTH_SHORT);

        t.setGravity(Gravity.CENTER, 0, 0);

        t.show();*/


        //토스트는 기본이 Text이므로 Custom View하여 그림 등으로 토스트 띄우기

        Toast t = Toast.makeText(this, "", Toast.LENGTH_LONG);

        t.setGravity(Gravity.CENTER, 0, 0);


        //자바로 만들기

        /*ImageView iv = new ImageView(this);

        iv.setImageResource(android.R.drawable.ic_lock_silent_mode);

        TextView tv = new TextView(this);

        tv.setText("음소거 모드");


        //여러개의 뷰를 넣으려면 ViewGroup으로 감싸서 넣기

        LinearLayout layout = new LinearLayout(this);

        layout.setOrientation(LinearLayout.VERTICAL);

        layout.addView(iv);

        layout.addView(tv);

        t.setView(layout);*/


        //원하는 View를 자바로 만들면 코드가 너무 지저분하므로 View 생성을 xml로 사용하기

        //- XML로 View 객체의 모양을 설계하고 자바의 객체로 생성시켜 사용하기

        //res 폴더 안에 layout 폴더 안에 있는 toast.xml 문서를 읽어서

        // 자바 객체로 생성(부풀리는 inflate)하는 능력을 가진 객체를

        //운영체제 대리인(Context)로부터 얻어오기

        //LayoutInflater inflater = getLayoutInflater();

        LinearLayout layout = (LinearLayout)getLayoutInflater().inflate(R.layout.toast, null);

        t.setView(layout);

        t.show();

    }

반응형

Java : GUI 버섯 먹기 게임 만들기

Java Programming|2018. 11. 23. 15:33
반응형

 

import java.awt.BorderLayout;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.Toolkit;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.util.ArrayList;

import java.util.Random;

 

import javax.swing.JFrame;

import javax.swing.JPanel;

 

public class MainFrame extends JFrame {

GamePanel panel;

GameThread gThread;

public MainFrame() {

 

setTitle("Graphic Game Test");

setDefaultCloseOperation(EXIT_ON_CLOSE);

setBounds(300, 300, 700, 700);

setResizable(false);

 

panel = new GamePanel();

add(panel,BorderLayout.CENTER);

 

setVisible(true);

//게임 진행시키는 스레드 객체 생성 및 스타트

gThread = new GameThread();

gThread.start(); //run() 메소드 자동실행!!

 

//프레임에 키보드 입력에 반응하는 keyListner 등록

addKeyListener(new KeyListener() {

@Override

public void keyTyped(KeyEvent e) {

// TODO Auto-generated method stub

반응형

}

@Override

public void keyReleased(KeyEvent e) {

//눌러진 키가 무엇인지 알아내기 

int keyCode = e.getKeyCode();

switch( keyCode ) {

case KeyEvent.VK_LEFT:

panel.dx = 0; //원랜 getsetter 만들어야함

break;

case KeyEvent.VK_RIGHT:

panel.dx = 0;

break;

case KeyEvent.VK_UP:

panel.dy = 0;

break;

case KeyEvent.VK_DOWN:

panel.dy = 0;

break;

}

//방향키 4개 구분

}

@Override

public void keyPressed(KeyEvent e) {

//눌러진 키가 무엇인지 알아내기 

int keyCode = e.getKeyCode();

switch( keyCode ) {

case KeyEvent.VK_LEFT:

panel.dx = -8; //원랜 getsetter 만들어야함

break;

case KeyEvent.VK_RIGHT:

panel.dx = 8;

break;

case KeyEvent.VK_UP:

panel.dy = -8;

break;

case KeyEvent.VK_DOWN:

panel.dy = 8;

break;

}

//방향키 4개 구분

}

});

}//생성자

 

///////////////////////////////////////////////////////

class GamePanel extends JPanel { //게임화면 그려낼 Panel

 

//화면에 보여질 이미지 객체 참조변수 - 멤버변수

Image imgBack, imgPlayer, imgEnemy;

int width, height;//패널 사이즈 가져오기

int x, y, w, h;//xy : 플레이어의 중심 좌표 / wh : 이미지 절반폭;

int dx = 0, dy = 0;//플레이어 이미지의 이동속도, 이동방향

//적군 객체 참조변수, 여러마리일수있으므로 ArrayList(유동적 배열) 활용

ArrayList<Enemy> enemies = new ArrayList<Enemy>();

 

int score; //점수

 

 

public GamePanel() {

//GUI 관련 프로그램의 편의를 위해 만들어진 도구상자(Toolkit) 객체 

Toolkit toolkit = Toolkit.getDefaultToolkit();

//생성자에서 사이즈를 구하려하면 무조건 0임, 아직 패널이 안붙어서 사이즈를 모르기때문

//width = getWidth(); 

//height = getHeight();

 

imgBack = toolkit.getImage("images/bg.png");//배경 이미지

imgPlayer = toolkit.getImage("images/ms21.png");//플레이어 이미지 객체

imgEnemy = toolkit.getImage("images/ms20.png");//적군 이미지 객체 

 

}//생성자

 

//화면에 보여질때  보여질 내용물 작업을 수행하는 메소드 : 자동 실행(콜백 메소드)

@Override

protected void paintComponent(Graphics g) {

//화면에 보여질 작업 코딩

if( width == 0 || height == 0) { //처음 호출시엔 느려서 안보이다 이후 보임

width = getWidth();

height = getHeight();

//리사이징

imgBack = imgBack.getScaledInstance(width, height, Image.SCALE_SMOOTH);

imgPlayer = imgPlayer.getScaledInstance(128, 128, Image.SCALE_SMOOTH);

x = width/2;//플레이어의 좌표 계산

y = height - 100;

w = 64;

h = 64;

}

//이곳에 화가객체가 있으므로 그림 그리는 작업은 무조건 여기서

g.drawImage(imgBack, 0, 0, this);//배경 그리기

for(Enemy t : enemies) {

g.drawImage(t.img, t.x-t.w, t.y-t.h, this);

}

 

g.drawImage(imgPlayer, x - w, y - h, this);//플레이어

g.setFont(new Font(null, Font.BOLD, 20));//점수 표시하기

g.drawString("Score : " + score,10, 30);

//여러장면 만들기 위해 일정시간마다 다시 그리기(re painting)

}//paintComponent method                                       

 

void move() { //플레이어 움직이기(좌표 변경)

//적군들 움직이기

//중간에 배열의 개수 변경될 여지가 있다면

//맨 마지막 요소부터 거꾸로 0번 요소까지 역으로 처리해야함.

for(int i = enemies.size()-1; i >= 0; i--) {

Enemy t = enemies.get(i);

t.move();

if(t.isDead)  //ArrayList에서 제거

enemies.remove(i);

}

 

//for(Enemy t : enemies) { //foreach문으론 불가 }

x += dx;

y += dy;

//플레이어 좌표가 화면 밖으로 나가지 않도록

if(x < w) x = w;

if(x > width - w) x = width - w;

if(y < h) y = h;

if(y > height - h) y = height - h;

}

 

void makeEnemy() { //적군 생성 메소드

if(width == 0 || height == 0) return;

 

Random rnd = new Random();//50번에 한번꼴로 만들기

int n = rnd.nextInt(15);

if( n == 0 ) {

enemies.add(new Enemy(imgEnemy, width, height));

}

}//makeenemy

 

//충돌체크 작업 계산 메소드

void checkCollision() { //플레이어와 적군의 충돌

 

for(Enemy t : enemies) {

int left = t.x - t.w;

int right = t.x + t.w;

int top = t.y - t.h;

int bottom = t.y + t.h;

 

if(x > left && x < right && y > top && y < bottom) {

t.isDead = true; //충돌했음

score += 5;

}

}

}

 

}//GamePanel class

///////////////////////////////////////////////////////

//일정 시간마다 개엠화면을 갱신시키는 작업 수행하는 별도 스레드 클래스

class GameThread extends Thread {

@Override

public void run() {

while(true) {

//적군 객체 만들어내는 기능 메소드 호출

panel.makeEnemy();

//GamePanel의 플레이어 좌표 변경 

//panel.x += -1;// 객체의 멤버값 변경은

//panel.y += -5;/// 그 객체가 스스로 하도록 하는것이 OOP이 기본 모티브

panel.move();

panel.checkCollision();//충돌 체크 기능 호출

panel.repaint();//GamePanel의 화면 갱신

try { //너무 빨리 돌아서 천천히 돌도록

sleep(20);

} catch (InterruptedException e) {}

}

}

}

 

public static void main(String[] args) {

new MainFrame();

}

 

}

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡEnemy classㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

import java.awt.Image;

import java.util.Random;

 

public class Enemy {

 

Image img; //이미지 참조변수

int x, y; //이미지 중심 좌표

int w, h; //이미지 절반폭, 절반높이

 

int dy; //적군의 변화량

 

int width, height; //화면(panel)의 사이즈

//본인 객체가 죽었는지 여부!

boolean isDead = false;

 

public Enemy(Image imgEnemy, int width, int height) {

this.width = width;

this.height = height;

 

//멤버변수 값 초기화..

img = imgEnemy.getScaledInstance(64, 64, Image.SCALE_SMOOTH);

w = 32; //이미지 절반넓이

h = 32;

 

Random rnd = new Random();

x = rnd.nextInt(width - w * 2) + w; //w ~ width - w

y = -h;

 

dy =+ rnd.nextInt(15) + 1;//떨어지는 속도 랜덤하게

}

 

void move() { //Enemy의 움직이는 기능 메소드

y += dy;

//만약 화면 밑으로 나가버리면 객체 없애기

if( y > height + h ) { //ArrayList에서 제거

isDead = true; //죽음 표식! 

}

}

}

반응형

Java : 예외처리(Exception)에 대해 알아보기

Java Programming|2018. 11. 22. 20:56
반응형

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.InputMismatchException;

import java.util.Scanner;


public class Main {


public static void main(String[] args) {

// TODO Auto-generated method stub

//1. Error : 실행불가!!

//2. Exception : 실행중(RunTime) 문제가 발생!!

//Exception의 대표적인 예)

//1) 사용자가 잘못된 데이터를 입력하는 경우 : 숫자입력상황에 문자입력..등..

//2) 개발자가 로직이나 계산을 잘못한 경우 : 배열의 인덱스번호 오류, or 0으로 나눗셈.

//3) 네트워크나 하드웨어 오류 (하드디스크의 파일제어 오류.. 특정사이트(서버)접속 오류 : URL 미스, 사이트서버 불량)

//4) ?? 악의적인 과부하에 의한 오류(디도스 공격) : 해결이 어려움!!

System.out.println("예외처리에 대해 알아봅시다.");

//위의 예외상황에 대응하는 문법 소개..

//int a=0;

//System.out.println( 10/a );

//예외가 발생하면 그 순간 프로그램이 다운됨!!

//이를 방지할 필요가 있음..즉, 문제가 생기는 부분만 실행하지 않고 다음 코드를 계속 실행하도록!!

//if를 이용해서 a값이 0인 검사해보고 나눗셈을 실행할지 여부를 결정할 수 있음.

//경우에 따라서는 일단 시도를 해보고 예외가 발생하면 그에 대응해야 하는 경우도 있음.

//예): 인터넷 사이트에 접속하는 경우(www.naver.com): 접속은 해보는데 그 서버문제로 접속이 안되는 경우!

//이럴 경우 예외처리 문법이 유용함!! 프로그래머들에게는 필수 기술!!

//1) 0으로 나눗셈..

int a=0;

try {//일단 한번 시도해보는 영역 : 예외가 발생될 여지가 있는 코드들 작성 영역

System.out.println( 10/a );

}catch( ArithmeticException e ) {

//에러가 발생할 때 실행할 코드들..

System.out.println("에러가 발생했습니다");

System.out.println("에러메세지 : "+ e.getMessage() );

System.out.println("에러메세지 풀버전: "+ e.toString() );

}

//2) 배열의 인덱스 번호 사용 오류..

int[] arr= new int[5];

try {

//에러가 발생할 여지가 있는 코드는 try{ .. } 안에 작성!!

for(int i=0; i<6; i++) {

System.out.println( arr[i] );

}

}catch( ArrayIndexOutOfBoundsException e ) {

System.out.println("에러!!!");

}

//3) null참조변수로 객체 메소드 사용.(가장 많이발생..)

String s= null;

try {

System.out.println( s.length() );

}catch( NullPointerException e ) {

System.out.println("null 에러!! : 객체 없어!!!!");

}

//4) 잘못된 데이터를 입력!!

Scanner scanner= new Scanner(System.in);

int n;

try {

// n= scanner.nextInt();

// System.out.println(" n : " + n );

}catch( InputMismatchException e ) {

System.out.println(" 정수만 입력해!!! ");

}

//5) 숫자로 바꿀 수 없는 데이터를 숫자로 바꾸고자 할때!!

// String str= scanner.next(); //문자열 입력

//문자열을 int형으로 변환하기!

try {

// int num= Integer.parseInt(str);

// System.out.println(" num : " + num);

}catch( NumberFormatException e) {

System.out.println("정수형 문자열이 아니여서 변환 불가!");

}

//예외가 한번에 여러가지 발생하는 경우도 있음!!!

//예) 두 수를 입력받아 나눗셈을 하는 프로그램..

//예외 안에 중첩으로 예외 필요..

int c, d;

try {

// c= scanner.nextInt();

// d= scanner.nextInt();

//

// try {

//

// System.out.println( c/d ); //d가 0인 문제가 있을 수 있음.

//

// }catch( ArithmeticException e) {

// System.out.println("수학적 오류 : 0 나눗셈");

// }

}catch( InputMismatchException e ) {

System.out.println("정수가 아닌 값 입력 에러!!");

}

//중첩에 중첩.....중첩..이거 좀 짜증

//if else중첩 대신에  if else if문..

//다중 catch문으로 간결하게 처리하기!!

try {

// c= scanner.nextInt();

// d= scanner.nextInt();

//

// System.out.println( c/d );

}catch( InputMismatchException e) {

System.out.println("정수가 아닌값을 입력!");

}catch( ArithmeticException e) {

System.out.println("수학오류 : 0나눗셈");

}

//멀티catch문은 개수제한이 없음.

//만약 에러상황마다 대처할 내용은 똑같다면. 굳이 여러개의 catch문을

//반복적으로 작성하는 것은 낭비!!

//예외클래스들의 최상위 클래스인 Exception으로 모든 종류의 Exception객체를 catch할 수 있음.

try {

// c= scanner.nextInt();

// d= scanner.nextInt();

//

// System.out.println( c/d );

}catch( Exception e) {

System.out.println("에러!!!");

}

//예외발생 여부와 상관없이 무조건 할 일이 있다면...??

//보통 사용예)메모리를 관리하거나 외부(서버, 파일)와 연결통로 종료시키는 코드들..작성!

int x=0;

try {

System.out.println(10/x);

System.out.println("계산성공");

}catch(ArithmeticException e) {

System.out.println("계산실패");

}finally {

//여기는 무조건 실행되는 영역!!!

System.out.println("여긴 무조건 실행");

}

//가만 보니..finally를 안써도..어차피 cath{}다음 줄이 실행됨!!

//그럼 어차피 무조건 실행되는 코드작성 가능함!! 

//만약, 그냥쓰면 위의 try- catch문과는 상관없는 코드인것 처럼 인식될 가능성이 더 많음.

//finally를 쓰게되면 catch문을 안써도 됨.

try {

}finally {}

//Exception의 2가지 분류!

//1. Checked Exception : 예외처리를 안하면 에러가 발생하여 실행조차도 못하는 예외들!!

//2. UnChecked Exception : 예외처리(try문)을 해도되고 안해도 되는 예외들...지금까지 봤던 저 위의 예외들..

//Checked Exception의 대표적인 것들..:반드시 예외처리해야만 사용가능!

try {

//URL url= new URL("http://www.naver.com");//예외처리를 안하면 실행도 안되는 기능!!

URL url= new URL("www.naver.com");//주소오류: http://없어서..

System.out.println("서버접속 완료!!");

}catch( MalformedURLException e ) {

System.out.println("서버 주소에 이상이 있습니다.");

}

File file= new File("D://aaa.txt");

try {

//예외처리를 안하면 에러나는 코드들!

FileInputStream fis= new FileInputStream(file);

System.out.println("파일접속 성공");

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

System.out.println("파일접속 실패. 파일을 찾을 수 없습니다.");

}

System.out.println();

System.out.println("aaaa");


}


}



반응형

Java : GUI, 네트워크(1:1 채팅 프로그램 만들기)

Java Programming|2018. 11. 22. 15:09
반응형

MainFrame


import java.awt.BorderLayout;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;


import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;


public class MainFrame extends JFrame {

public MainFrame() {

setTitle("Swing TCP Chatting Test");

setBounds(10, 50, 400, 250);

setDefaultCloseOperation(EXIT_ON_CLOSE);

JPanel panel = new JPanel();

panel.setLayout(new GridLayout(0, 2));

JButton btnServer = new JButton("Server");

JButton btnClient = new JButton("Client");

//버튼클릭 액션에 반응하기 위해 리스너 객체 생성 및 추가

btnServer.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

//ServerFrame 객체 생성

ServerFrame frame = new ServerFrame();

}

});

btnClient.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

//ClientFrame 객체 생성

ClientFrame frame = new ClientFrame();

}

});

panel.add(btnServer);

panel.add(btnClient);

add(panel, BorderLayout.CENTER);

setVisible(true);

}


public static void main(String[] args) {

new MainFrame();

}

}


ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

ServerFrame


import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;


import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.JTextField;


public class ServerFrame extends JFrame {

JTextArea textArea; //멤버 참조변수

JTextField tfMsg;

JButton btnSend;

ServerSocket serverSocket;

Socket socket;

DataInputStream dis;

DataOutputStream dos;

public ServerFrame() {

setTitle("Server");

setBounds(450, 50, 500, 350);

textArea = new JTextArea();

textArea.setEditable(false); //쓰기 금지

JScrollPane scrollPane = new JScrollPane(textArea);

add(scrollPane,BorderLayout.CENTER);

JPanel msgPanel = new JPanel();

msgPanel.setLayout(new BorderLayout());

tfMsg = new JTextField();

btnSend = new JButton("send");

msgPanel.add(tfMsg, BorderLayout.CENTER);

msgPanel.add(btnSend, BorderLayout.EAST);

add(msgPanel,BorderLayout.SOUTH);

//send 버튼 클릭에 반응하는 리스너 추가

btnSend.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

sendMessage();

}

});

//엔터키 눌렀을 때 반응하기

tfMsg.addKeyListener(new KeyAdapter() {

//키보드에서 키 하나를 눌렀을때 자동으로 실행되는 메소드..: 콜백 메소드

@Override

public void keyPressed(KeyEvent e) {

super.keyPressed(e);

//입력받은 키가 엔터인지 알아내기, KeyEvent 객체가 키에대한 정보 갖고있음

int keyCode = e.getKeyCode();

switch(keyCode) {

case KeyEvent.VK_ENTER:

sendMessage();

break;

}

}

});

setVisible(true);

tfMsg.requestFocus();

//상대방이 접속할 수 있도록 서버소켓을 만들고 통신할 수 있는 준비 작업!

//네트워크 작업을 Main Thread가 하게하면 다른 작업(키보드 입력, 클릭 등..)들을 

//전혀 할 수 없음, 프로그램이 멈춤, 그래서 Main은 UI작업에 전념하도록 하고, 

//다른 작업들(오래 걸리는)은  별도의 Thread에게 위임하는 것이 적절함.

ServerThread serverThread = new ServerThread();

serverThread.setDaemon(true); //메인 끝나면 같이 종료

serverThread.start();

addWindowListener(new WindowAdapter() {

@Override //클라이언트 프레임에 window(창) 관련 리스너 추가

public void windowClosing(WindowEvent e) {

super.windowClosing(e);

try {

if(dos != null) dos.close();

if(dis != null) dis.close();

if(socket != null) socket.close();

if(serverSocket != null) serverSocket.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

});

}//생성자 메소드

//이너클래스 : 서버소켓을 생성하고 클라이언트의 연결을 대기하고,

//연결되면 메시지를 지속적으로 받는 역할 수행

class ServerThread extends Thread {

@Override

public void run() {

try {  //서버 소켓 생성 작업

serverSocket = new ServerSocket(10001);

textArea.append("서버소켓이 준비됐습니다...\n");

textArea.append("클라이언트의 접속을 기다립니다.\n");

socket = serverSocket.accept();//클라이언트가 접속할때까지 커서(스레드)가 대기

textArea.append(socket.getInetAddress().getHostAddress() + "님이 접속하셨습니다.\n");

//통신을 위한 스트림 생성

dis = new DataInputStream(socket.getInputStream());

dos = new DataOutputStream(socket.getOutputStream());

while(true) {

//상대방이 보내온 데이터를 읽기

String msg = dis.readUTF();//상대방이 보낼때까지 대기

textArea.append(" [Clinent] : " + msg + "\n");

textArea.setCaretPosition(textArea.getText().length());

}

} catch (IOException e) {

textArea.append("클라이언트가 나갔습니다.\n");

}

}

}

//메시지 전송하는 기능 메소드

void sendMessage() {

String msg = tfMsg.getText(); //TextField에 써있는 글씨를 얻어오기

tfMsg.setText(""); //입력 후 빈칸으로

textArea.append(" [SERVER] : " + msg + "\n");//1.TextArea(채팅창)에 표시

textArea.setCaretPosition(textArea.getText().length()); //스크롤 따라가게

//2.상대방(Client)에게 메시지 전송하기

Thread t = new Thread() {

@Override

public void run() {

try {

dos.writeUTF(msg);

dos.flush();

} catch (IOException e) {

e.printStackTrace();

}

}

};

t.start();

}

}//class


/*if (tfMsg.getText().contains("강아지")) {  //비속어 필터

String s = textArea.getText().replace("강아지", "****");

tfMsg.setText(s);

} */

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


ClientFrame


import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

import java.net.UnknownHostException;


import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.JTextField;


public class ClientFrame extends JFrame{

JTextArea textArea; //멤버 참조변수

JTextField tfMsg;

JButton btnSend;

Socket socket;

DataInputStream dis;

DataOutputStream dos;

public ClientFrame() {

setTitle("Client");

setBounds(450, 400, 500, 350);

textArea = new JTextArea();

textArea.setEditable(false); //쓰기 금지

JScrollPane scrollPane = new JScrollPane(textArea);

add(scrollPane,BorderLayout.CENTER);

JPanel msgPanel = new JPanel();

msgPanel.setLayout(new BorderLayout());

tfMsg = new JTextField();

btnSend = new JButton("send");

msgPanel.add(tfMsg, BorderLayout.CENTER);

msgPanel.add(btnSend, BorderLayout.EAST);

add(msgPanel,BorderLayout.SOUTH);

//send 버튼 클릭에 반응하는 리스너 추가

btnSend.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

sendMessage();

}

});

//엔터키 눌렀을 때 반응하기

tfMsg.addKeyListener(new KeyAdapter() {

//키보드에서 키 하나를 눌렀을때 자동으로 실행되는 메소드..: 콜백 메소드

@Override

public void keyPressed(KeyEvent e) {

super.keyPressed(e);

//입력받은 키가 엔터인지 알아내기, KeyEvent 객체가 키에대한 정보 갖고있음

int keyCode = e.getKeyCode();

switch(keyCode) {

case KeyEvent.VK_ENTER:

sendMessage();

break;

}

}

});

setVisible(true);

tfMsg.requestFocus();

//서버와 연결하는 네트워크 작업 : 스레드 객체 생성 및 실행

ClientThread clientThread = new ClientThread();

clientThread.setDaemon(true);

clientThread.start();

addWindowListener(new WindowAdapter() {

@Override //클라이언트 프레임에 window(창) 관련 리스너 추가

public void windowClosing(WindowEvent e) {

super.windowClosing(e);

try {

if(dos != null) dos.close();

if(dis != null) dis.close();

if(socket != null) socket.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

});

}//생성자

//이너클래스 : 서버와 연결하는 네트워크 작업 스레드

class ClientThread extends Thread {

@Override

public void run() {

try {

socket = new Socket("  접속 IP 주소  ", 10001);

textArea.append("서버에 접속됐습니다.\n");

//데이터 전송을 위한 스트림 생성(입추력 모두)

InputStream is = socket.getInputStream();

OutputStream os = socket.getOutputStream();

//보조스트림으로 만들어서 데이터전송 작업을 편하게 ※다른 보조스트림 사용

dis = new DataInputStream(is);

dos = new DataOutputStream(os);

while(true) {//상대방 메시지 받기

String msg = dis.readUTF();

textArea.append(" [SERVER] : " + msg + "\n");

textArea.setCaretPosition(textArea.getText().length());

}

} catch (UnknownHostException e) {

textArea.append("서버 주소가 이상합니다.\n");

} catch (IOException e) {

textArea.append("서버와 연결이 끊겼습니다.\n");

}

}

}

//메시지 전송하는 기능 메소드

void sendMessage() {

String msg = tfMsg.getText(); //TextField에 써있는 글씨를 얻어오기

tfMsg.setText(""); //입력 후 빈칸으로

textArea.append(" [Clinet] : " + msg + "\n");//1.TextArea(채팅창)에 표시

textArea.setCaretPosition(textArea.getText().length());

//2.상대방(Server)에게 메시지 전송하기

//아웃풋 스트림을 통해 상대방에 데이터 전송

//네트워크 작업은 별도의 Thread가 하는 것이 좋음

Thread t = new Thread() {

@Override

public void run() {

try { //UTF = 유니코드의 규약(포맷), 한글 깨지지 않게 해줌

dos.writeUTF(msg);

dos.flush(); //계속 채팅 위해 close()하면 안됨

} catch (IOException e) {

e.printStackTrace();

}

}

};

t.start();

}

}//class

반응형

Java : GUI 회원 명단 추가삭제 프로그램(Table 등)

Java Programming|2018. 11. 21. 20:15
반응형

import java.awt.BorderLayout;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.ArrayList;

 

import javax.swing.ButtonGroup;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JRadioButton;

import javax.swing.JScrollPane;

import javax.swing.JTable;

import javax.swing.JTextField;

import javax.swing.table.DefaultTableModel;

 

public class TableTest2 extends JFrame {

 

ArrayList<MemberVO> members = new ArrayList<MemberVO>();

 

public TableTest2() {

 

setTitle("회원 명단 추가삭제 프로그램");

setDefaultCloseOperation(EXIT_ON_CLOSE);

setAlwaysOnTop(true);

setBounds(200, 100, 400, 200);

반응형

//표 제목줄

String[] colNames = new String[] {"Name", "Age", "Gender"};

//표에 들어갈 데이터들.. /처음엔 빈 테이블 만들기 위해.. 데이터관리객체 생성

DefaultTableModel model = new DefaultTableModel(colNames, 0);

 

JTable table = new JTable(model);

JScrollPane scrollPane = new JScrollPane(table);

add(scrollPane, BorderLayout.CENTER);

 

//테이블 아래쪽에 데이터 입력 할수있는 패널

JPanel bottomPanel = new JPanel();

bottomPanel.setLayout(new GridLayout(2, 1));

 

JPanel panel = new JPanel();

JTextField tfName = new JTextField(6);

JTextField tfAge = new JTextField(3);

JRadioButton rb1 = new JRadioButton("Female");

JRadioButton rb2 = new JRadioButton("male");

JRadioButton rb3 = new JRadioButton();

ButtonGroup rg = new ButtonGroup();

rg.add(rb1); rg.add(rb2); rg.add(rb3);

rb1.setSelected(true);

 

panel.add(new JLabel("NAME"));

panel.add(tfName);

panel.add(new JLabel("AGE"));

panel.add(tfAge);

panel.add(rb1); panel.add(rb2);

bottomPanel.add(panel);

 

JPanel panel2 = new JPanel();

JButton btnAdd = new JButton("Add");

JButton btnDel = new JButton("Delete");

panel2.add(btnAdd); panel2.add(btnDel);

bottomPanel.add(panel2);

 

btnAdd.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

//입력된 값 테이블에 추가하기

//입력된 값들을 한줄 데이터 덩어리(배열)로 만들어줘야 함    ←←←

String[] rows = new String[3];

rows[0] = tfName.getText();

rows[1] = tfAge.getText();

if(rb1.isSelected()) rows[2] = "female";

else rows[2] = "male";

model.addRow(rows); //한줄단위로만 대입 가능하므로↑↑

 

//입력후 텍스트 필드 값 제거

tfName.setText("");

tfAge.setText("");

rb3.setSelected(true); //라디오 초기화

 

//어레이 리스트에 멤버 객체 추가

String name = rows[0];

int age = Integer.parseInt(rows[1]);

String gender = rows[2];

members.add(new MemberVO(name, age, gender));

System.out.println("회원 숫자:" + members.size());

}

});

//선택한 줄 지우기

btnDel.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

//선택한 줄(row)의 번호 알아내기

int rowIndex = table.getSelectedRow();

//선택 안하고 누를 경우 리턴값 -1

if(rowIndex == -1) return;

model.removeRow(rowIndex);

 

members.remove(rowIndex); //데이터 지우기

System.out.println("회원 숫자:" + members.size());

}

});

 

add(bottomPanel,BorderLayout.SOUTH);

setVisible(true);

}

class MemberVO { //회원 1명 정보 저장하는 클래스 : 오로지 데이터 저장용

private String name;  //VO클래스

private int age;

private String gender;

public MemberVO(String name, int age, String gender) {

this.name = name;

this.age = age;

this.gender = gender;

}

}

 

public static void main(String[] args) {

new TableTest2();

}

}

 

 

반응형