ActionPerformed&更新(模型,对象)在mvc和GridBagLayout中

时间:2015-07-07 23:36:16

标签: java swing model-view-controller actionlistener gridbaglayout

我有几个问题,请原谅我的denglish! 问题:

  • 我的动作在我的控制器中执行了不要反应
  • 我不知道如何在View中使用更新(模型,对象)方法。
  • 下一个问题是我的GridBag。尽管代码是以oracle为例的,但它看起来很混乱。
  • 没有最后一个。在视图行41中,由于在模型中初始化的类,我得到一个NPE。不,为什么。我已经完成了测试是否构建了Class并且是的。

程序应该使JuliaSet变得更好。 没有theire导入的类 控制器:

public class JuliaController extends WindowAdapter implements ActionListener {

private JuliaView view;
private JuliaModel model;
private String linkBuffer;

public JuliaController(){
    model = new JuliaModel();

    System.out.println("true!");
    view = new JuliaView("JuliaMenge");
    view.makeView();
}
@Override
public void actionPerformed(ActionEvent arg0) {
    String action = arg0.getActionCommand();
    if(action.equals(view.ACTION_CLEAR))
    {
        //Clear Graphics
        view.setBtClear();
    }
    if(action.equals(view.ACTION_COMPLEX))
    {
        String input = view.getComplex();
        view.setTfComplex();            //Zurücksetzen des Felds!

        model.juliaBerechnung(input);
        view.getBtPaint();      //Setzt den Button auf anklickbar
        //Paint Button anklickbar machen
    }
    if(action.equals(view.ACTION_ENDE))
    {
        view.release();
        System.exit(0);
    }
    if(action.equals(view.ACTION_LINK))
    {

        String inLink = view.getTfLink();
        view.setTfLink();
        try {
            model.juliaBerechnung(dataInList(inLink));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        view.getBtPaint();

    }
    if(action.equals(view.ACTION_PAINT))
    {
        //Erzeuge Graphics!

        view.getBtPaint();      //Button nicht mehr anklickbarkeit

    }

}
public String dataInList(String link)throws IOException
{
    String temp="";
    BufferedReader inBuffer = null;
    try {
        inBuffer = new BufferedReader(new FileReader(new File(link)));
        while((temp=inBuffer.readLine())!=null)
        {
            //System.out.println("Buffer : "+temp);
            linkBuffer += temp;
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    int dateiLength = linkBuffer.length();
    inBuffer.close();

    char c;
    int index=0;
    for(int i = index;index<dateiLength;index++){
        c = linkBuffer.charAt(index);
        if((c=='+')||(c=='-'))break;
    }
    temp = "";
    for(int i=index;i<index+8;i++)
    {
        temp+=linkBuffer.charAt(i); 
    }
    return temp;        //Keine Anhang in der Datei
}

public void release() {
    // TODO Auto-generated method stub
    model = null;
    view = null;

}
public void windowClosing( WindowEvent we)
{
    view.release();
}

}

查看:

public class JuliaView extends JFrame implements Observer{

//:::: ACTIONS
public final String ACTION_ENDE = "Ende";
public final String ACTION_PAINT = "Paint";
public final String ACTION_COMPLEX = "+a.x+b.x";
public final String ACTION_LINK = "Link";
public final String ACTION_CLEAR = "Clear";
//:::: Components
private JButton btEnde;
private JButton btPaint;
private JButton btClear;
public JuliaPanel drawArea;     //Bereich für Paint
//private JButton btAutoPaint;
private JTextField tfComplex;
private JTextField tfLink;
//:::: Observer
private JuliaModel model;
private JuliaController controller;
private JuliaBild map;



public JuliaView(String titel){
    super(titel);
    this.model = model;
    //this.map = model.getMap();            //??????//Iterationsarray einbinden
    //this.model.addObserver(this);
    //controller = makeController();
    initForm();
    //makeView();
}
void makeView() {

    resetView();

    // Fenster
    addWindowListener( controller);
    pack();
    setVisible( true);

}
/*private JuliaController makeController() {                ?????????????????
    return new JuliaController();
}*/

/**
 * Anordnen der Komponenten im GridBag
 */
private void initForm(){
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLayout(new GridBagLayout());
    this.setBounds(200, 200, 800, 600);
    GridBagConstraints c = new GridBagConstraints();
    c.insets = new Insets(15,15,15,15);
    //this.add(btAutoPaint,c);


    // TextField für Kompleze Zahl
    tfComplex = new JTextField(ACTION_COMPLEX,8);
    tfComplex.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 2;
    this.getContentPane().add(tfComplex,c);

    // Link
    tfLink = new JTextField(ACTION_LINK);
    tfLink.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 1;
    c.gridwidth = 2;
    this.getContentPane().add(tfLink,c);
    // Paint Button
    btPaint = new JButton(ACTION_PAINT);
    btPaint.setEnabled(false);
    btPaint.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 2;
    c.gridwidth = 2;
    c.ipady = 40;
    this.getContentPane().add(btPaint,c);
    //CLS Button
    btClear = new JButton(ACTION_CLEAR);
    btClear.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 4;
    c.gridwidth = 2;
    this.getContentPane().add(btClear,c);
    //Exit Button
    btEnde = new JButton(ACTION_ENDE);
    btEnde.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 1;
    c.gridy = 5;
    c.gridwidth = 1;
    this.getContentPane().add(btEnde,c);
    //draw area
    drawArea = new JuliaPanel(); //Place for the JuliaSet
    c.fill = GridBagConstraints.HORIZONTAL; 
    c.gridx = 2;
    c.gridy = 0;
    c.gridwidth = 6;
    this.getContentPane().add(drawArea,c);
    setVisible( true);
    pack();
}
public void resetView(){
    this.tfComplex.setText("+a.x+b.x");
    this.tfLink.setText("c:/...");
    //drawArea.paint(g);
}
@Override
public void update(Observable m, Object o) {
    // TODO Auto-generated method stub
    if(model == m) setBtPaint();    //???

}
public void setBtPaint()
{
    btPaint.setText(ACTION_PAINT);
    btPaint.requestFocus();
    btPaint.setEnabled(true);
    drawArea.setKoordinaten(map);
    //Zeichnen
    //drawArea.repaint();
    drawArea.print(getGraphics());
    //drawArea.paint(getGraphics());
}
public void getBtPaint()
{
    btPaint.setText(ACTION_PAINT);
    drawArea.createImage();
    btPaint.requestFocus();
    btPaint.setEnabled(false);          //anklickbarkeit
}
public void setBtClear()
{
    btClear.setText(ACTION_CLEAR);
    resetView();
    drawArea.clearImage();
    btClear.requestFocus();
}
public void setTfComplex()
{
    tfComplex.setText(ACTION_COMPLEX);
    tfComplex.setCaretPosition(tfComplex.getText().length());
    tfComplex.requestFocus();
}
public void setTfLink()
{
    tfLink.setText(ACTION_LINK);
    tfLink.setCaretPosition(tfLink.getText().length());
    tfLink.requestFocus();
}
public void getBtEnde()
{
    btEnde.setText(ACTION_ENDE);
    btEnde.requestFocus();
}

public String getComplex()
{
    String temp = "";
    temp = tfComplex.getText();
    return temp;
}
public String getTfLink()
{
    String temp = tfLink.getText();
    return temp;
}

public void release(){

    dispose();

    // Controller
    controller.release();
    controller = null;

    // Model
    model.deleteObserver( this);
    model = null;
}

} 型号:

public class JuliaModel extends Observable{
//private Complex startWert;
private Complex konst;
private String pfad;
private JuliaBild map;

public JuliaModel()
{
    //startWert = new Complex(re, im);
    konst = new Complex(1.0,1.0);
    pfad = "";
    makeBild();
}
private void makeBild()
{
    map = new JuliaBild(600,600);
    System.out.println("bild true");
}
public JuliaModel(double reK, double imK)
{
    map = new JuliaBild(600,600);
    //startWert = new Complex(re, im);
    konst = new Complex(reK,imK);
    pfad = "";
}

private int grundAlgoIt(double x,double y)
{
    Complex temp = new Complex(x,y);
    double xTemp=0;
    for(int n=0;n<256;n++)
    {
        if(temp.abs()<4){return n;}
        xTemp = Math.pow(temp.getRe(), 2)-Math.pow(temp.getIm(), 2) + konst.getRe();
        temp.setIm((2*temp.getIm()*temp.getRe())+konst.getIm());//y=
        temp.setRe(xTemp);
    }
    return 0;
}
void juliaBerechnung(String input)
{
    double xmin = -2.0;//fx
    double ymin = -2.0;//fy
    double width  =  4.0;//fw       //Weg im Koordinatensystem
    double height =  4.0;//fh
    double schrittWeite = 4.0/600;
    stringToKonst(input);
    //Complex temp = new Complex(xmin-schrittWeite,1);
    double xTemp,yTemp;
    xTemp = xmin-schrittWeite;
    //durch die Pixel gehen
    for(int j=0;j<600;j++)
    {
        xTemp = xTemp+schrittWeite;
        yTemp = ymin;
        for(int i=0;i<600;i++)
        {
            yTemp = yTemp + schrittWeite;
            map.setBild(j,i,grundAlgoIt(xTemp,yTemp));
        }
    }
}

private void stringToKonst(String in)
{
    char cBuffer;
    String sBuffer="";
    double im = 0;
    double re = 0;
    for(int a=0;a<=4;a+=4)
        for(int i=0;i<4;i++)
        {
            cBuffer = in.charAt(i+a);
            sBuffer+=cBuffer;
            if(a==0&&i==4)
            {
                re = Double.parseDouble(sBuffer);
            }
            if(a==4&&i==4)
            {
                im = Double.parseDouble(sBuffer);
            }
        }
    konst.setNumber(re, im);
}
public JuliaBild getMap()
{
    return map;
}}

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

  

我的动作在我的控制器中执行不反应

这是因为您从未向控制器注册能够生成ActionEvent

的任何内容
  

我不知道如何在View中使用更新(模型,对象)方法。

当状态发生变化时,代表您的模型调用update方法。您应该根据模型的新状态更新视图。

如果您的模型支持多个属性,PropertyChangeListener可能更适合。如果模型具有不同的状态,您可能更好地定义自己的侦听器,该侦听器定义模型可能触发的状态。

但是,再次,它永远不会被调用,因为你永远不会向它添加Observer

  

下一个问题是我的GridBag。尽管代码是以oracle为例的,但它看起来很混乱。

是的,那个GridBagLayout为你

  

没有最后一个。在视图行41中,由于在模型中初始化的类,我得到一个NPE。不,为什么。我已经完成了测试,如果Class是构造的,是的,它是

第41行是哪一行?堆栈跟踪的外观是什么?

一般建议

  • 在Swing中实现MVC并不是一件容易的事,因为Swing使用了自己的VC-M形式,所以你最终会加倍努力。并不是说它无法完成,但你需要以不同的方式思考
  • 在某些形式的MVC中,控制器知道模型和视图,但模型和视图并不了解彼此,模型和视图之间的所有通信都是通过控制器完成的。这有点是Swing实现偏离的地方,但你应该知道这是它更常见的实现方式

首先定义视图和控制器之间的契约。定义控制器可以对视图执行的操作以及视图愿意接受的事件侦听器。

通常,我避免将侦听器直接连接到控制器的视图控件,而是定义视图可以生成的事件,这样,您可以在两者之间分离合约,并允许视图和控制器的不同实现一起工作

例如,如果您有一个按钮,表示用户被读取以处理输入,而不是允许控制器直接向按钮添加ActionListener,您将定义{{1视图支持的一个侦听器中的event。这样,另一个实现可以使用一些其他机制来触发事件,由控制器不关心。

有关该主题的更多讨论,请查看:

答案 1 :(得分:0)

好的,我添加了Observer并更改了类相互认识的构造函数。 但我仍然不知道我应该在哪里/或如何将actionlistener添加到控制器,因为我认为我已经实现了它。

但是现在当我初步化这个NPE的课程时:

Exception in thread "main" java.lang.NullPointerException
at JuliaView.resetView(JuliaView.java:126)
at JuliaView.makeView(JuliaView.java:57)
at JuliaController.<init>(JuliaController.java:23)
at JuliaView.<init>(JuliaView.java:44)
at Huston.main(Huston.java:10)

以下是更改的类:

型号:

public class Huston {

//static private JuliaController missionControl;
public static void main(String[] args) {
    // TODO Auto-generated method stub


    JuliaModel model = new JuliaModel();
    JuliaView view = new JuliaView(model, "JuliaSet");
    JuliaController missionControl = new JuliaController(model, view);
}

}

型号:

public class JuliaModel extends Observable{
//private Complex startWert;
private Complex konst;
private String pfad;
private JuliaBild map;

public JuliaModel()
{
    //startWert = new Complex(re, im);
    konst = new Complex(1.0,1.0);
    pfad = "";
    makeBild();
}
private void makeBild()
{
    map = new JuliaBild(600,600);
    System.out.println("bild true");
}
public JuliaModel(double reK, double imK)
{
    map = new JuliaBild(600,600);
    //startWert = new Complex(re, im);
    konst = new Complex(reK,imK);
    pfad = "";
}

private int grundAlgoIt(double x,double y)
{
    Complex temp = new Complex(x,y);
    double xTemp=0;
    for(int n=0;n<256;n++)
    {
        if(temp.abs()<4){return n;}
        xTemp = Math.pow(temp.getRe(), 2)-Math.pow(temp.getIm(), 2) + konst.getRe();
        temp.setIm((2*temp.getIm()*temp.getRe())+konst.getIm());//y=
        temp.setRe(xTemp);
    }
    return 0;
}
void juliaBerechnung(String input)
{
    double xmin = -2.0;//fx
    double ymin = -2.0;//fy
    double width  =  4.0;//fw       //Weg im Koordinatensystem
    double height =  4.0;//fh
    double schrittWeite = 4.0/600;
    stringToKonst(input);
    //Complex temp = new Complex(xmin-schrittWeite,1);
    double xTemp,yTemp;
    xTemp = xmin-schrittWeite;
    //durch die Pixel gehen
    for(int j=0;j<600;j++)
    {
        xTemp = xTemp+schrittWeite;
        yTemp = ymin;
        for(int i=0;i<600;i++)
        {
            yTemp = yTemp + schrittWeite;
            map.setBild(j,i,grundAlgoIt(xTemp,yTemp));
        }
    }
}

private void stringToKonst(String in)
{
    char cBuffer;
    String sBuffer="";
    double im = 0;
    double re = 0;
    for(int a=0;a<=4;a+=4)
        for(int i=0;i<4;i++)
        {
            cBuffer = in.charAt(i+a);
            sBuffer+=cBuffer;
            if(a==0&&i==4)
            {
                re = Double.parseDouble(sBuffer);
            }
            if(a==4&&i==4)
            {
                im = Double.parseDouble(sBuffer);
            }
        }
    konst.setNumber(re, im);
}
public JuliaBild getMap()
{
    return map;
}}

查看:

public class JuliaView extends JFrame implements Observer{

//:::: ACTIONS
public final String ACTION_ENDE = "Ende";
public final String ACTION_PAINT = "Paint";
public final String ACTION_COMPLEX = "+a.x+b.x";
public final String ACTION_LINK = "Link";
public final String ACTION_CLEAR = "Clear";
//:::: Components
private JButton btEnde;
private JButton btPaint;
private JButton btClear;
public JuliaPanel drawArea;     //Bereich für Paint
//private JButton btAutoPaint;
private JTextField tfComplex;
private JTextField tfLink;
//:::: Observer
private JuliaModel model;
private JuliaController controller;
private JuliaBild map;



public JuliaView(JuliaModel model,String titel){
    super(titel);
    this.model = model;

    //this.map = model.getMap();            //??????//Iterationsarray einbinden
    this.model.addObserver(this);
    controller = new JuliaController(model,this);

    initForm();
    //makeView();
}
void makeView() {


    // Fenster
    addWindowListener( controller);
    setVisible( true);
    pack();

    resetView();
}

/**
 * Anordnen der Komponenten im GridBag
 */
private void initForm(){
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLayout(new GridBagLayout());
    this.setBounds(200, 200, 800, 600);
    GridBagConstraints c = new GridBagConstraints();
    c.insets = new Insets(15,15,15,15);
    //this.add(btAutoPaint,c);


    // TextField für Kompleze Zahl
    tfComplex = new JTextField(ACTION_COMPLEX,8);
    tfComplex.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 2;
    this.getContentPane().add(tfComplex,c);

    // Link
    tfLink = new JTextField(ACTION_LINK);
    tfLink.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 1;
    c.gridwidth = 2;
    this.getContentPane().add(tfLink,c);
    // Paint Button
    btPaint = new JButton(ACTION_PAINT);
    btPaint.setEnabled(false);
    btPaint.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 2;
    c.gridwidth = 2;
    c.ipady = 40;
    this.getContentPane().add(btPaint,c);
    //CLS Button
    btClear = new JButton(ACTION_CLEAR);
    btClear.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 4;
    c.gridwidth = 2;
    this.getContentPane().add(btClear,c);
    //Exit Button
    btEnde = new JButton(ACTION_ENDE);
    btEnde.addActionListener(controller);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 1;
    c.gridy = 5;
    c.gridwidth = 1;
    this.getContentPane().add(btEnde,c);
    //draw area
    drawArea = new JuliaPanel();
    c.fill = GridBagConstraints.HORIZONTAL; 
    c.gridx = 2;
    c.gridy = 0;
    c.gridwidth = 6;
    this.getContentPane().add(drawArea,c);
    setVisible( true);
    pack();
}
public void resetView(){
    this.tfComplex.setText("+a.x+b.x");
    this.tfLink.setText("c:/...");
    //drawArea.paint(g);
}
@Override
public void update(Observable m, Object o) {
    // TODO Auto-generated method stub
    if(model == m) setBtPaint();    //???

}
public void setBtPaint()
{
    btPaint.setText(ACTION_PAINT);
    btPaint.requestFocus();
    btPaint.setEnabled(true);
    drawArea.setKoordinaten(map);
    //Zeichnen
    //drawArea.repaint();
    drawArea.print(getGraphics());
    //drawArea.paint(getGraphics());
}
public void getBtPaint()
{
    btPaint.setText(ACTION_PAINT);
    drawArea.createImage();
    btPaint.requestFocus();
    btPaint.setEnabled(false);          //anklickbarkeit
}
public void setBtClear()
{
    btClear.setText(ACTION_CLEAR);
    resetView();
    drawArea.clearImage();
    btClear.requestFocus();
}
public void setTfComplex()
{
    tfComplex.setText(ACTION_COMPLEX);
    tfComplex.setCaretPosition(tfComplex.getText().length());
    tfComplex.requestFocus();
}
public void setTfLink()
{
    tfLink.setText(ACTION_LINK);
    tfLink.setCaretPosition(tfLink.getText().length());
    tfLink.requestFocus();
}
public void getBtEnde()
{
    btEnde.setText(ACTION_ENDE);
    btEnde.requestFocus();
}

public String getComplex()
{
    String temp = "";
    temp = tfComplex.getText();
    return temp;
}
public String getTfLink()
{
    String temp = tfLink.getText();
    return temp;
}

public void release(){

    dispose();

    // Controller
    controller.release();
    controller = null;

    // Model
    model.deleteObserver( this);
    model = null;
}}

控制器:

public class JuliaController extends WindowAdapter implements ActionListener {

private JuliaView view;
private JuliaModel model;
private String linkBuffer;

public JuliaController(JuliaModel model,  JuliaView view){
    this.model = model;

    this.view = view;
    view.makeView();
}
@Override
public void actionPerformed(ActionEvent arg0) {
    String action = arg0.getActionCommand();
    if(action.equals(view.ACTION_CLEAR))
    {
        //Clear Graphics
        view.setBtClear();
    }
    if(action.equals(view.ACTION_COMPLEX))
    {
        String input = view.getComplex();
        view.setTfComplex();            //Zurücksetzen des Felds!

        model.juliaBerechnung(input);
        view.getBtPaint();      //Setzt den Button auf anklickbar
        //Paint Button anklickbar machen
    }
    if(action.equals(view.ACTION_ENDE))
    {
        view.release();
        System.exit(0);
    }
    if(action.equals(view.ACTION_LINK))
    {

        String inLink = view.getTfLink();
        view.setTfLink();
        try {
            model.juliaBerechnung(dataInList(inLink));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        view.getBtPaint();

    }
    if(action.equals(view.ACTION_PAINT))
    {
        //Erzeuge Graphics!

        view.getBtPaint();      //Button nicht mehr anklickbarkeit

    }

}
public String dataInList(String link)throws IOException
{
    String temp="";
    BufferedReader inBuffer = null;
    try {
        inBuffer = new BufferedReader(new FileReader(new File(link)));
        while((temp=inBuffer.readLine())!=null)
        {
            linkBuffer += temp;
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    int dateiLength = linkBuffer.length();
    inBuffer.close();

    char c;
    int index=0;
    for(int i = index;index<dateiLength;index++){
        c = linkBuffer.charAt(index);
        if((c=='+')||(c=='-'))break;
    }
    temp = "";
    for(int i=index;i<index+8;i++)
    {
        temp+=linkBuffer.charAt(i); 
    }
    return temp;        //Keine Anhang in der Datei
}

public void release() {
    // TODO Auto-generated method stub
    model = null;
    view = null;

}
public void windowClosing( WindowEvent we)
{
    view.release();
}}