Исключение в конструкторе приложения - не удается запустить класс - PullRequest
0 голосов
/ 06 января 2019

** Я не могу создать конструктор из "GUIController" .. Программа запускается, если я удаляю эту строку "GUIController () {myModel = new TheModel (this)" но мне все еще нужно это в другой части. Пожалуйста, помогите!

**

package theclient;

import java.rmi.RemoteException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.stage.Stage;


public class GUIController extends Application {

    TheModel myModel;

    GUIController(){
        myModel = new TheModel(this);
    }

    //public void init(){}

    public TextArea myTextArea;
    public TextField myTextField;

    // Button and text field actions
    public void myButtonAction() {
        sendMsg();
    }

    public void myTextFieldAction() {
        sendMsg();
    }

    // Append coming message
    public void displayMsg(String comingMSG) {
        System.out.println("Receive 01");
        myTextArea.appendText(comingMSG);
    }

    public void sendMsg() {
        try {
            System.out.println("Send 01");
            myModel.myChatServer.tellOthers(myTextField.getText());
        } catch (RemoteException ex) {
            Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("GUI.fxml"));

        Scene scene = new Scene(root, 600, 400);

        stage.setScene(scene);
        stage.setResizable(false);
        stage.show();
    }

    public static void main(String[] args) throws Exception {
        new GUIController();
        launch(args);
    }
}

Второй класс. Я был бы благодарен, если бы вы могли предложить какие-либо изменения в коде. Заранее спасибо за ваши усилия.

package theclient;

import common.ChatServerInt;
import common.ClientInt;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TheModel implements ClientInt {

    public GUIController myCtrl;
    ChatServerInt myChatServer;

    TheModel(GUIController myCtrl) {
        this.myCtrl = myCtrl;
    }

    public ChatServerInt connection() {
        if (myChatServer == null) {
            try {
                Registry reg = LocateRegistry.getRegistry(1111);
                myChatServer = (ChatServerInt) reg.lookup("ChatService");
                myChatServer.register(this);
                myChatServer.tellOthers("I'm here!");
            } catch (RemoteException | NotBoundException ex) {
                Logger.getLogger(TheModel.class.getName()).log(Level.SEVERE, null, ex);
            }
        } return myChatServer;
    }

    @Override
    public void receive(String msg) throws RemoteException {
        myCtrl.displayMsg(msg);
    }
}

1 Ответ

0 голосов
/ 06 января 2019

Следуя шаблону проектирования Model-view-controller , модель не должна содержать ссылку на свой контроллер. Если контроллеру необходимо реагировать на изменения данных модели, это можно сделать с помощью свойств и прослушивателей. Модель содержит свойство (здесь StringProperty ), и контроллер прослушивает изменения свойства.

Для вашего кода это означает сохранение msg в StringProperty. Контроллер после построения модели присоединяет ChangeListener, который вызывает displayMsg, когда модель получает сообщение.

Используя свойство и слушатель, TheModel больше не сохраняет ссылку на GUIController и не принимает GUIController в качестве параметра в своем конструкторе.

GUIController будет выглядеть примерно так:

public class GUIController extends Application {
 ...
TheModel myModel;
 ...
GUIController(){
    myModel = new TheModel();
    // Listen for changes in the msg StringProperty and call displayMessage when it changes
    myModel.getMsgProperty().addListener(msg -> this.displayMsg(msg));
}
 ...

Обратите внимание, что конструктору для GUIController больше не нужно передавать this в конструктор TheModel. (Как правило, избегайте передачи this за пределы конструктора . Объект не полностью построен, пока конструктор не вернется.)

TheModel будет выглядеть примерно так:

public class TheModel implements ClientInt {
 ...
private StringProperty msgProperty;
 ...
//  remember to add a getter and setter for msgProperty!
 ...
@Override
public void receive(String msg) throws RemoteException {
    // When a message is received, listeners attached to msgProperty will execute when setValue is called
    msgProperty.setValue(msg);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...