0

我有一个可以在运行时修改的模型。这是一个例子:

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

参数可以有不同的类型(integer, boolean, string, float...)和不同的有效值。例如,一个名为age的整数参数只能保存正整数。

问题是我想用 Swing 生成一个视图来配置该JavaMethod对象,但我不确定正确的方法。

例如,作为正整数的年龄参数将链接到一个类扩展JTextField,以防止输入负任何字母。另一个名为numberOfFingers的整数参数的范围可以从 8 到 12 将链接到一个JComboBox允许在该范围内选择选项的类扩展。

我可以通过将生成适当的 Swing 组件的任务交给 Parameter 对象来使用多态性来做到这一点,但是我的模型会知道视图是如何生成的。

为这样的模型生成视图的正确方法是什么?我能想到的(不涉及视图生成的模型)是控制器中的一种巨大开关,它通过读取参数的详细信息来选择好的组件。

谢谢

4

2 回答 2

1

为此,您需要创建 Customized PlainDocument。例如,对于JTextField仅包含年龄值,您应该创建AgeDocument如下所示的类:

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

每当您想将此AgeDocument属性设置为JTextField对象时,您只需编写JTextFieldOBject.setDocument(new AgeDocument ())

同样,您可以独立创建多个模型。并且可以在代码中的任何地方使用它们。

于 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 回答