kingxip 2010-08-05 18:42
浏览 342
已采纳

swing中采用mvc,导致空指针

在做swing的时候习惯把界面和逻辑分开,比如一个窗体我采用下面方式:
[code="java"]public MainFrame extends JFrame {
MainFrameController controller;
public MainFrame {
initUI();
controller=new MainFrameController(this);
}
}

public MainFrameController {
MainFrame view;
public MainFrameController(MainFrame view) {
this.view=view;
}
}[/code]
controller用来控制view的事件处理以及载入数据等,但是经常导致空指针:
下面简单例子:
[code="java"]
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class MainFrame extends JFrame {

private static final long serialVersionUID = 1L;
private JPanel jContentPane = null;
private JPanel topPanel = null;
private JPanel buttonPanel = null;
private JButton OKButton = null;
private JButton CancelButton = null;
private ViewController controller = null;

public MainFrame() {
    super();
    this.setSize(384, 260);
    this.setContentPane(getJContentPane());
    this.setTitle("JFrame");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    controller = new ViewController(this);
}

private JPanel getJContentPane() {
    if (jContentPane == null) {
        jContentPane = new JPanel();
        jContentPane.setLayout(null);
        jContentPane.add(getTopPanel(), null);
        jContentPane.add(getButtonPanel(), null);
    }
    return jContentPane;
}

private JPanel getTopPanel() {
    if (topPanel == null) {
        topPanel = new CustomPanel(controller);
        topPanel.setBounds(new Rectangle(0, 0, 380, 180));
    }
    return topPanel;
}

private JPanel getButtonPanel() {
    if (buttonPanel == null) {
        buttonPanel = new JPanel();
        buttonPanel.setBounds(new Rectangle(0, 180, 380, 45));
        buttonPanel.add(getOKButton(), null);
        buttonPanel.add(getCancelButton(), null);
    }
    return buttonPanel;
}

private JButton getOKButton() {
    if (OKButton == null) {
        OKButton = new JButton();
        OKButton.setText("⊕");
        OKButton.addActionListener(new ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
                controller.action_OK(e);
            }
        });
    }
    return OKButton;
}

private JButton getCancelButton() {
    if (CancelButton == null) {
        CancelButton = new JButton();
        CancelButton.setText("Cancel");
        CancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
                controller.action_cancel(e);
            }
        });
    }
    return CancelButton;
}

public static void main(String[] args) {
    new MainFrame().setVisible(true);
}

}

class CustomPanel extends JPanel {

private static final long serialVersionUID = 1L;
private JComboBox typeComboBox = null;
private JLabel typeLabel = null;
private JPanel changedPanel = null;

private PanelEventHandler handler;

public CustomPanel(PanelEventHandler handler) {
    this.handler = handler;
    typeLabel = new JLabel();
    typeLabel.setBounds(new Rectangle(20, 20, 40, 20));
    typeLabel.setText("Type:");
    this.setSize(380, 180);
    this.setLayout(null);
    this.add(getTypeComboBox(), null);
    this.add(typeLabel, null);
    this.add(getChangedPanel(), null);
}

private JComboBox getTypeComboBox() {
    if (typeComboBox == null) {
        typeComboBox = new JComboBox();
        typeComboBox.setBounds(new Rectangle(70, 20, 285, 20));
        typeComboBox.addItem("All");
        typeComboBox.addItem("Vector");
        typeComboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                handler.action_CustomPanel_combox(e);
            }
        });
    }
    return typeComboBox;
}

private JPanel getChangedPanel() {
    if (changedPanel == null) {
        changedPanel = new JPanel();
        changedPanel.setLayout(null);
        changedPanel.setBounds(new Rectangle(22, 50, 340, 126));
        changedPanel.setBorder(BorderFactory
                .createTitledBorder("This Panel should be changed according to the jcombox"));
    }
    return changedPanel;
}

}

interface PanelEventHandler {
public void action_CustomPanel_combox(ItemEvent e);
}

class ViewController implements PanelEventHandler {
public ViewController(JFrame owner) {
}

public void action_OK(ActionEvent e) {
}

public void action_cancel(ActionEvent e) {
}

@Override
public void action_CustomPanel_combox(ItemEvent e) {
    if (e.getStateChange() == ItemEvent.SELECTED) {
        String select = e.getItem().toString();
        System.out.println(select);
    }
}

}
[/code]
handler为空,因为在构建的时候那个controller还没有初始化,怎么解决?

  • 写回答

3条回答 默认 最新

  • qinglangee 2010-08-06 19:56
    关注

    this作为参数传进去,不需要初始化完,只要对象已经存在了就可以了
    this传的是引用,后面进行的view初始化动作完成后,引用的就是初始化完成的对象

    再说, controller = new ViewController(this); 放在最后也还是在它的构造函数中,view不还是没构建完么

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名