Как вызвать метод в контроллере из представления? - PullRequest
0 голосов
/ 25 мая 2020

На мой взгляд, я переопределил метод actionPerformed () внутри него, я хочу вызвать метод updateMap (), который находится в моем контроллере. Я пробовал писать: MapController.updateMap (selected), но это дает ошибку: на нестандартный c метод updateMap (int) нельзя ссылаться из контекста stati c.

I Я пытался сделать updateMap () stati c, но это дает мне массу ошибок внутри updateMap (). Я просто хочу sh узнать, как я могу вызвать updateMap () контроллера внутри моего метода actionPerformed () внутри представления.

Мой контроллер:

package main.java.controllers;
import main.app.view.MapView;
import main.java.models.MapModel;
import org.w3c.dom.ls.LSOutput;

import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;

public class MapController {
    private MapView view;
    private MapModel model;

    public MapController(MapView view, MapModel model) {
        this.view = view;
        this.model = model;
        this.model.getAllRoutes();

        ArrayList<String> routes = model.getAllRoutes();
        this.view.getRouteComboBox().getSelectedItem();
        this.view.setComboBoxValues(routes);
        this.updateMap(2);
        this.view.setVisible(true);
    } //constructor end

    public void updateMap(int routeID){
        model.fillCoordinateListArray(routeID);
        Image image = null;
            try {
                URL url = new URL("https://maps.googleapis.com/maps/api/staticmap?" +
                        "&size=600x450" +
                        "&maptype=roadmap" +
                        this.model.parseCoordinates() +
                        //"San+Francisco,CA" + "%7C" +
                        //"&markers=label:1%7C40.702147,-74.015794" + "%7C" +

                        "&key=AIzaSyAbLM94WcbkB-cf_ubHXOHmCDSsNWEz7XE");
                image = ImageIO.read(url);
              //  System.out.print(url);
            } catch (IOException e) {
                System.out.println("Ongeldige URL");
                e.printStackTrace();
        }
        this.view.setImage(image);
        this.view.repaint();
    } //method end



      /*  public int getSelected(){
            return this.selected;
        } */


} //class end

Мое представление:

package main.app.view;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;


import main.java.controllers.MapController;
import main.java.models.MapModel;
import main.resources.ConnectionManager;

public class MapView extends JPanel {
    public Image image;
    private JLabel jlImage;
    private static JButton jbOk;
    private ArrayList<String> comboBoxValues;
    private JComboBox routeComboBox = new JComboBox();
    //private JComboBox<ArrayList<>>;
    private ActionListener actionListener;

    public MapView(){
        super(new FlowLayout());
        setSize(900, 450);
        this.add(getRouteComboBox());
        jbOk = new JButton("OK");
        jbOk.setActionCommand("OK");
        ListenerOfActions listener = new ListenerOfActions();
        jbOk.addActionListener(listener);
        add(jbOk);

    } //constructor end

    public void setComboBoxValues(ArrayList<String> comboBoxValues) {
        this.comboBoxValues = comboBoxValues;
        for (String item: comboBoxValues) {
            routeComboBox.addItem( item );
        }
    }

    public void setImage(Image image){
        this.image = image;
    }


    public MapView getView(){
        jlImage = new JLabel(new ImageIcon(this.image));
        add(jlImage);
        return this;
    }

    public void addListenerOfActions(ActionListener listenForAction) {
        this.actionListener = listenForAction;
    }

    public JComboBox getRouteComboBox(){
        return routeComboBox;
    }

    class ListenerOfActions implements ActionListener {
        int selected = 0;

        @Override
        public void actionPerformed(ActionEvent e) {

            String actionCommand = e.getActionCommand();
            if(actionCommand.equals("OK")) {
                 int selected = getRouteComboBox().getSelectedIndex() + 1;
                 System.out.println(selected);
                System.out.println("print1");

                   MapController.updateMap(selected);
            }
            System.out.println("print2");

        }

        public int getSelected(){
            return this.selected;
        }


    } //class end
} //class end

Ответы [ 2 ]

0 голосов

Попытка вызвать методы контроллера в режиме c определенно не является ответом, и я не рекомендую использовать синглтон, кроме случаев крайней необходимости (как рекомендовано другим ответом), поскольку использование синглтона может быть сложным в соответствии с переполнение стека Что такого плохого в синглтонах? Q / A.

Почему бы просто не дать MapView поле MapController и передать экземпляр через метод установки, который можно вызвать в MapController конструктор? Например:

public class MapView {
    private MapController controller;
    // ...

    public MapView() {
        //......
    }

    public void setMapController(MapController controller) {
        this.controller = controller;
    }

    // then here you can call the instance methods as needed

}

и подключите его следующим образом:

public class MapController {

    public class MapController {
        private MapView view;
        private MapModel model;

        public MapController(MapView view, MapModel model) {
            this.view = view;
            this.model = model;    
            view.setMapController(this);

            // .....
}

Поскольку в этом примере контроллер передается в представление через параметр установщика, а не параметр конструктора , нет никакой гарантии, что это соединение произойдет. и поэтому в представлении было бы разумно выполнить нулевой тест перед попыткой вызова методов контроллера, и, если будет обнаружен null, возможно, вызовет исключение, которое имеет смысл для вас и пользователя.

Итак, снова , это плохо: private static JButton jbOk;

Сделать все GUI компоненты экземпляром, а не stati c. Я также предпочитаю избегать использования одного ActionListener для всего GUI, так называемого прослушивателя "switch-board", так как это может излишне усложнять программу. Лучше использовать анонимных внутренних слушателей, которые вызывают методы контроллера.

0 голосов
/ 25 мая 2020

Я не думаю, что вы можете вызвать экземпляр MapController напрямую, потому что создание экземпляра Swing повлияет на новый экземпляр. Пытался использовать одноэлементный подход к MapController и вызвать его из MapView.

...