MVC mit erweiterter View-Klasse

Hallo, ich habe 3 MVC Klassen. Funktioniert auch. Allerdings habe ich eine extra Klasse, die quasi eine Row darstellt. In dieser Klasse sind sowohl GUI-Elems als auch Daten. Es kann mehrere Objekte dieser Klasse geben. Meine Frage wäre jetzt, ob/wie diese Klasse als zusätzliche View in das Design einbinden kann.

Beispiel (erweiterte/extra Klasse):


        private boolean runs = false;

        private int level = -1;
        private int faktor = -1;

        private JProgressBar jpb = null;
        private JButton jb = null;
        private JLabel jl = null;
        private JLabel jl2 = null;

        private Clazz(int level, int faktor) {
            this.level = level;
            this.faktor = faktor;

            jpb = new JProgressBar();
            jpb.setStringPainted(true);
            jpb.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {

                }
            });

            jb = new JButton();
            jb.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                }
            });

            jl = new JLabel("", JLabel.CENTER);
            jl2 = new JLabel("", JLabel.CENTER);

            this.setLayout(new GridLayout(1, 3));
            this.add(jpb);
            this.add(jb);
            this.add(jl);
            this.add(jl2);
        }

        private void updateClazz(Clazz next) {

        }

        private void startProgress() {

        }

        private void startProgress2() {

        }

        private void startThread(boolean b) {

        }

        private void startRun() {
            runs = true;

            updateGui();
            runs = false;
        }

        private void startButton() {
                updateGui();

        }
    }```

Wie man schnell sieht, hat GUI eine update() Methode updateGui() und Clazz auch eine eigene update() Methode updateClazz(Clazz next).

Daten, level, faktor usw., und GUI-Elems, JProgressBar, JLabel usw., sollen in dieser Klasse bleiben. Allerdings stellt mir dann diese Designfrage, denn ohne ein sinnvolles Design kann ich nicht erweitern.

Danke für eure Hilfe


[Anmerkung SlaterB: nach IP wahrscheinlich gesperrter User CyborgBeta.., Zufälle natürlich immer möglich]

Ich habe es mal aufgezeichnet:

Das Problem: Bei MVC sollte eine Klasse nicht gleichzeitig View (Elems) und Model (Daten) sein, aber Row und Clazz sollten genau y-mal vorhanden und eine Einheit sein.

Lösung: ?

Da ich mich selbst aktuell mal wieder etwas mehr mit MVC und desse Varianten befasse ein recht einfacher Hinweis: manchmal kann man die einzelnen “Gruppen” nicht von einander trennen.
Siehe Swing als Bleistift: wenn ich auf einem JLabel die Methode setText(String) calle wird dass was eigentlich in meinem Model liegen soll in das Model der View-Component geschrieben (weshalb bei einem Model.update() auch zwangsläufig ein View.update() folgen muss - sofern nicht als Observer gebaut). Grund: Swing ist selbst nach MVC aufgebaut.
Nun könnte man zwar sein eigenes JLabel bauen dass bei einem paintComponent() anstatt auf das eigene Model über meinen Controller auf das Model zugreift und sich dort den Wert rauszieht (was ja intern auch passiert), aber warum? Wenn Swing von sich aus schon eine einfache Möglichkeit anbietet die Daten zu halten warum unnötig selbst was drumbauen wollen?

Letzlich würde ich zwei Ansätze vorschlagen:
Du nutzt vorgefertigte GUI-Elemente die selbst intern nach MVC gebaut sind und so eine Art eigenen Zwischenspeicher haben und nach Außen setter und update anbieten und steuerst über deinen Controller dass bei einem Update des ClazzModel die Daten ans ClazzGUI kopiert werden.
Oder du zeichnest alles selbst und baust es letztlich so dass bei einem Neuzeichnen die Daten immer aus dem Model geladen werden (also der “interne” Puffer wegfällt).

Je nach dem wie dein Gesamtkonzept geplant ist (ich persönlich bin kein Fan davon dass sich Model und View direkt kennen) gibt es die eine oder andere “bessere” Möglichkeit.

Hallo Sen,
die Klassen sehen so aus (es sind alles statische innere Klassen, damit sie in einer Datei sind, sie können aber als eine normal Klasse betrachtet werden):

        private long money;
        private List<Mine> minen;
        private List<JPanel> panels;

        private Model(Controller controller) {
            money = 1;
            minen = new ArrayList<>(Arrays.asList(new Mine(-1, 1, 1)));
            panels = new ArrayList<>(Arrays.asList(new Row(controller)));
        }

        public void increment() {
			//TODO
			//count++;
            //System.out.println("count = " + count);
            setChanged();
            //notifyObservers(Integer.valueOf(count));
        }

        private List<JPanel> getPanels() {
            return panels;
        }
    }

    private static class Mine {
        private int level;
        private int faktor;
        private int bonus;

        public Mine(int level, int faktor, int bonus) {
            this.level = level;
            this.faktor = faktor;
            this.bonus = bonus;
        }
    }

    private static class Controller extends MouseAdapter implements ActionListener {
        private Model model;

        private Controller(Model model) {
            this.model = model;
        }

        @Override
        public void mouseClicked(MouseEvent e) {
			//TODO
            //e.getSource();
        }

        @Override
        public void actionPerformed(ActionEvent e) {
        }
    }

    private static class GUI implements Observer {
        private Model model;
        private Controller controller;

        private static JFrame jf;
        private static JLabel jl;
        private static JPanel jp1;
        private static JPanel jp2;
        private static JScrollPane jsp;

        private GUI(Model model, Controller controller) {
            this.model = model;
            this.controller = controller;

            jl = new JLabel("", JLabel.CENTER);
            jp2 = new JPanel(new GridLayout(6, 1));

            jp1 = new JPanel(new BorderLayout());
            jp1.add(jp2, BorderLayout.NORTH);
            jsp = new JScrollPane(jp1);

            jf = new JFrame("IdleTycoonXyz");
            jf.setLayout(new BorderLayout());
            jf.add(jl, BorderLayout.NORTH);
            jf.add(jsp, BorderLayout.CENTER);
            jf.setSize(800, 600);
            jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            jf.setVisible(true);

            List<JPanel> panels = model.getPanels();
            for (JPanel panel : panels) {
                jp2.add(panel);
            }

			//TODO
        }

        @Override
        public void update(Observable o, Object arg) {
        }
    }

    private static class Row extends JPanel {
        private JProgressBar jpb;
        private JButton jb;
        private JLabel jl1;
        private JLabel jl2;
        private Row(Controller controller) {
            jpb = new JProgressBar();
            jpb.setStringPainted(true);
            jb = new JButton();
            jl1 = new JLabel("", JLabel.CENTER);
            jl2 = new JLabel("", JLabel.CENTER);

            jpb.addMouseListener(controller);
            jb.addActionListener(controller);

            this.setLayout(new GridLayout(1, 3));
            this.add(jpb);
            this.add(jb);
            this.add(jl1);
            this.add(jl2);
        }
    }```
Die Methoden sind nicht vollständig, erst brauche ich ein "sinnvolles" Design.
Ich bin auf einige Probleme gestoßen:
Mehrfachvererbung ist nicht erlaubt,
Interfaces dürfen keinen Konstruktor deklarieren,
abstrakte Klassen müssen, wenn vorhanden, einen Konstruktor vervollständigen,
es muss genausoviele Rows wie Mines geben, wer legt sie an, welche Klassen sollen sie kennen?
Falls du darüberschauen magst, ich hab auch noch eine andere Version, allerdings ist in der kein MVC umgesetzt.
Vielen Dank

Hmm, mir fällt lediglich zu ein: so in dieser Art eine Katastrophe - du solltest lieber noch mal zwei Schritt zurück zur Planung des Design gehen - denn solchen Spaghetti-Code guckt sich keiner freiwillig an.

Okay, du hast recht. Ich werde noch mal zur Planung zurückgehen. Viele Klassen mit Komposition oder Aggregation mit jeweiliger update()-Methode erscheint mir am besten. Trotzdem danke für deine Müh’. Und das Thema ist [gelöst].