package hello; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; // 실수 2개를 비교하는 클래스로 Collections.sort클래스를 이용해서 내림차순할 때 객체로 넘겨줘야 됨!! class AscendingDouble implements Comparator<Double> { @Override public int compare(Double a, Double b) { return b.compareTo(a); //같으면 0, b가 더 크면 양수, b가 더 작으면 음수 반환 } } // val리스트를 이용해서 rank리스트를 조정하는 클래스 class Rank{ AscendingDouble asd=new AscendingDouble(); // 오름차순 정렬 public void sort(ArrayList<Integer> rank, ArrayList <Double>val){ for(int i=1; i<rank.size();i++) { if(asd.compare(val.get(i-1),val.get(i))==0) // 실수 2개가 같은지 비교 rank.set(i,rank.get(i-1)); } } } // 이벤트 처리 클래스 class myListener implements ActionListener{ JComboBox select; // 윈도우에 존재하는 콤보 박스 JTextField edit; // 이벤트 발생으로 넘겨 받은 텍스트 필드 ArrayList<Button> bts; // 버튼 패널을 요소로 가지는 리스트 static int curr; // 가장 밑에 있는 버튼 패널의 인덱스 double value; // 밸류 버튼의 텍스트 값을 수로 바꾼 변수 ArrayList<Double> values; // value를 요소로 가지는 리스트 ArrayList<Integer> ranks; // 1~10까지 초기화된 후에 정렬해 나가는 식인 리스트 Rank rankob; // rank리스트 조정 객체 참조변수 Color color; // 버튼의 원래 색 public Boolean isStringDouble(String s) { // 문자열을 실수로 전환이 가능하면 '수 형태의 문자열'이므로 true를 반환한다! try { double a=Double.parseDouble(s); return true; } catch(Exception e){ return false; } } public int DoubleformInt(double d) { // 소수점 아래 숫자가 없으면 정수 형태를 취한다고 취급하고 정수를 반환 아니면 0을 반환 int dint=(int)d; if(d%dint==0) return dint; else return 0; } public void add(double val) { if(curr!=window.scale-1) { // 텍스트필드란 초기화 edit.setText(""); // 버튼 색 초기화 for(Button bt:bts) bt.val.setBackground(color); // 밑애 버튼 하나 더 보이게 하기 curr++; window.curr++; bts.get(curr).setVisible(true); // values,ranks리스트에 요소 추가 후 정렬 values.add(val); ranks.add(curr+1); Collections.sort(values,new AscendingDouble()); // values 내림차순으로 정렬 rankob.sort(ranks,values); // values를 이용해서 ranks 오름차순 정렬 // 리스트 정렬한대로 버튼 텍스트 바꾸기 for(int i=0; i<=curr; i++) { int check=DoubleformInt(values.get(i)); // 실수가 정수형 형태인지 실수형 형태인지 확인 (10.0 => 정수형 형태로 취급한다) if(check==0 && val!=0) bts.get(i).val.setText(values.get(i)+""); else bts.get(i).val.setText(check+""); bts.get(i).rank.setText(ranks.get(i)+""); } // 추가한 버튼 색 바꾸기 for(Button bt:bts) { double num=Double.parseDouble(bt.val.getText()); if(num==val) { bt.val.setBackground(Color.yellow); break; } } } else System.out.println("더이상 추가할 수 없습니다!!"); } public void del(double val) { if(curr!=-1) { // 텍스트필드란 초기화 edit.setText(""); // 버튼 색 초기화 for(Button bt:bts) bt.val.setBackground(color); // value버튼 텍스트랑 val이랑 같은 것을 찾으면 1, 아니면 0 int can=0; for(Button bt:bts) { double num=Double.parseDouble(bt.val.getText()); if(num==val) { // 삭제할 자리 버튼 색 바꾸기 bt.val.setBackground(Color.yellow); // 삭제할 버튼을 가지고 리스트에서 인덱스 찾기 int idx=bts.indexOf(bt); // value버튼 값 한 칸씩 위로 올리기 for(int i=idx+1;i<=curr;i++) bts.get(i-1).val.setText(bts.get(i).val.getText()); // 맨 마지막꺼 안 보이게 하기 bts.get(curr).setVisible(false); values.remove(curr); ranks.remove(curr); curr--; window.curr--; // ranks와 values 초기화 for(int i=0;i<=curr;i++) { ranks.set(i,i+1); value=Double.parseDouble(bts.get(i).val.getText()); values.set(i,value); } // ranks재정렬 후 rank버튼 텍스트 수정 rankob.sort(ranks, values); for(int i=0; i<=curr; i++) bts.get(i).rank.setText(ranks.get(i)+""); can=1; break; } else can=0; } if(can==0) System.out.println("값을 찾을 수 없습니다!!"); } else System.out.println("더이상 삭제할 수 없습니다!!"); } public void search(double val) { // 텍스트필드란 초기화 edit.setText(""); // value버튼 텍스트랑 val이랑 같은 것을 찾으면 1, 아니면 0 int can=0; for(Button bt:bts) { double num=Double.parseDouble(bt.val.getText()); bt.val.setBackground(color); if(num==val) { // 버튼 색 바꾸기 bt.val.setBackground(Color.yellow); can=1; } else if(can!=1) can=0; } if(can==0) System.out.println("값을 찾을 수 없습니다!!"); } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub edit=(JTextField)e.getSource(); // 이벤트 발생으로 넘겨 받은 텍스트 필드 String s=edit.getText(); // 텍스트필드에서 입력받은 문자열 if(isStringDouble(s)) { // 문자열이 숫자 형태인지 확인 // 필드 초기화 및 추가 변수 선언 select=window.select; curr=window.curr; bts=window.bts; values=new ArrayList<>(); ranks=new ArrayList<>(); rankob=new Rank(); color=bts.get(0).getBackground(); int comboi=select.getSelectedIndex(); // 콤보박스에 선택된 필드의 인덱스 Double change=Double.parseDouble(s); // 텍스트필드에서 입력받은 문자열을 정수로 바꿈 // values,ranks 리스트 초기화 for(int i=0; i<=curr; i++) { value=Double.parseDouble(bts.get(i).val.getText()); values.add(value); ranks.add(i+1); } switch(comboi) { case 0: // add add(change); break; case 1: // delete del(change); break; case 2: // search search(change); break; } } else System.out.println("수를 입력해주세요!!"); } } // 버튼 패널 클래스 class Button extends JPanel{ JButton rank=new JButton(); JButton val=new JButton(); public Button(String i,String j) { setLayout(new GridLayout(0,2)); rank.setText(i); rank.setBackground(Color.white); val.setText(j); // 패널에 버튼 추가 add(rank); add(val); } } // 윈도우 생성 클래스 class window extends JFrame{ JPanel panel1,panel2; JTextField edit; static JComboBox select; static ArrayList<Button> bts; // 버튼 패널을 요소로 가지는 동적 배열 static int curr=-1; // 가장 밑에 보이게 할 버튼 패널의 인덱스 static int scale=30; // 리스트에서 버튼 패널의 최대 개수 public window() { setTitle("자바 정렬 리스트"); setSize(400,500); setLocation(800,200); setDefaultCloseOperation(EXIT_ON_CLOSE); class Panel1 extends JPanel{ public Panel1() { edit=new JTextField(10); edit.addActionListener(new myListener()); String[] st= {"add","delete","search"}; select=new JComboBox(st); select.setSelectedIndex(0); add(edit); add(select); } } class Panel2 extends JPanel{ public Panel2() { bts=new ArrayList<>(); setLayout(new GridLayout(0,1)); for(int i=0;i<scale;i++) { bts.add(new Button((i+1)+"",300-(i*10)+"")); add(bts.get(i)); if(i>curr) bts.get(i).setVisible(false); // 0~curr까지 => curr+1개만 보이게 하기 } } } panel1=new Panel1(); panel2=new Panel2(); add(panel1,BorderLayout.NORTH); add(panel2,BorderLayout.CENTER); setVisible(true); } } public class list{ public static void main(String args[]) { new window(); } }
로직 설명
add – 사용자가 입력한 문자열을 추가해서 value값들은 내림차순,rank값들은 오름차순을 해서 보이게 함
=> 가장 아래에 위치한 버튼 패널 밑에 숨겨진 패널을 보이게 함(1)
value값들이 저장된 values리스트에 새로운 문자열을 실수형으로 바꿔서 저장함 (2)
rank값들이 저장된 ranks리스트에 값을 하나 추가함 (ex)1,2,3,…8 +9) (3)
values는 Collections클래스가 제공하는 메소드로 내림차순을 하고 ranks는 필자가 만든 Rank클래스를 이용해서 오름차순을 함 (4)
정렬된 두 리스트를 가지고 value버튼들과 rank버튼들의 텍스트를 수정함 (5)
delete – 사용자가 입력한 문자열에 해당하는 value를 한 개 찾아서 삭제함, rank값들은 재정렬해서 보이게 함
=> 버튼 패널이 담긴 bts리스트를 가지고 for-each문을 이용해서 입력된 문자열과 같은 텍스트를 가지는 버튼 패널을 찾음 (1)
그 버튼 패널이 bts에서 인덱스 몇인지 확인 후, for문과 인덱스를 통해 value버튼 텍스트를 한 칸씩 위로 땡김 (2)
가장 아래에 위치한 버튼 패널을 숨김 (3)
values,ranks리스트 맨 마지막 요소를 없앤 다음 ,요소들을 모두 초기화함 (4)
ranks는 Rank클래스를 이용해서 다시 오름차순을 하고 , 이 리스트 값들을 이용해서 rank버튼 텍스트를 수정함 (5)
search -사용자가 입력한 문자열에 해당하는 value를 모두 찾아서 노랑 강조 표시를 함
=> 버튼 패널이 담긴 bts리스트를 가지고 for-each문을 이용해서 입력된 문자열과 같은 텍스트를 가지는 버튼 패널을 찾음 (1)
버튼 패널 안에 있는 value버튼의 배경을 노란 색으로 바꿈 (2)
Rank클래스 설명
(values리스트를 가지고 ranks리스트를 오름차순으로 바꾸는 sort메소드)를 지닌 클래스
=> 보이는 버튼 패널이 6개면 ranks는 1,2,3,4,5,6으로 초기화돼있어야 함, values는 정렬된 상태였어야 함
정수형 변수 i를 1로 초기화하고 ranks,values의 인덱스로 사용함 (1)
values의 인덱스i값과 인덱스i-1값을 비교해서 같으면 ranks의 인덱스 i값에 인덱스 i-1값을 저장함 (2)
i가 리스트의 사이즈-1이 될 때까지 (2)를 반복함 (3)
class Rank{ // 실수 비교에 필요한 클래스 인스턴스화 AscendingDouble asd=new AscendingDouble(); public void sort(ArrayList<Integer> ranks, ArrayList <Double>values){ for(int i=1; i<ranks.size();i++) { if(asd.compare(values.get(i-1),values.get(i))==0) // 실수 2개가 같은지 비교 ranks.set(i,ranks.get(i-1)); } } }