Java

Swing 예제, 로또번호 만들기

조충희 2025. 4. 30. 18:20

⭐Swing을 활용해 로또번호를 생성하는 프로그램을 만들어봤다.

요청사항
----- ----- -----
버튼을 누르면 번호 6개 출력되도록 만들 것

보더레이아웃

타이틀

패널

기능들을 활용할 것

 

🤔알아둘 개념

 

단일 책임 원칙 SRP
Single Responsibility Principle

클래스를 설계할 때의 원칙
클래스는 가능한 단 하나의 책임을 가지는 것이 좋다

 

 

1. 단일 책임 원칙에 따라

난수를 생성하는 클래스를 따로 만들었다.

 

중복을 방지하기 위해

이중 for 문을 알 필요가 있다.

package _lotto.ch01;

import java.util.Arrays;
import java.util.Random;

/**
 * 4.29
 * 난수를 만들어주는 프로그램을 따로 만들어본다.
 * <p>
 * 단일 책임 원칙
 * SRP
 * Single Responsibility Principle
 * 클래스를 설계할 때의 원칙
 * 클래스는 가능한 단 하나의 책임을 가지는 것이 좋다.
 */
public class LottoRandomNumber {

    //상수
    final int LOTTO_NUMBER_COUNT = 6;

    //변수

    //생성자

    //메서드
    public int[] creatNumber() { //6개의 숫자묶음을 만들기 위해 배열 활용

        int[] lottoWinNum = new int[LOTTO_NUMBER_COUNT];

        Random random = new Random();

        //for문이 돌아간 횟수 확인해보자
        int forCount = 0;

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

            lottoWinNum[i] = random.nextInt(45) + 1;

            /*
            outer for 1회차 순회
                j < i, 0 < 0 반복문이 수행되지 않는다.
             */
            for (int j = 0; j < i; j++) {
                /*
                최초 outer for 가 2회차 수행될 때
                inner for는 1회차 수행된다.
                 */
                if (lottoWinNum[j] == lottoWinNum[i]) {
                    i--;
                    /*
                    값이 중복된 상태라면
                    outer for 의 i 값을 내려
                    한 번 더 반복문을 수행하도록 한다.
                     */
                }

                forCount++; // for문이 돌아간 횟수 계산

            }//inner for 끝

            /*
            중복을 없애보자

            0번과 1번이 같은가?
            0번과 2번이 같은가?
            0번과 3번이 같은가?
                만약 같다면 다시 번호 생성!
            0번과 4번이 같은가?
            0번과 5번이 같은가?

            2중 for문?
             */

        }//outer for

//        lottoWinNum[0] = random.nextInt(45) + 1;
//        lottoWinNum[1] = random.nextInt(45) + 1;
//        lottoWinNum[2] = random.nextInt(45) + 1;
//        lottoWinNum[3] = random.nextInt(45) + 1;
//        lottoWinNum[4] = random.nextInt(45) + 1;
//        lottoWinNum[5] = random.nextInt(45) + 1;

        System.out.println("for문이 돌아간 횟수는: " + forCount);

        //오름차순 정렬
        Arrays.sort(lottoWinNum);

        return lottoWinNum;
    }

    //메인
    public static void main(String[] args) {

        LottoRandomNumber lottoRandomNumber = new LottoRandomNumber();
        int[] result = lottoRandomNumber.creatNumber();

        for (int i = 0; i < result.length; i++) {
            System.out.print(result[i] + " ");
        }

    }//end of main
}//end of class

 

2. 생성자와 구현부가 들어간 클래스를 설계한다.

 

가)JFrame 상속, ActionListener 구현

package _lotto.ch02;
/**
 * 4.30
 */
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class LottoFrame extends JFrame implements ActionListener {

 

 

나) 멤버변수 선언

//member
private int testNumber = 45;

private JButton button;

private LottoRandomNumber lottoRandomNumber1;

private int[] result = new int[6];

 

다. 생성자

//constructor
public LottoFrame() {
    initData();
    setInitLayout();
    addEventListener();
}

 

라. 메서드

//method
    private void initData() {
        setTitle("로또게임");
        setSize(360, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);

        button = new JButton("게임시작");

        lottoRandomNumber1 = new LottoRandomNumber();
    }

    private void setInitLayout() {
//        add(button, BorderLayout.NORTH);
        setLayout(new FlowLayout());

        add(button);

        setVisible(true); //마지막에 실행
    }

    private void addEventListener() {
        button.addActionListener(this);
    }

 

마. 인터페이스 추상메서드 구현

ActionListener에 딸려오는

actionPerformed 메서드에

버튼을 눌렀을 시 나타나는 동작을 구현한다.

 

paint 메서드에는

글씨를 쓰는 기능을 구현했다.

@Override
public void actionPerformed(ActionEvent e) {

    System.out.println("그림을 그려라");

    result = lottoRandomNumber1.creatNumber();

    repaint();
}

@Override
public void paint(Graphics g) {
    super.paint(g);

    Font f = new Font("궁서체", Font.BOLD, 25);

    g.setFont(f);

    g.drawString(result[0] + " ", 50, 100);
    g.drawString(result[1] + " ", 100, 100);
    g.drawString(result[2] + " ", 150, 100);
    g.drawString(result[3] + " ", 200, 100);
    g.drawString(result[4] + " ", 250, 100);
    g.drawString(result[5] + " ", 300, 100);
}

 

바. 메인함수

//main
    public static void main(String[] args) {

        new LottoFrame();

    }//end of main
}//end of class

 

3. 리팩토링

상수를 선언해 더 깔끔하고 간결한 코드를 짜봤다.

package _lotto.ch03;

import java.util.Arrays;
import java.util.Random;

public class LottoRandomNumber {

    //상수
    static final int LOTTO_NUMBER_COUNT = 6;

    //메서드
    public int[] creatNumber() { //6개의 숫자묶음을 만들기 위해 배열 활용

        int[] lottoWinNum = new int[LOTTO_NUMBER_COUNT];

        Random random = new Random();

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

            lottoWinNum[i] = random.nextInt(45) + 1;

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

                if (lottoWinNum[j] == lottoWinNum[i]) {
                    i--;

                }

            }//inner for 끝

        }//outer for

        //오름차순 정렬
        Arrays.sort(lottoWinNum);

        return lottoWinNum;
    }

    //메인
    public static void main(String[] args) {

        LottoRandomNumber lottoRandomNumber = new LottoRandomNumber();
        int[] result = lottoRandomNumber.creatNumber();

        for (int i = 0; i < result.length; i++) {
            System.out.print(result[i] + " ");
        }

    }//end of main
}//end of class

 

구현부

package _lotto.ch03;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class LottoFrame extends JFrame implements ActionListener {

    //member
    private static final String INITIAL_MESSAGE = "로또 번호 생성";
    private static final String FONT_NAME = "명조";
    private static final int FONT_SIZE = 20;

    private JButton button;
    private LottoRandomNumber lottoRandomNumber;

    private boolean isInitState = true; // 초기상태 플래그

    private int[] currentNo;

    //constructor
    public LottoFrame() {
        initData();
        setInitLayout();
        addEventListener();
    }

    //method
    private void initData() {
        setTitle("로또게임");
        setSize(360, 150);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);

        button = new JButton("게임시작");

        lottoRandomNumber = new LottoRandomNumber();

        currentNo = new int[LottoRandomNumber.LOTTO_NUMBER_COUNT];
    }

    private void setInitLayout() {
        setLayout(new BorderLayout()); //기본 배치관리자

        add(button, BorderLayout.NORTH);

        setVisible(true); //마지막에 실행
    }

    private void addEventListener() {
        button.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        isInitState = false;

        currentNo = lottoRandomNumber.creatNumber();

        repaint();
    }

    @Override
    public void paint(Graphics g) {

        super.paint(g);

        g.setFont(new Font(FONT_NAME, Font.BOLD, FONT_SIZE));

        if (isInitState) {
            g.drawString(INITIAL_MESSAGE, 100, 100);
        } else {

            for (int i = 0; i < currentNo.length; i++) {
                g.drawString(currentNo[i] + " ", (i + 1) * 50, 100);

            }//for

        }//if

    }//paint

    //main
    public static void main(String[] args) {

        new LottoFrame();

    }//end of main
}//end of class

 

 

4. 단일책임원칙 SRP 을 위배해

한 클래스에 모든 기능을 담는 것을 연습해봤다.

 

package _my;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Random;

public class LottoMachine extends JFrame implements ActionListener {

    /*
    구조
    ----- ----- -----
    JFrame 상속 ActionListener 구현

    멤버변수
    JButton
    배열

    생성자

    메서드
    makeNo(난수생성)

    initData
    setInitLayout
    addActionListener

    오버라이드
    action Performed
    paint

    메인
     */

    //멤버변수
    private JButton button;

    private boolean isInitState = true;

    private int[] currentNo;

    //생성자
    public LottoMachine() {

        initData();
        setInintLayout();
        addActionListener();

    }

    //메서드 - makeNo
    public int[] makeNo() {

        int[] lottoNo = new int[6];
        Random ran = new Random();

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

            lottoNo[i] = ran.nextInt(45) + 1;

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

                if (lottoNo[i] == lottoNo[j]) {

                    i--; //중복 제거

                }//if

            }//inner

        }//outer
        Arrays.sort(lottoNo);

        return lottoNo;
    }//makeNo

    private void initData() {

        setTitle("로또머신");
        setSize(360, 150);
        setDefaultCloseOperation(3);
        setResizable(false);

        button = new JButton("게임시작");
        currentNo = new int[6];
    }

    private void setInintLayout() {

        add(button, BorderLayout.NORTH);

        setVisible(true);
    }

    private void addActionListener() {

        button.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        isInitState = false;

        currentNo = makeNo();

        repaint();
    }

    @Override
    public void paint(Graphics g) {

        super.paint(g);

        g.setFont(new Font("궁서체", Font.BOLD, 30));

        if (isInitState) {

            g.drawString("로또번호생성", 100, 100);

        } else {

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

                g.drawString(currentNo[i] + " ", (i+1)*50, 100);

            }//for

        }//if

    }//paint

    //메인
    public static void main(String[] args) {

        new LottoMachine();

    }

}//end of class LM