私の問題は、不可解な無能さにあります。クラスにリスナーを割り当てようとするときのトラブル
ソフトウェアは、メインフレームと呼ばれるのJFrameの子クラスが複数にダイアログを聞いているJavaのSwingベースのデスクトップアプリケーションです。すべてのダイアログウィンドウは、リスナー関連の変数と関数を運ぶPDialogクラスの子です。だから私は、私は成功し、彼らがPDialogの子クラスとして継承された機能を使用してに耳を傾ける3つのダイアログを作成している
public class PDialog extends JDialog {
private MainFrameChildrenListener listener;
// Function that assigns its parameter to local listener value "listener setter"
public void addMainFrameChildrenListener(MainFrameChildrenListener listener) {
this.listener = listener;
}
public void removeMainFrameChildrenListener() {
this.listener = null;
}
public void firePDialogEvent(MainFrameChildrenEventObject event) {
this.listener.dialogEventOccured(event);
}
// This method was useful when I tried to debug with System.out.println() method
public String retrieveListenerInformation(){
if(listener == null){
return "No listener loaded";
}
return this.listener.toString();
}
}
:これはPDialogクラスは次のようになります。メインフレームクラスはMainFrameChildrenListenerリスナーオブジェクトを実装し、それはそのコンストラクタでダイアログにリスナーとして渡されます。
public class MainFrame extends JFrame implements MainFrameChildrenListener {
private PDialogCustomer dialogCustomer = new PDialogCustomer();
private PDialogOrder dialogOrder = new PDialogOrder();
private PDialogProduct dialogProduct = new PDialogProduct();
private PDialogMaterial dialogMaterial = new PDialogMaterial();
public MainFrame(){
dialogMaterial.addMainFrameChildrenListener(this);
dialogCustomer.addMainFrameChildrenListener(this);
dialogOrder.addMainFrameChildrenListener(this);
dialogProduct.addMainFrameChildrenListener(this);
System.out.println("Material dialog: " + dialogMaterial.retrieveListenerInformation());
System.out.println("Customer dialog: " + dialogCustomer.retrieveListenerInformation());
System.out.println("Order dialog: " + dialogOrder.retrieveListenerInformation());
System.out.println("Product dialog: " + dialogProduct.retrieveListenerInformation());
}
驚くべきアプリケーションの起動後にコンソールがPDialog.retrieveListenerInformation()命令を出力し、これはそれが見えるものです以下のような:私は火災リスナーイベントにしようとした場合
Material dialog: No listener loaded
Customer dialog: view.MainFrame[-deleted the .toString() rubbish to keep things short-]
Order dialog: view.MainFrame[-deleted the .toString() rubbish to keep things short-]
Product dialog: view.MainFrame[-deleted the .toString() rubbish to keep things short-]
そして、私はPDialog.firePDialogEvent()メソッドのためnullポインタ例外を取得します。 リスナーをPDialogMaterialクラスのコンストラクタを介して渡そうとしましたが、PDialogMaterialクラス内で新しいメソッドを作成しようとしても、リスナーを渡すことはできませんでした。
public class PDialogMaterial extends PDialog{
public MainFrameChildrenListener testListener;
}
public class MainFrame extends JFrame implements MainFrameChildrenListener{
public MainFrame(){
dialogMaterial.testListener = this;
dialogCustomer.addMainFrameChildrenListener(this);
dialogOrder.addMainFrameChildrenListener(this);
dialogProduct.addMainFrameChildrenListener(this);
}
}
あります:私は物事を動作させることができた唯一の方法は、公共を宣言(!EEK)などは以下のようにメインフレームのコンストラクタから、それは直接(!eeeeek)にアクセスされた新しいMainFrameChildrenListener変数を作成しましたなぜすべて継承した4つのクラスのうちの3つがと同じかリスナハンドリングメソッドは4番目のクラスとは異なる振る舞いをしていますか?私は何が欠けていますか?
コメントフォロー:
PDialogMaterial(動作していない)の完全なコード:
package view.dialogs;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import view.listeners.MainFrameChildrenEventObject;
import view.listeners.MainFrameChildrenListener;
import view.utils.DoubleFormatCheck;
public class PDialogMaterial extends PDialog {
private static final long serialVersionUID = 6190469565649183032L;
// private PMaterialFabricObject fabricObject;
public static final int FABRIC_MASK = 0;
public static final int STRAP_MASK = 1;
public static final int PARTS_MASK = 2;
public static final int THREAD_MASK = 3;
private String[] fabricMaterialList = { "Cotton", "Brocate", "Satin", "Synthetic" };
private String[] fabricColorsList = { "Red", "Green", "Blue", "Purple", "Gray", "Yellow", "Black", "Khakhi",
"Carcaline" };
private MainFrameChildrenListener listener;
private GridBagConstraints gc = new GridBagConstraints();
private Dimension size = new Dimension(300, 300);
private DoubleFormatCheck dfc = new DoubleFormatCheck();
private JTextField nameField = new JTextField(8);
private JTextField priceField = new JTextField(6);
private JTextField widthField = new JTextField(6);
private JTextField vendorField = new JTextField(8);
private JButton okButton = new JButton("Ok");
private JButton cancelButton = new JButton("Cancel");
private DefaultComboBoxModel<String> fabricMaterialComboBoxModel = new DefaultComboBoxModel<String>(
fabricMaterialList);
private DefaultComboBoxModel<String> materialColorComboBoxModel = new DefaultComboBoxModel<String>(
fabricColorsList);
private JComboBox<String> fabricMaterialComboBox = new JComboBox<String>(fabricMaterialComboBoxModel);
private JComboBox<String> fabricColorComboBox = new JComboBox<String>(materialColorComboBoxModel);
public PDialogMaterial(){
}
public void addMainFrameChildrenListener(MainFrameChildrenListener listener) {
this.listener = listener;
}
public void removeMainFrameChildrenListener() {
this.listener = null;
}
public void firePDialogMaterialEventOccured(MainFrameChildrenEventObject event) {
this.listener.dialogEventOccured(event);
}
public ImageIcon getPicture(String path) {
URL link = this.getClass().getResource(path);
ImageIcon icon = new ImageIcon(link);
return icon;
}
public void setFabricMask() {
gc.gridx = 0;
gc.gridy = 0;
gc.gridwidth = 1;
gc.gridheight = 1;
gc.weightx = 1;
gc.weighty = 1;
gc.anchor = GridBagConstraints.CENTER;
// First line - picture
gc.gridwidth = 2;
this.add(new JLabel(getPicture("/images/material_32pos.gif")), gc);
gc.gridwidth = 1;
// Second line - name
gc.gridy++;
this.add(new JLabel("Name: "), gc);
gc.gridx++;
this.add(nameField, gc);
// Third line - material
gc.gridx--;
gc.gridy++;
this.add(new JLabel("Material: "), gc);
gc.gridx++;
this.add(fabricMaterialComboBox, gc);
// Fourth line - vendor name
gc.gridx--;
gc.gridy++;
this.add(new JLabel("Vendor: "), gc);
gc.gridx++;
this.add(vendorField, gc);
// Fifth line - predominating color
gc.gridx--;
gc.gridy++;
this.add(new JLabel("Predominaing color: "), gc);
gc.gridx++;
this.add(fabricColorComboBox, gc);
// Sixth line - price
gc.gridx--;
gc.gridy++;
this.add(new JLabel("Price per square meter: "), gc);
gc.gridx++;
this.add(priceField, gc);
// Seventh line - control buttons
gc.gridx--;
gc.gridy++;
this.add(okButton, gc);
gc.gridx++;
this.add(cancelButton, gc);
}
public void setStrapMask() {
gc.gridx = 0;
gc.gridy = 0;
gc.gridwidth = 1;
gc.gridheight = 1;
gc.weightx = 1;
gc.weighty = 1;
gc.anchor = GridBagConstraints.CENTER;
// First line - picture
gc.gridwidth = 2;
this.add(new JLabel(getPicture("/images/material_32pos.gif")), gc);
gc.gridwidth = 1;
// Second line - name
gc.gridy++;
this.add(new JLabel("Name: "), gc);
gc.gridx++;
this.add(nameField, gc);
// Third line - strap width
gc.gridx--;
gc.gridy++;
this.add(new JLabel("Width: "), gc);
gc.gridx++;
this.add(widthField, gc);
// Fourth line - predominating color
gc.gridx--;
gc.gridy++;
this.add(new JLabel("Predominaing color: "), gc);
gc.gridx++;
this.add(fabricColorComboBox, gc);
// Fifth line - strap price
gc.gridx--;
gc.gridy++;
this.add(new JLabel("Price per meter: "), gc);
gc.gridx++;
this.add(priceField, gc);
// Sixth line - control buttons
gc.gridx--;
gc.gridy++;
this.add(okButton, gc);
gc.gridx++;
this.add(cancelButton, gc);
}
public void constructPDialogMaterial(int maskType){
this.setLayout(new GridBagLayout());
this.setLocationRelativeTo(this.getParent());
this.setDefaultCloseOperation(PDialog.DISPOSE_ON_CLOSE);
this.setSize(size);
this.setResizable(false);
this.setVisible(false);
this.setIconImage(getPicture("/images/material_32pos.gif").getImage());
this.nameField.setBackground(this.getBackground());
this.vendorField.setBackground(this.getBackground());
this.priceField.setBackground(this.getBackground());
switch (maskType) {
case PDialogMaterial.FABRIC_MASK:
this.setTitle("Fabric material");
setFabricMask();
break;
case PDialogMaterial.STRAP_MASK:
this.setTitle("Straps");
setStrapMask();
break;
// TODO
default:
System.out.println("Oh noes! Something happend!");
}
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String priceString = dfc.removeWhitespacesAndSwapCommas(priceField.getText());
if(dfc.testDoubleFormat(priceString)){
Double price = Double.valueOf(priceString);
MainFrameChildrenEventObject eventObject = new MainFrameChildrenEventObject(okButton, vendorField.getText(), nameField.getText(),
(String)materialColorComboBoxModel.getSelectedItem(), (String)materialColorComboBoxModel.getSelectedItem(),
price, PDialog.MATERIAL_EVENT_FABRIC);
firePDialogEvent(eventObject);
dispose();
}
else{
JOptionPane.showMessageDialog(PDialogMaterial.this, "Wrong price format", "Format error",
JOptionPane.WARNING_MESSAGE);
}
}
});
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
dispose();
}
});
}
}
PDialogCustomer(実施例)の完全なコード:
package view.dialogs;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import view.listeners.MainFrameChildrenEventObject;
public class PDialogCustomer extends PDialog {
private static final long serialVersionUID = 8431597688560531951L;
private GridBagConstraints gc = new GridBagConstraints();
private URL imageLink;
private URL iconLink;
// New customer GUI setup
JLabel nameLabel = new JLabel("Customer name: ");
JLabel addressLabel = new JLabel("Customer address: ");
JLabel dogLabel = new JLabel("Dog name: ");
JTextField nameField = new JTextField(8);
JTextField streetField = new JTextField(8);
JTextField cityField = new JTextField(8);
JTextField countryField = new JTextField(8);
JTextField dogField = new JTextField(8);
JButton okBttn = new JButton("Ok");
JButton cancelBttn = new JButton("Cancel");
// ________________________________________________________
public PDialogCustomer() {
String imagePath = "/images/customer_32pos.gif";
String iconPath = "/images/customer_16pos.gif";
this.iconLink = getClass().getResource(iconPath);
this.setIconImage(new ImageIcon(iconLink).getImage());
this.imageLink = getClass().getResource(imagePath);
this.setTitle("New customer");
nameField.setBorder(BorderFactory.createEtchedBorder());
nameField.setBackground(this.getBackground());
streetField.setBorder(BorderFactory.createTitledBorder("Street"));
streetField.setBackground(this.getBackground());
cityField.setBorder(BorderFactory.createTitledBorder("City"));
cityField.setBackground(this.getBackground());
countryField.setBorder(BorderFactory.createTitledBorder("Country"));
countryField.setBackground(this.getBackground());
dogField.setBorder(BorderFactory.createTitledBorder("Dogs name"));
dogField.setBackground(this.getBackground());
gc.weightx = 1;
gc.weighty = 1;
gc.gridheight = 1;
gc.gridwidth = 2;
gc.gridx = 0;
gc.gridy = 0;
gc.anchor = GridBagConstraints.CENTER;
add(new JLabel(new ImageIcon(imageLink)));
gc.gridwidth = 1;
gc.gridy++;
add(nameLabel, gc);
gc.gridx++;
add(nameField, gc);
gc.gridy++;
gc.gridx--;
add(addressLabel, gc);
gc.gridx++;
add(streetField, gc);
gc.gridy++;
add(cityField, gc);
gc.gridy++;
add(countryField, gc);
gc.gridy++;
gc.gridx--;
add(dogLabel, gc);
gc.gridx++;
add(dogField, gc);
gc.gridy++;
gc.gridx--;
add(okBttn, gc);
gc.gridx++;
add(cancelBttn, gc);
okBttn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String address = streetField.getText() + ", " + cityField.getText() + ", " + countryField.getText();
firePDialogEvent(new MainFrameChildrenEventObject(okBttn, nameField.getText(), address,
dogField.getText(), PDialog.CUSTOMER_EVENT));
dispose();
}
});
cancelBttn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
}
}
1)優れたヘルプを表示する:
は、この問題を説明するために、私は小さな例を構築しました.sscce.org /)。 2)「スタックトレースとは何ですか?アプリケーションエラーをデバッグするにはどうすれば使用できますか?」(http://stackoverflow.com/q/3988788/418556)&[Null Pointer Exceptionとは何ですか?私はそれを修正?](http://stackoverflow.com/q/218384/418556) –'PDialogMaterial'のコードと' PDialogOrder'のような他のコードの1つを投稿します。 – c0der
@AndrewThompson私はスタックトレースをたどり、ヌルポインタを投げたメソッドを見つけました。他のクラスがこのメソッドを問題なく使用するので、私はソリューションに近づけませんでした。シンプルなクラスでスクラッチレクレーションをした後、私は再び例外を取得しませんでした。私は最小、完全、そして実証可能な例を扱っていますが、それには時間がかかるかもしれません:(モデルとコントローラの部分が必要ですか? – Avo