在做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还没有初始化,怎么解决?