ㅎㅎ 이것도 곧 올리겠습니다.
리플렉션을 어떻게 설명할까하다가.. 지쳐가지고 중간에 업로딩을 안했었거든요. ㅠㅠ
제작에 꼭 필요한 부분은 아니지만, 리팩토링하다가 재밌어서 올려봅니다 ㅎㅎ\
3일내로 제작해서 올리겠습니다 (_ _)
리플렉션이란?
리플렉션이란,.. (저도 정확한 개념은 잘 모르고 그냥 말씀드립니다).
하나의 클래스에서 다른 클래스의 정보를 알아낼 수 있는 개념입니다.
다른 클래스의 지도를 볼 수가 있는 것이죠. 또한 그 클래스로 만든 객체까지 주어준다면,
그 객체들의 값을 바꿀 수도 있는 것입니다.
자세한 것은 일단 영상 보도록 하시겠습니다.
코드로 설명드리자면,
import java.lang.reflect.Field; public class RefUser { public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException { //지도(클래스) 선언 Class<?> clazz = RefObject.class; //지도에서 필드들을 받아와서 출력 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) System.out.println(field.getName()); //필드를 받아옴. clazz에서 getDeclaredField("필드명")해도 됨. Field field = fields[0]; //객체를 만들어서 객체값 변경 RefObject refObject = new RefObject(); field.setInt(refObject, 3); System.out.println("넘버 아이디는 :"+refObject.getNumId()); } }
여기서 참조되는 클래스는 뭐... 간단합니다;;
public class RefObject { private int numId; public int getNumId() {return numId;} public void setNumId(int numId) {this.numId = numId;} }
클래스와, 객체를 가지고서 clazz.getDeclaredField("필드명") 혹은 getDeclared~ 로 필드들을 받아오시는 것을 보실 수가 있습니다.
자, 이제 리팩토링을 적용해보도록 하겠습니다.
리플렉션을 이용한 리팩토링적용
여기서는 반복된 부분. 이부분들을 리플렉션을 이용하여서 이름값만을 가지고 Settings 클래스에서 값을 가져와서 불러들여 적용해보는 것을 해봅니다. 영상을 보도록 하겠습니다.
setPanel(layeredPane).setBounds(Setting.bRectangle); setPanel(backGround).setBounds(Setting.bpanRectangle); setPanel(imgClock).setBounds(Setting.imgClock); setPanel(clockMessage).setBounds(Setting.clockMessage); setPanel(myStarPanel).setBounds(Setting.bpanRectangle);
ManageView 는 다음과 같습니다. (깃허브에는 더 정리된 것이 올라갑니다)
package view; import java.awt.Component; import java.awt.Rectangle; import java.lang.reflect.Field; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; import view.panel.ClockMessage; import view.panel.ImgClock; import view.panel.MyStarPanel; import view.panel.PanImgload; import asset.Setting; @SuppressWarnings("serial") public class ManageView extends JFrame { private JLayeredPane layeredPane = new JLayeredPane(); //JPanels private JPanel backGround = new PanImgload("img/mainHud_back.png"); private ImgClock imgClock = new ImgClock(); private ClockMessage clockMessage = new ClockMessage(); private MyStarPanel myStarPanel = new MyStarPanel(); public ManageView() { //Configure this Frame setLayout(null); setVisible(true); setTitle("ManageView"); setSize(Setting.bDimen); setDefaultCloseOperation(EXIT_ON_CLOSE); setLocation(Setting.locationX, Setting.locationY); //LayerdPanel and Component Setting , Finally add To this Frame /* setPanel(layeredPane).setBounds(Setting.bRectangle); setPanel(backGround).setBounds(Setting.bpanRectangle); setPanel(imgClock).setBounds(Setting.imgClock); setPanel(clockMessage).setBounds(Setting.clockMessage); setPanel(myStarPanel).setBounds(Setting.bpanRectangle); */ add(setJLayered(backGround, myStarPanel, imgClock, clockMessage)); //Action Events //threadStart(imgClock, clockMessage, myStarPanel); } public void setRectangles(Class<?> clazz, Object instance, Class<?> targetClass, Object target) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException{ Object tempObject = null; Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { System.out.println("필드 :" + field.getName()); System.out.println("세팅클래스에서 받아온 값은"+targetClass.getDeclaredField(field.getName()).get(target)); tempObject = field.get(instance); if(tempObject instanceof JComponent){ Rectangle rectangle = (Rectangle) targetClass.getDeclaredField(field.getName()).get(target); ((JComponent) tempObject).setBounds(rectangle); ((JComponent) tempObject).setOpaque(false); ((JComponent) tempObject).setLayout(null); } if(tempObject instanceof Runnable){ new Thread((Runnable) tempObject).start(); } } } public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { ManageView manageView = new ManageView(); manageView.setRectangles(ManageView.class, manageView, Setting.class, Setting.getInstance()); } // Setting inner Methods private JComponent setPanel(JComponent panel) { panel.setLayout(null); panel.setOpaque(false); return panel; } private JLayeredPane setJLayered(Component...components) { int i = 0; for (Component component : components) layeredPane.add(component, new Integer(i++)); return layeredPane; } private void threadStart(Runnable...target) { for (Runnable runnable : target) new Thread(runnable).start(); } // TODO 계속 들어감 }
Settings 에는 다음소스를 넣어주세요.
// ManageView 에 들어갈 것들 public static Rectangle layeredPane = bRectangle; public static Rectangle backGround = bRectangle; public static Rectangle myStarPanel = bRectangle; // singleTone private static Setting instance = new Setting(); public static Setting getInstance() { return instance; } private Setting() { }
zip 소스코드는 여기서 https://github.com/arahansa/pcbang/archive/2.zip 다운받으실 수 있습니다.