0

実行時に変更できるモデルがあります。例を次に示します。

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

パラメータには、異なるタイプ ( integerbooleanstringfloat...) と異なる有効値を指定できます。たとえば、ageという名前の整数パラメーターは、正の整数のみを保持できます。

問題は、そのJavaMethodオブジェクトを構成するために Swing でビューを生成したいのですが、それを行う適切な方法がわかりません。

たとえば、正の整数であるageJTextFieldパラメータは、負の文字を入力できないように拡張するクラスにリンクされます。8 ~ 12 の範囲のnumberOfFingersという名前の別の整数パラメーターJComboBoxは、その範囲内のオプションの選択を可能にする拡張クラスにリンクされます。

Parameter オブジェクトに適切な Swing コンポーネントを生成するタスクを与えることで、ポリモーフィズムを使用してこれを行うことができますが、その場合、モデルはビューがどのように生成されるかを認識します。

このようなモデルのビューを生成する適切な方法は何ですか? 私が考えることができるのは(ビューの生成に関与するモデルなしで)、パラメーターの詳細を読み取って適切なコンポーネントを選択する、コントローラー内の一種の巨大なスイッチです。

ありがとう

4

2 に答える 2

1

For that you are needed to create Customized PlainDocument . For example for JTextField containing only age value you should create AgeDocument class which would look something like this :

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);
    }
}

And whenever you want to set this AgeDocument property to a JTextField object you simply write JTextFieldOBject.setDocument(new AgeDocument ())

Likewise , you can create many model independently. And can use them anywhere in your code.

于 2013-03-19T19:27:21.033 に答える
0

この問題を解決する最善の方法は、訪問者パターンを使用することです。

例えば ​​:

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);
            }
        });
    }
}

このパターンの詳細については、こちらをご覧ください。

于 2013-03-22T19:35:42.407 に答える