2013-03-19 2 views
0

런타임에 수정할 수있는 모델이 있습니다. 다음 예를동적 모델에서 뷰 생성

public class JavaMethod 
{ 
    private String   name; 
    private List<Parameter> parameters; 
    private boolean   isConstructor; // this is an example 
} 

파라미터는 다른 종류 (integer, boolean, string, float ...)와 다른 유효한 값을 가질 수있다. 예를 들어, 이라는 정수 매개 변수는 양의 정수만 포함 할 수 있습니다.

문제는 내가 그 JavaMethod 개체를 구성하는 스윙과 함께보기를 생성하고 싶습니다,하지만 그것을 할 적절한 방법을 잘 모르겠습니다.

예를 들어, 양수 인 연령 매개 변수는 음수가 입력되지 않도록하는 JTextField 확장 클래스에 연결됩니다. numberOfFingers의 범위가 8에서 12까지의 정수 매개 변수는 해당 범위의 옵션을 선택할 수있는 JComboBox 확장 클래스에 링크됩니다.

매개 변수 개체에 적절한 Swing 구성 요소를 생성하는 작업을 제공하여 다형성을 사용하여이 작업을 수행 할 수 있지만 내 모델은보기 생성 방법을 알 수 있습니다.

이와 같은 모델에 대한보기를 생성하는 올바른 방법은 무엇입니까? 내가 생각할 수있는 것은 (뷰 생성과 관련된 모델없이) 매개 변수의 세부 사항을 읽음으로써 좋은 구성 요소를 선택하는 컨트롤러의 일종의 거대한 스위치입니다.

감사가 들어

+0

"Java 속성 시트"에 대한 검색을 수행하고 – MadProgrammer

+0

이 무엇인지 생각해보십시오. 고맙습니다. 실제로 모델 개체의 속성 시트를 만들고 있습니다. – phil

+0

테이블/트리 API의 작동 방식을 조금 생각해보십시오. 기본적으로 렌더러/편집기 구성 요소를 뷰에 등록하려고합니다. 이렇게하면 뷰가 매개 변수 유형을 검사하고 값을 렌더링/편집하는 최선의 방법을 결정할 수 있습니다. 그런 다음 가장 일반적인 데이터 유형에 대한 기본 구현을 정의하는 최선의 조치 과정을 결정해야합니다. – MadProgrammer

답변

0

이 문제를 해결하는 가장 좋은 방법은 방문자 패턴을 사용하는 것입니다. 예를 들어

이 패턴 here

import java.awt.EventQueue; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.WindowConstants; 

public class Main 
{ 
    public static class JavaMethod implements Iterable<Parameter> 
    { 
     private List<Parameter> parameters; 

     public JavaMethod() 
     { 
      this.parameters = new ArrayList<>(); 
      // This is an example 
      this.parameters.add(new IntegerParameter()); 
      this.parameters.add(new StringParameter()); 
     } 

     @Override 
     public Iterator<Parameter> iterator() 
     { 
      return this.parameters.iterator(); 
     } 
    } 

    public static interface Parameter 
    { 
     public void accept(ParameterVisitor visitor); 
    } 

    public static class IntegerParameter implements Parameter 
    { 
     public int value = 10; 

     @Override 
     public void accept(final ParameterVisitor visitor) 
     { 
      visitor.visit(this); 
     } 
    } 

    public static class StringParameter implements Parameter 
    { 
     public String value = "Hello"; 

     @Override 
     public void accept(final ParameterVisitor visitor) 
     { 
      visitor.visit(this); 
     } 
    } 

    public static interface ParameterVisitor 
    { 
     void visit(StringParameter stringParameter); 
     void visit(IntegerParameter integerParameter); 
    } 

    public static class ParameterSwingVisitor implements ParameterVisitor 
    { 
     private final JComponent container; 

     public ParameterSwingVisitor(final JComponent container) 
     { 
      this.container = container; 
     } 

     @Override 
     public void visit(final StringParameter stringParameter) 
     { 
      this.container.add(new JTextField(stringParameter.value)); 
     } 

     @Override 
     public void visit(final IntegerParameter integerParameter) 
     { 
      // This could be a custom component to pick numbers 
      this.container.add(new JLabel(String 
        .valueOf(integerParameter.value))); 
     } 

    } 

    public static void main(final String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       JPanel myPanel = new JPanel(); // view 
       JavaMethod myMethod = new JavaMethod(); // model 

       final ParameterVisitor visitor = new ParameterSwingVisitor(
         myPanel); 

       for (final Parameter picked : myMethod) 
       { 
        picked.accept(visitor); // This will add the appropriate 
              // swing 
              // component 
       } 

       JFrame myFrame = new JFrame("Visitor pattern"); 
       myFrame.setContentPane(myPanel); 
       myFrame.setVisible(true); 
       myFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 
       myFrame.setSize(500, 500); 
      } 
     }); 
    } 
} 

추가 정보.

1

당신은 사용자 정의 PlainDocument을 만들 필요가있다.

import javax.swing.text.Document; 
import javax.swing.text.PlainDocument; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
class AgeDocument extends PlainDocument 
{ 
    @Override 
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException 
    { 
     /**Write your logic here**/ 
     if (str == null) 
     { 
      return; 
     } 
     char[] arr = str.toCharArray(); 
     for (int i = 0; i < arr.length; i++) 
     { 
      if (!Character.isDigit(arr[i]))//Checking for Non Numeric. 
      { 
       return; 
      } 
      if (Character.getNumericValue(arr[i])==0) 
      { 
       try 
       { 
        int val = Integer.parseInt(getText(0,offs)); 
        if (val == 0) 
        { 
         super.insertString(offs,"", a);//Don't allow to put 0 as age. 
         return; 
        } 
       } 
       catch (Exception ex){return;} 
      } 
     } 
     super.insertString(offs, new String(str), a); 
    } 
} 

을 그리고 당신이 JTextField 목적이 AgeDocument 속성을 설정할 때마다 당신은 단순히 마찬가지로 JTextFieldOBject.setDocument(new AgeDocument())

쓰기 만 나이 값을 포함 JTextField에 대한 예를 들어, 당신은 다음과 같이 보일 것 AgeDocument 클래스를 만들어야합니다 , 당신은 많은 모델을 독립적으로 만들 수 있습니다. 또한 코드의 어느 위치에서나 사용할 수 있습니다.

+0

유용 할 수 있습니다. 감사합니다. 그러나이 기술을 사용하여 입력을 필터링하기 전에 적절한 구성 요소로 뷰를 초기화해야합니다.'JTextField','JComboBox' 또는'Parameter'의 타입 및 조건과 관련된 다른 컴포넌트를 어디에서 어떻게 선택해야합니까? 이 모든 것이 큰 스위치로 들어가야할까요? if (param.isInt() && param.isRange()) {createComboBox(); }'모든 유형에 대한 대소 문자를 넣으시겠습니까? – phil

+0

주어진 입력 유형에서'swing'의 구성 요소가 호출되면,'key'를 매개 변수로 사용하고'value'를'Swing' 클래스의 이름으로 사용하여'Map'을 생성 할 수 있습니다 해당 키에 대해 생성하려는 객체를 가진'component'. 이렇게하면'Map'의'get (key)'메소드를 사용하여 주어진 타입의 매개 변수에 따라 생성 될 실제 컴포넌트를 쉽게 찾을 수 있습니다. IMO –