일본에 있는 친구의 작은 프로그램 요청에 따라 구현하게 되었습니다.


간단한 프로그램이지만, 알고 있던 부분으로 구현한 프로그램이지만, 더욱 깊숙히 알게 되었고 만족스러운 프로그램입니다.




-----------------------------------------------------------프로그램 다운로드

OddsCalculator.exe



1. MainFrame.java

 main 메서드가 있는 클래스입니다. main 메서드에서 처음 보여질 화면을 구성한 클래스인 MainView 클래스 객체를 생성하면서 프로그램은 시작됩니다. 여기서 MainView 클래스는 JFrame을 상속받은 클래스 입니다.


MainFrame.java--------------------------------------------------------------------------------------

public class MainJFrame {

public static void main(String[] args) {

new MainView();

}

}






2. Result.java
 JTable의 아이템을 정의하는 클래스입니다. 아이템이란 테이블의 하나의 row를 뜻합니다. 이 테이블의 Column은 order와 outcome 입니다. 이렇게 구현하면 object 타입으로 사용할 때보다 더욱 객체지향적입니다. 또한 아이템에 Thread 등을 추가할 수도 있습니다.

 order

outcome 

 int

String 


Result.java------------------------------------------------------------------------------------------
import java.util.Observable;

public class Result extends Observable {
private int order;
private String outcome;
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
public String getOutcome() {
return outcome;
}
public void setOutcome(String outcome) {
this.outcome = outcome;
}
}




3. UserTableModel.java
 이 클래스는 AbstractTableModel 라는 추상 클래스를 상속받은 클래스입니다. JTable에 대응되는 속성들을 포함하고 있으며, 이 클래스는 TableModel로 사용할 수 있게 됩니다.



UserTableModel.java----------------------------------------------------------------------------------
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import javax.swing.table.AbstractTableModel;

public class UserTableModel extends AbstractTableModel implements Observer {
// 테이블 열에 대한 이름
private static final String[] columnNames = {"order", "outcome"};
// 열의 값에 대한 클래스
private static final Class<?>[] columnClasses = {String.class, String.class};
// 테이블의 Result 리스트
public ArrayList<Result> resultList = new ArrayList<Result>();
// 새로운 result를 테이블에 추가
public void addResult(Result result) {
// result가 변경될 때 통보받도록 등록
result.addObserver(this);
resultList.add(result);
// 테이블 행 삽입을 테이블에게 통보
fireTableRowsInserted(getRowCount()-1, getRowCount()-1);
}
public void resetResult() {
resultList.clear();
fireTableRowsInserted(getRowCount()+1, getRowCount()+1);
}
// 지정한 행에 대한 result 를 얻음
public Result getResult(int row) {
return (Result)resultList.get(row);
}
// 열의 이름을 얻음
public String getColumnName(int column) {
return columnNames[column];
}
// 열의 클래스를 얻음
public Class<?> getColumnClass(int column) {
return columnClasses[column];
}
@Override
public int getColumnCount() {
return columnNames.length;
}

@Override
public int getRowCount() {
return resultList.size();
}

@Override
public Object getValueAt(int row, int column) {
Result result = (Result)resultList.get(row);
switch(column) {
case 0:
return result.getOrder();
case 1:
return result.getOutcome();
}
return null;
}

@Override
public void update(Observable arg0, Object arg1) {
int index = resultList.indexOf(0);
fireTableRowsUpdated(index, index);
}

}





4. MainView.java
 MainView 클래스는 main 메서드에서 생성하는 클래스입니다. 즉, 처음 사용자에게 보여지는 화면을 구현한 클래스입니다. 



MainView.java--------------------------------------------------------------------------------------------
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

public class MainView extends JFrame {

JPanel userPanel = new JPanel();
JPanel tablePanel = new JPanel();
JLabel numeratorLabel = new JLabel("numerator: ");
JLabel denominatorLabel = new JLabel("denominator: ");
JLabel statisticsLabel = new JLabel("statistics: ");
public static JTextField numeratorTextField = new JTextField(4);
public static JTextField denominatorTextField = new JTextField(4);
public static int win = 0;

UserTableModel userTableModel = new UserTableModel();
JTable table = new JTable(userTableModel);

JMenuBar menubar = new JMenuBar();
JMenu menu_show = new JMenu("show");
JMenu menu_help = new JMenu("help");
JMenuItem menuitem_statistics = new JMenuItem("statistics");
JMenuItem menuitem_menual = new JMenuItem("instruction manual");
JMenuItem menuitem_about = new JMenuItem("About program..");

JButton okButton = new JButton("Go");
JButton resetButton = new JButton("Reset");

public MainView() {
super("Probability Calculator");
setLayout(new BorderLayout());
userPanel.setLayout(new FlowLayout());
tablePanel.setLayout(new BorderLayout());

// 메뉴 설정
menu_show.add(menuitem_statistics);
menu_help.add(menuitem_menual);
menu_help.add(menuitem_about);
menubar.add(menu_show);
menubar.add(menu_help);
setJMenuBar(menubar);

// 색깔 설정
menubar.setBackground(Color.orange);
userPanel.setBackground(Color.LIGHT_GRAY);

// tooltip 설정
numeratorTextField.setToolTipText("here is input / denominator");
denominatorTextField.setToolTipText("numerator / here is input");

// tablePane 패널 설정
tablePanel.setBorder(BorderFactory.createTitledBorder("Result"));

// 메뉴의 통계버튼 클릭
menuitem_statistics.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
try {
JOptionPane.showMessageDialog(null, "total: "
+ userTableModel.getRowCount() + "\nwin: " + win
+ "\nlose: " + (userTableModel.getRowCount() - win)
+ "\nwinning Rate: "
+ ((win * 100) / userTableModel.getRowCount())
+ "%", "Counting", JOptionPane.DEFAULT_OPTION);
} catch (Exception exception) {
JOptionPane.showMessageDialog(null,
"Statistics is not exist.", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
});
menuitem_menual.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
JOptionPane
.showMessageDialog(
null,
"Odds calculator program.\n\nYou can set the probability.\n1. we set the numerator.\n2. we set the denominator.\n3. click the Go button.\n4. check the results.\nAgain in order to press the reset button.",
"Instruction Manual",
JOptionPane.INFORMATION_MESSAGE);
}

});
// 메뉴의 만든이버튼 클릭
menuitem_about.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
JOptionPane
.showMessageDialog(
null,
"Made by Jo Jae-Hyeok.\nKakao Talk ID: zealot71\ne-mail: zealot71@naver.com",
"Information", JOptionPane.INFORMATION_MESSAGE);
}

});

// ok 버튼 클릭
okButton.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
Result result = new Result();

try {
result.setOrder(userTableModel.getRowCount() + 1);
result.setOutcome(probability(
Double.parseDouble(numeratorTextField.getText()),
Double.parseDouble(denominatorTextField.getText())));
userTableModel.addResult(result);
} catch (Exception exception) {
JOptionPane.showMessageDialog(null, "Value is not.",
"Error", JOptionPane.ERROR_MESSAGE);
}

}

});

// reset 버튼 클릭
resetButton.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
userTableModel.resetResult();
win = 0;
}

});

userPanel.add(numeratorLabel);
userPanel.add(numeratorTextField);
userPanel.add(denominatorLabel);
userPanel.add(denominatorTextField);

userPanel.add(okButton);
userPanel.add(resetButton);
tablePanel.add(new JScrollPane(table), "Center");

add(userPanel, "North");
add(tablePanel, "Center");

setBounds(200, 100, 400, 500);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setResizable(false);
setVisible(true);
}

private String probability(double numerator, double denominator) {
String flag = "Lose";

// 확률 계산
double probability = (numerator / denominator) * 100;

// 난수
double random = (Math.random() * 100);

// 승률 설정
if (random < probability) {
flag = "Win";
win++;
}
return flag;
}
}



처음 실행시 모습.






70/100 로 설정한 후 결과.







메뉴의 show - Statistics 모습. 






메뉴의 help - instruction manual 모습. 간단한 사용법.






메뉴의 help - About program.. 모습. 만든이에 대한 정보







Reset 버튼을 눌렀을 때 모습. 테이블을 비움.









posted by 쪼재