JOptionPane aus einer von JPanel abgeleiteten Klasse aufrufen

Weiti

Mitglied
Hallo, meine JOptionPanes werden ohne Inhalt angezeigt wenn ich sie aus einer Klasse aufrufe die Von JPanel erbt,welches zu einem JFrame gehört.
Direkt aus dem JFrame klappt es, aber mein TicTacToe ist dann sehr ruckelig, weil ich ich paint() eines JFrames überschreibe.

Wie kann ich die JOptionPanes aus einem JPanel aufrufen?

JPanel:
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tictactoegui;

/**
 *
 * @author c.weitemeyer
 */
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

class DrawPanel extends JPanel
{

    int x = 0;
    int y = 0;
    int x2;
    int y2;
    int posx = 50;
    int posy = 50;
    int EndOFGameFlag = 0;
    int pnr = 0;
    SpielBrett b = new SpielBrett();
    Player[] Spieler = new Player[2];

    public DrawPanel()
    {
        addMouseListener(new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent me) {
              MouseClicked(me);
           
          }
        });
        addMouseMotionListener(new MouseAdapter() {
          @Override
          public void mouseMoved(MouseEvent me) {
              MouseMoved(me);

          }
        });

    }   



   private void MouseClicked(MouseEvent evt)
   {       
        x = evt.getX();
        y = evt.getY();

        int [] move = Spieler[pnr].calcMove(b,getFieldOfPos(x),getFieldOfPos(y));

        if (b.setMove(move[0], move[1], pnr))
        {
            pnr++;
            pnr = pnr % 2;
        }

        if (b.checWin(1))
        {
            EndOFGameFlag = 2;
        } else
        {
            if (b.checWin(0))
            {
                EndOFGameFlag = 1;
            }
        }
       
        if( !(b.checkDraw()) && EndOFGameFlag==0 &&Spieler[pnr].getClass()!=HumanPlayer.class)
        {
             /*
            try {
            Thread.sleep (1);
            }
            catch (InterruptedException e) {
            }
            */
            MouseClicked(evt);
        }
         
         
        repaint();
   }

   private void MouseMoved(MouseEvent evt)
   {
        x2 = evt.getX();
        y2 = evt.getY();
        repaint();
   }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        for (int i = 1; i <= 4; i++) {
            g.drawLine(i * 50, 50, i * 50, 200);
            g.drawLine(50, i * 50, 200, 50 * i);

        }
        for (int i = 0; i < b.size; i++) {
            for (int j = 0; j < b.size; j++) {
                int ir = i + 1;
                int jr = j + 1;
                switch (b.board[i][j]) {
                    case 0:
                        g.setColor(Spieler[0].color);
                        g.fillOval(ir * 50 + 5, jr * 50 + 5, 40, 40);
                        break;
                    case 1:
                        g.setColor(Spieler[1].color);
                        g.fillOval(ir * 50 + 5, jr * 50 + 5, 40, 40);
                        break;
                }
            }
        }
        g.setColor(Color.black);


        posx = getPosOfField(getFieldOfPos(x2), posx);
        posy = getPosOfField(getFieldOfPos(y2), posy);



        g.drawOval(posx + 5, posy + 5, 40, 40);

        if (EndOFGameFlag != 0) {
            showEndOFGameDialog(EndOFGameFlag);
        } else {
            if (b.checkDraw()) {
                showEndOFGameDialog();
            }
        }
    }

    private void showEndOFGameDialog(int p)
    {
        String s = "Player \"" + Spieler[(p - 1) % 2].name + "\" hat gewonnen, Neuse Spiel oder beenden?";
        showEndOFGameDialog(s);
    }

    private void showEndOFGameDialog()
    {
        String s = "Unentschieden, Neuse Spiel oder beenden?";
        showEndOFGameDialog(s);
    }

    private void showEndOFGameDialog(String s)
    {
        JFrame frame = new JFrame();

        Object[] options = {
            "Neues Spiel",
            "Ende"
        };
        int n = JOptionPane.showOptionDialog(frame,
                s,
                "Spiel zu Ende",
                JOptionPane.YES_NO_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                options[1]);

        if (n == 1) {
            System.exit(0);
        } else {
            b = new SpielBrett();
            pnr = 0;
            EndOFGameFlag = 0;
            showGameConfigDialog();
        }
        
    }

    private int getFieldOfPos(int pos)
    {
        if (pos > 50 && pos <= 100) {
            return 0;
        } else {
            if (pos > 100 && pos <= 150) {
                return 1;
            } else {
                if (pos > 150 && pos < 200) {
                    return 2;
                }
            }
        }
        return 3;
    }

    private int getPosOfField(int field, int stdValue)
    {
        switch (field) {
            case 0:
                return 50;
            case 1:
                return 100;
            case 2:
                return 150;
        }
        return stdValue;
    }

    public void showGameConfigDialog()
    {
        JFrame frame = new JFrame();

        Object[] options = {
            "anderen Mensch",
            "leichte KI",
            "mittlere KI",
            "schwere KI"
        };
        int n = JOptionPane.showOptionDialog(frame,
                "Gegen wen willst du spielen?",
                "Neues Spiel",
                JOptionPane.YES_NO_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                options[1]);

        Spieler[0] = new HumanPlayer(">Du<", Color.blue);
        switch (n) {
            case 0:
                Spieler[1] = new HumanPlayer("anderer Mensch", Color.red);
                break;
            case 1:
                Spieler[1] = new RandomKIPlayer("leichte KI", Color.green);
                break;
            case 2:
                Spieler[1] = new PassivKIPlayer("mittlere KI", Color.orange);
                break;
            case 3:
                Spieler[1] = new AgressivKIPlayer("schwere KI", Color.red);
                break;
            default:
                System.exit(0);
        }
    }

    public void centerPosition(Window gui)
    {
        Dimension dm = Toolkit.getDefaultToolkit().getScreenSize();
        double width = dm.getWidth();
        double height = dm.getHeight();
        double xPosition = (width / 2 - gui.getWidth() / 2);
        double yPosition = (height / 2 - gui.getHeight() / 2);
        gui.setLocation((int) xPosition - 200, (int) yPosition - 200);
    }
}

Aufrufende Main:
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tictactoegui;

import javax.swing.JFrame;

/**
 *
 * @author c.weitemeyer
 */
public class Main
{

    /**
     * @param args the command line arguments
     */



    public static void main(String[] args)
    {
        DrawPanel dp = new DrawPanel();
        JFrame f = new JFrame();
        dp.centerPosition(f.getFrames()[0]);
        dp.showGameConfigDialog();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(250, 250);
        f.add(dp);
        f.setVisible(true);       
    }
}

unschöne Methode in der es klappt, außerdem mit Netbeans Editor erstellt, daher der Overhead.
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * GUI.java
 *
 * Created on 12.10.2010, 12:54:44
 */
package TicTacToe;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.Window;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 *
 * @author c.weitemeyer
 */
public class GUI extends javax.swing.JFrame
{

    int x = 0;
    int y = 0;
    int x2;
    int y2;
    int posx = 50;
    int posy = 50;
    int EndOFGameFlag = 0;
    int pnr = 0;
    SpielBrett b = new SpielBrett();

    Player[] Spieler = new Player[2];


    Frame[] gui = this.getFrames();

     DrawPanel dp = new DrawPanel();
    /** Creates new form GUI */
    public GUI()
    {

        initComponents();
        showGameConfigDialog();
        centerPosition(gui[0]);
        add(dp);
        dp.setData(Spieler, b);
        dp.repaint();

    }

    
   

    @Override
    public void paint(Graphics g)
    {
        //super.paint(g);

        g.setColor(Color.white);
        g.fillRect(50, 50, 150, 150);
        g.setColor(Color.black);


        for (int i = 1; i <= 4; i++)
        {
            g.drawLine(i * 50, 50, i * 50, 200);
            g.drawLine(50, i * 50, 200, 50 * i);

        }

        for (int i = 0; i < b.size; i++)
        {
            for (int j = 0; j < b.size; j++)
            {
                int ir = i + 1;
                int jr = j + 1;
                switch (b.board[i][j])
                {
                    case 0:
                        g.setColor(Spieler[0].color);
                        g.fillOval(ir * 50 + 5, jr * 50 + 5, 40, 40);
                        break;
                    case 1:
                        g.setColor(Spieler[1].color);
                        g.fillOval(ir * 50 + 5, jr * 50 + 5, 40, 40);
                        break;
                }
            }
        }
        g.setColor(Color.black);


        posx = getPosOfField(getFieldOfPos(x2), posx);
        posy = getPosOfField(getFieldOfPos(y2), posy);



        g.drawOval(posx + 5, posy + 5, 40, 40);

        if (EndOFGameFlag != 0)
        {
            showEndOFGameDialog(EndOFGameFlag);
        } else
        {
            if (b.checkDraw())
            {
                showEndOFGameDialog();
            }
        }

    }

    /**
     * berechnet die Koordinaten des Feldes.
     */
    private int getPosOfField(int field, int stdValue)
    {
        switch (field)
        {
            case 0:
                return 50;
            case 1:
                return 100;
            case 2:
                return 150;
        }
        return stdValue;
    }

    /**
     * berechnet die Nummer des Feldes anhand der Position des Mausklicks
     * @param pos die Position des Mausklicks
     */
    private int getFieldOfPos(int pos)
    {
        if (pos > 50 && pos <= 100)
        {
            return 0;
        } else
        {
            if (pos > 100 && pos <= 150)
            {
                return 1;
            } else
            {
                if (pos > 150 && pos < 200)
                {
                    return 2;
                }
            }
        }
        return 3;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */


    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("TicTacToe by Weiti");
        setBounds(new java.awt.Rectangle(0, 0, 0, 0));
        setMinimumSize(new java.awt.Dimension(250, 250));
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                formMouseClicked(evt);
            }
        });
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                formMouseMoved(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 150, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 129, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    private void formMouseClicked(java.awt.event.MouseEvent evt) {                                  

        x = evt.getX();
        y = evt.getY();

        int [] move = Spieler[pnr].calcMove(b,getFieldOfPos(x),getFieldOfPos(y));

        if (b.setMove(move[0], move[1], pnr))
        {
            pnr++;
            pnr = pnr % 2;           
        }

        if (b.checWin(1))
        {
            EndOFGameFlag = 2;
        } else
        {
            if (b.checWin(0))
            {
                EndOFGameFlag = 1;
            }
        }
        if( !(b.checkDraw()) && EndOFGameFlag==0 &&Spieler[pnr].getClass()!=HumanPlayer.class)
        {
            try {
            Thread.sleep (1);
            }
            catch (InterruptedException e) {
            }
            formMouseClicked(evt);
        }
        dp.repaint();
        

    }                                 

    private void showEndOFGameDialog(int p)
    {
        String s = "Player \"" +Spieler[(p-1)%2].name + "\" hat gewonnen, Neuse Spiel oder beenden?";
        showEndOFGameDialog(s);
    }

    private void showEndOFGameDialog()
    {
        String s = "Unentschieden, Neuse Spiel oder beenden?";
        showEndOFGameDialog(s);
    }

    public void showEndOFGameDialog(String s)
    {
        JFrame frame = new JFrame();

        Object[] options =
        {
            "Neues Spiel",
            "Ende"
        };
        int n = JOptionPane.showOptionDialog(frame,
                s,
                "Spiel zu Ende",
                JOptionPane.YES_NO_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                options[1]);

        if (n == 1)
        {
            System.exit(0);
        } else
        {
            b = new SpielBrett();
            pnr = 0;
            EndOFGameFlag = 0;
            showGameConfigDialog();
        }
    }

    private void showGameConfigDialog()
    {
     JFrame frame = new JFrame();

        Object[] options =
        {
            "anderen Mensch",
            "leichte KI",
            "mittlere KI",
            "schwere KI"
        };
        int n = JOptionPane.showOptionDialog(frame,
                "Gegen wen willst du spielen?",
                "Neues Spiel",
                JOptionPane.YES_NO_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                options[1]);

        Spieler[0]= new HumanPlayer(">Du<", Color.blue);
        switch(n)
        {
            case 0: Spieler[1] = new HumanPlayer("anderer Mensch",Color.red); break;
            case 1: Spieler[1] = new RandomKIPlayer("leichte KI",Color.green); break;
            case 2: Spieler[1] = new PassivKIPlayer("mittlere KI",Color.orange); break;
            case 3: Spieler[1] = new AgressivKIPlayer("schwere KI",Color.red); break;
            default: System.exit(0);
        }
    }


    private void formMouseMoved(java.awt.event.MouseEvent evt) {                                
        x2 = evt.getX();
        y2 = evt.getY();
        repaint();
    }                               

    /**
     * @param args the command line arguments
     */
    public static void main(String args[])
    {
        java.awt.EventQueue.invokeLater(new Runnable()
        {

            public void run()
            {
                new GUI().setVisible(true);
            }
        });
    }

    public static void centerPosition(Window gui) {
        Dimension dm = Toolkit.getDefaultToolkit().getScreenSize();
        double width = dm.getWidth();
        double height = dm.getHeight();
        double xPosition = (width / 2 - gui.getWidth() / 2);
        double yPosition = (height / 2 - gui.getHeight() / 2);
        gui.setLocation((int) xPosition, (int) yPosition);
    }
    // Variables declaration - do not modify                     
    // End of variables declaration                   
}
 
Du rufst die JOptionPane aus der
Code:
paintComponent()
auf? Das halte ich für Unsinn. Ich weiß auch nicht was das für Auswirkungen auf die AWT-EventQueue (Thread) und andere hat, da die JOptionPane ein modales Fenster ist, dass deine übrige Anwendung blockiert.
So wie ich es beim überfliegen gesehen habe, prüfst du irgendwie das Spielende ab. Aber das darf doch nicht in
Code:
paint()
geschehen sondern eher in den Listener-Methode (
Code:
MouseMoved()
und
Code:
MouseClicked()
).

Dann verwendest du in der
Code:
showBLabla()
-Mtethode einen neuen Frame als Parent für die OptionPane. Auch das ist unsinnig. Entweder nimmst du dein DrawPanel selbst als Parent, oder null. Wenn der Frame, den du da lokal erzeugst niemals angezeigt wird, wird vermutlich auch die OptionPane nicht angezeigt.
 
hallo, es liegt wirklich daran das ich in der PaintComponent den ShowDialog mache.
Unter Windows führt das zu einem anderen Fehler: Der Dialog wird sichtbar(!) hunderte male neu gezeichnet und nach einigen Sekunden gibt es einen Stackoverflow. Linux hat schlicht den Dialog nicht mit Inhalt gezeichnet.

Mein Problem ist nun aber: Durch das beenden im MouseClicked-Event wird der letzte Zug nicht mehr angezeigt, das ist nicht so schön. hat jemand eine Idee wie ich noch ein einziges mal Zeichnen kann?
Durch ein Flag geht es nicht, da ich ja sonst nochmal klicken muss um das Spiel zu beeenden, da der Aufruf ja im MouseEvent steht.

Den anderen "Fehler" hab ich auch korregiert, ich lege kein neues Frame an sonder starte mit:
Java:
 int n = JOptionPane.showOptionDialog(this,
                s,
                "Spiel zu Ende",
                JOptionPane.YES_NO_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                options[1]);

Den JOptionPane
 
Hallo, ich habs gerade selber gemerkt:
Java:
 if (EndOFGameFlag != 0) {
            repaint();
            showEndOFGameDialog(EndOFGameFlag);
        } else {
            if (b.checkDraw()) {
                repaint();
                showEndOFGameDialog();
            }
        }
         
        repaint();

nach repaint() springt er wieder zurück und zeigt mir erst dann den Dialog.

Damit ist alles geklärt, das zeichnen läuft völlig ohne ruckeln.
Danke für die Hilfe.
Gruß, Weiti
 

Neue Themen


Zurück
Oben