Swing Zeichenfläche im JPanel des Haupfenster anzeigen lassen

Josie

Mitglied
Hallo

Ich habe Probleme damit, eine Zeichenfläche aufzurufen.
Es geht darum, dass ich ein Hauptfenster habe. Über den Menüpunkt "Datei">"Neues Rätsel" wird ein Dialogfenster eingeblendet, wo man Höhe und Breite des Rasters eingeben kann. Der Generator erstellt daraufhin das Raster, was danach auf der Zeichenfläche im Haupfenster angezeigt werden sollte.
Nur erscheint bei mir nichts.
Ich weiss nicht, wo der Fehler ist.

Für einen Tipp wäre ich dankbar.

Hier mein Code:
Haupfenster: class BridgesMainGui
Java:
package gui;
import rechner.*;

import java.awt.*;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.*;

import java.awt.GridLayout;

import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

/**
*
* @author
*
*/

// Hauptfenster
public class BridgesMainGui extends JFrame implements ActionListener {
    JButton button;
    RaetselDialog raetselDialog;
    JPanel zeichenflaeche;
    Generator generator;
    JFileChooser fc;
    int breite;

    JPanel contentPanel;

    JMenuItem mntmNeuesRtsel, mntmRtselNeuStarten, mntmRtselLaden,
            mntmRtselSpeichern, mntmRtselSpeichernUnter, mntmBeenden;

    public BridgesMainGui() {
        setTitle("Katrin Schläpfer / M-Nr. 9241108");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 500);
       
        fc = new JFileChooser();
        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);

        // Menüleiste
        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);

        JMenu menu = new JMenu("Datei");
        menuBar.add(menu);

        mntmNeuesRtsel = new JMenuItem("Neues Rätsel");
        menu.add(mntmNeuesRtsel);
        mntmNeuesRtsel.addActionListener(this); //Beobachter registrieren

        mntmRtselNeuStarten = new JMenuItem("Rätsel neu starten");
        mntmRtselNeuStarten.addActionListener(this);
        menu.add(mntmRtselNeuStarten);

        mntmRtselLaden = new JMenuItem("Rätsel laden");
        mntmRtselLaden.addActionListener(this);//Beobachter registrieren
        menu.add(mntmRtselLaden);

        mntmRtselSpeichern = new JMenuItem("Rätsel speichern");
        mntmRtselSpeichern.addActionListener(this); //Beobachter registrieren
        menu.add(mntmRtselSpeichern);

        mntmRtselSpeichernUnter = new JMenuItem("Rätsel speichern unter");
        mntmRtselSpeichernUnter.addActionListener(this);
        menu.add(mntmRtselSpeichernUnter);

        mntmBeenden = new JMenuItem("Beenden");
        mntmBeenden.addActionListener(this); //Beobachter registrieren
        menu.add(mntmBeenden);

        // CENTER
        zeichenflaeche = new JPanel(new BorderLayout());
        zeichenflaeche.setBackground(Color.WHITE);
      
        // SOUTH
        JPanel southPanel = new JPanel();
        southPanel.setLayout(new GridLayout(3, 1));

        JPanel checkboxPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JCheckBox checkbox = new JCheckBox("Anzahl fehlender Brücken anzeigen");
        checkboxPanel.add(checkbox);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1, 2));
        JButton buttonLoesen = new JButton("Automatisch lösen");
        JButton buttonNaechsteBruecke = new JButton("Nächste Brücke");
        buttonPanel.add(buttonLoesen);
        buttonPanel.add(buttonNaechsteBruecke);

        JPanel statusPanel = new JPanel();
        statusPanel.setLayout(new FlowLayout((FlowLayout.LEFT)));
        JLabel status = new JLabel();
        statusPanel.add(status);

        southPanel.add(checkboxPanel);
        southPanel.add(buttonPanel);
        southPanel.add(statusPanel);

        // Hauptpanel (alle Komponenten zusammenfügen)
        contentPanel = new JPanel();
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPanel);
        contentPanel.setLayout(new BorderLayout());
        contentPanel.add(BorderLayout.CENTER, zeichenflaeche);
        contentPanel.add(BorderLayout.SOUTH, southPanel);
       
       
        raetselDialog = new RaetselDialog(this); //Dialogfenster erzeugen
        setVisible(true);
    }
   
  
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == mntmNeuesRtsel) {
            raetselDialog.showDialog(); //Dialogfenster anzeigen
             generator= new Generator();
           zeichenflaeche.add(generator, Borde 
           
        }
       
        if (e.getSource() == mntmRtselLaden) {
            int returnVal = fc.showOpenDialog(this);
            if (returnVal == JFileChooser.APPROVE_OPTION)
            {
                File file = fc.getSelectedFile();
            }
        }
       
        if (e.getSource() == mntmRtselSpeichernUnter) {
            int returnVal = fc.showSaveDialog(this);
            if (returnVal == JFileChooser.APPROVE_OPTION)
            {
                File file = fc.getSelectedFile();
            }
        }
        if (e.getSource() == mntmBeenden) {
            System.exit(0);
           
        }
    }

    public static void main(String[] args) {
        new BridgesMainGui();
    }

}

Dialogfenster: class RaetselDialog
Java:
package gui;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class RaetselDialog extends JDialog implements ActionListener {

    JButton abbrechenButton = new JButton("Abbrechen");
    JButton okButton = new JButton("OK");
    JTextField textFBreite = new JTextField(10);
    JTextField textFHoehe = new JTextField(10);
    JTextField textFInsel = new JTextField(10);
    // um das Ergebnis speichern
    String breite = "";
    String hoehe = "";
    String insel = "";

    public RaetselDialog(JFrame f) {

        super(f, "Neues Rätsel", true); //modales Dialogfenster
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        // Beobachter registrieren
        okButton.addActionListener(this);
        abbrechenButton.addActionListener(this);

        JPanel contentPanel = new JPanel(new BorderLayout());

        // NORTH
        JPanel radioPanel = new JPanel(new GridLayout(2, 1));
        JRadioButton rButtonAutom = new JRadioButton(
                "Automatische Grösse und Inselanzahl");
        JRadioButton rButtonWaehlen = new JRadioButton(
                "Grösse und/oder Inselanzahl festlegen");
        radioPanel.add(rButtonAutom);
        radioPanel.add(rButtonWaehlen);
        add(radioPanel, BorderLayout.NORTH);

        // CENTER
        JPanel centerPanel = new JPanel(new GridLayout(2, 1));

        JPanel groessePanel = new JPanel(new GridLayout(4, 2));
        groessePanel.setAlignmentY(JComponent.LEFT_ALIGNMENT);
        JLabel labelBreite = new JLabel("Breite", JLabel.RIGHT);
        JLabel labelHoehe = new JLabel("Höhe", JLabel.RIGHT);
        JCheckBox checkboxInsel = new JCheckBox("Inselanzahl festlegen:");
        // JLabel labelInsel = new JLabel("Inseln", JLabel.RIGHT);
        groessePanel.add(labelBreite);
        groessePanel.add(textFBreite);
        groessePanel.add(labelHoehe);
        groessePanel.add(textFHoehe);
        groessePanel.add(checkboxInsel);

        JPanel inselPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        JLabel labelInsel = new JLabel("Inseln");
        inselPanel.add(labelInsel);
        inselPanel.add(textFInsel);

        centerPanel.add(groessePanel);
        centerPanel.add(inselPanel);
        add(centerPanel, BorderLayout.CENTER);

        // SOUTH
        JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        southPanel.add(abbrechenButton);
        southPanel.add(okButton);
        add(southPanel, BorderLayout.SOUTH);

        pack();

    }

    public void showDialog() {
        textFBreite.setText("");
        textFHoehe.setText("");
        textFInsel.setText("");
        breite = "";
        hoehe = "";
        insel = "";
        setVisible(true);

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == okButton) {
            //System.out.println("ausgeführt");
        } else if (source == abbrechenButton) {
        }
        setVisible(false);
    }

    public String getBreite() {
        return breite;
    }

    public String getHoehe() {
        return hoehe;
    }

    public String getInsel() {
        return insel;
    }

   
}

class Generator
Java:
package rechner;

import java.awt.*;

import javax.swing.JPanel;

import gui.*;

public class Generator extends JPanel{
   
    public static final int ABSTAND=30;
    static final int WERT=30;
    public int hoehe;
    public int breite;
   
    RaetselDialog raetselDialog = new RaetselDialog(null);

    public Generator() {
    }
   
   
    @Override
    public void paintComponents(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
      
            breite = Integer.parseInt(raetselDialog.getBreite());
           
            hoehe = Integer.parseInt(raetselDialog.getHoehe());

            for (int x = 0; x < breite; x++) {
                for (int y = 0; y < hoehe; y++) { //waagrechte Linien
                    g2.drawLine(WERT, (y * ABSTAND) + WERT, (breite*ABSTAND), (y * ABSTAND)+WERT);
                }
               
               g2.drawLine((x * ABSTAND) + WERT, WERT, (x * ABSTAND)+WERT, (hoehe* ABSTAND)); //senkrechte Linien
               g2.setColor(Color.BLACK);
            }*/
    }
   

}
 
Dein geposteter Code scheint nicht vollständig zu sein (die actionPerformed Methode).
Aber generell gilt: Wenn man zur Laufzeit das Layout ändert sollte man immer revalidate() aufrufen. Und wenn man eine Komponente austauschen will am besten auch immer die alte Komponente zuerst entfernen:
Java:
zeichenflaeche.removeAll();
zeichenflaeche.add(generator, BorderLayout.CENTER);
zeichenflaeche.revalidate();

Edit: Vorsichtshalber kann man auch noch ein zeichenflaeche.repaint() versuchen.
 
Zusätzlich zu den Anmerkungen von Enceladus271 noch folgende Hinweise: Der Dialog raetselDialog wird nur angezeigt, verarbeitet die Eingaben jedoch nicht, so dass im Generator keine Werte für Höhe und Breite berechnet werden können. Ausserdem glaube ich, dass die Zeichenlogik im Generator nicht in die Methode paintComponents(), sondern paint() gehört.
 
Der Dialog raetselDialog wird nur angezeigt, verarbeitet die Eingaben jedoch nicht, so dass im Generator keine Werte für Höhe und Breite berechnet werden können. Ausserdem glaube ich, dass die Zeichenlogik im Generator nicht in die Methode paintComponents(), sondern paint() gehört.

Du meinst also, dass die Übergabe noch nicht stimmt? Dann muss ich das nochmals genauer anschauen.
Was ist denn der Unterschied von paintComponents() zu paint(). Ich habe gedacht, dass paintComponents() für Swing besser sei?
 
Du meinst also, dass die Übergabe noch nicht stimmt?
Genau, in der zugehörigen actionPerformed-Methode wird ja nichts gemacht und soweit ich sehe werden die Textfelder werden auch nicht anderweitig ausgelesen. Für einen ersten Test kannst du in der Zeichenroutine ja mal feste Werte für Höhe und Breite vorgeben, damit es nicht gleichzeitig so viele Baustellen sind.
Was ist denn der Unterschied von paintComponents() zu paint(). Ich habe gedacht, dass paintComponents() für Swing besser sei?
Ich denke, paintComponents zeichnet die im Container enthaltenen Komponenten, also die Unterkomponenten von generator (die es in diesem Fall nicht gibt). paint zeichnet die Komponente, in diesem Fall also generator.
 

Neue Themen


Zurück
Oben