Componentes de JDialog mesclam em JPanel

Olá pessoal, estou tendo problemas ao iniciar uma aplicação. Quando clico no botão “OK” do JDialog, era para fechar a pop-up e voltar para o JFrame. Até aí acontece tudo certo, porém quando faço a primeira ação no JPanel, os botões do JDialog aparecem no JPanel. Podem ajudar?

package jogodavelha;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;

public class ChooseSide extends JDialog{

	private static final long serialVersionUID = 1L;
	private ButtonGroup group;
	private JRadioButton x, o;
	private JLabel label;
	private RadioButtonHandler handler;
	private JButton button;
	private JogoDaVelha game;

	public ChooseSide(){

	}

	public ChooseSide(JogoDaVelha game){
		super();
		this.game = game;

		handler = new RadioButtonHandler();
		label = new JLabel("Player 1, select your symbol:");

		//RadioButton de opcoes X ou O
		group = new ButtonGroup();
		x = new JRadioButton("X");
		x.addItemListener(handler);
		group.add(x);
		o = new JRadioButton("O");
		o.addItemListener(handler);
		group.add(o);

		//OK Para voltar
		button = new JButton("OK");
		button.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent e){
				if(x.isSelected() || o.isSelected())
					dispose();
				else
					JOptionPane.showMessageDialog(null, "Choose a symbol!");
			}
		});

		this.getContentPane().setLayout(new FlowLayout());
		this.getContentPane().add(label);
		this.getContentPane().add(x);
		this.getContentPane().add(o);
		this.getContentPane().add(button);
		this.setTitle("Jogo da Velha");
		this.setSize(260, 150);
		this.setLocationRelativeTo(null);
	}

	private class RadioButtonHandler implements ItemListener{
		@Override
		public void itemStateChanged(ItemEvent e){
			if(x.isSelected())
				game.setCheckX(true);
			if(o.isSelected())
				game.setCheckO(true);

		}
	}
}

package jogodavelha;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;

import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.MouseInputListener;

public class JogoDaVelha extends JPanel {
	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	private boolean checkX;
	private boolean checkO;
	private int vetor[] = new int[10];
	private int x, y, i;

	public JogoDaVelha(){
		super();
		repaint();
	}

	public boolean isCheckX() {
		return checkX;
	}

	public void setCheckX(boolean checkX) {
		this.checkX = checkX;
	}

	public boolean isCheckO() {
		return checkO;
	}

	public void setCheckO(boolean checkO) {
		this.checkO = checkO;
	}

	//Gerar tabuleiro
	@Override
	public void paintComponent(Graphics g) {
		ManipuladorMouse handler = new ManipuladorMouse();
		this.addMouseListener(handler);

		g.setFont(new Font("Arial", Font.BOLD, 42));
		//Linhas Verticais
		g.drawLine(90, 10, 90, 250);
		g.drawLine(190, 10, 190, 250);
		//Linhas Horizontais
		g.drawLine(10, 90, 270, 90);
		g.drawLine(10, 180, 270, 180);

		// X ou O
		if(checkX && vetor[i] == 0){
			g.drawString("X", x, y);
			checkX = false;
			checkO = true;
			vetor[i] = 1;
		}
		else if(checkO && vetor[i] == 0){
			g.drawString("O", x, y);
			checkO = false;
			checkX = true;
			vetor[i] = 2;
		}
		whoWon();
	}

	public void whoWon(){
		if((vetor[1] == 1 && vetor[2] == 1 && vetor[3] == 1) ||
		   (vetor[4] == 1 && vetor[5] == 1 && vetor[6] == 1) ||
		   (vetor[7] == 1 && vetor[8] == 1 && vetor[9] == 1) ||
		   (vetor[1] == 1 && vetor[4] == 1 && vetor[7] == 1) ||
		   (vetor[2] == 1 && vetor[5] == 1 && vetor[8] == 1) ||
		   (vetor[3] == 1 && vetor[6] == 1 && vetor[9] == 1) ||
		   (vetor[1] == 1 && vetor[5] == 1 && vetor[9] == 1) ||
		   (vetor[3] == 1 && vetor[5] == 1 && vetor[7] == 1) ){
			JOptionPane.showMessageDialog(null, "Player 1 wins!");
			System.exit(0);
		}
		if((vetor[1] == 2 && vetor[2] == 2 && vetor[3] == 2) ||
			(vetor[4] == 2 && vetor[5] == 2 && vetor[6] == 2) ||
			(vetor[7] == 2 && vetor[8] == 2 && vetor[9] == 2) ||
			(vetor[1] == 2 && vetor[4] == 2 && vetor[7] == 2) ||
			(vetor[2] == 2 && vetor[5] == 2 && vetor[8] == 2) ||
			(vetor[3] == 2 && vetor[6] == 2 && vetor[9] == 2) ||
			(vetor[1] == 2 && vetor[5] == 2 && vetor[9] == 2) ||
			(vetor[3] == 2 && vetor[5] == 2 && vetor[7] == 2) ){
			JOptionPane.showMessageDialog(null, "Player 2 wins!");
			System.exit(0);
		}

	}

	private class ManipuladorMouse implements MouseInputListener {
		@Override
		public void mouseClicked(MouseEvent e) {
			//PRIMEIRO QUADRANTE
			if((e.getX() > 0 && e.getX() < 90) && (e.getY() > 0 && e.getY() < 90)){
				x = 30;
				y = 60;
				i = 1;
				repaint();
			}

			//SEGUNDO QUADRANTE
			if((e.getX() > 91 && e.getX() < 190) && (e.getY() > 0 && e.getY() < 90)){
				x = 125;
				y = 60;
				i = 2;
				repaint();
			}

			//TERCEIRO QUADRANTE
			if((e.getX() > 191 && e.getX() < 290) && (e.getY() > 0 && e.getY() < 90)){
				x = 220;
				y = 60;
				i = 3;
				repaint();
			}

			//QUARTO QUADRANTE
			if((e.getX() > 0 && e.getX() < 90) && (e.getY() > 91 && e.getY() < 180)){
				x = 30;
				y = 150;
				i = 4;
				repaint();
			}

			//QUINTO QUADRANTE
			if((e.getX() > 91 && e.getX() < 190) && (e.getY() > 91 && e.getY() < 180)){
				x = 125;
				y = 150;
				i = 5;
				repaint();
			}

			//SEXTO QUADRANTE
			if((e.getX() > 191 && e.getX() < 290) && (e.getY() > 91 && e.getY() < 180)){
				x = 220;
				y = 150;
				i = 6;
				repaint();
			}

			//SETIMO QUADRANTE
			if((e.getX() > 0 && e.getX() < 90) && (e.getY() > 180 && e.getY() < 260)){
				x = 30;
				y = 230;
				i = 7;
				repaint();
			}

			//OITAVO QUADRANTE
			if((e.getX() > 91 && e.getX() < 190) && (e.getY() > 181 && e.getY() < 270)){
				x = 125;
				y = 230;
				i = 8;
				repaint();
			}

			//NONO QUADRANTE
			if((e.getX() > 191 && e.getX() < 290) && (e.getY() > 181 && e.getY() < 270)){
				x = 220;
				y = 230;
				i = 9;
				repaint();
			}
		}
		@Override
		public void mousePressed(MouseEvent e) {
			// TODO Auto-generated method stub

		}
		@Override
		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub

		}
		@Override
		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub

		}
		@Override
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub

		}
		@Override
		public void mouseDragged(MouseEvent e) {
			// TODO Auto-generated method stub

		}
		@Override
		public void mouseMoved(MouseEvent e) {
			// TODO Auto-generated method stub

		}
	}
}

package jogodavelha;

import javax.swing.JFrame;

public class Main {
	public static void main(String[] args) {
		JFrame window = new JFrame("Jogo da Velha");
		JogoDaVelha game = new JogoDaVelha();

		//JANELA DE JOGO
		window.getContentPane().add(game);
		window.setSize(300,300);
		window.setResizable(false);
		window.setVisible(true);
		window.setLocationRelativeTo(null);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		//POP-UP DE ESCOLHA
		ChooseSide side = new ChooseSide(game);
		side.setVisible(true);
		side.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

	}
}

Segue um print da tela

Não sei o motivo disso estar acontecendo, tem vários problemas no programa:

  • ChooseSide

Por se tratar de um dialog, recomendo que seja modal, que impedem a ação do clique em outras janelas enquanto aberta:

public ChooseSide(JogoDaVelha game){
	super();
	setModal(true);
  • JogoDaVelha

Nunca misture código do funcionamento do programa com a renderização, remova o handler do paintComponent e coloque no construtor

public JogoDaVelha() {
	super();
	ManipuladorMouse handler = new ManipuladorMouse();
	this.addMouseListener(handler);
	repaint();
}

Também há mistura de código em outras partes, que devem ser removidos:
Toda vez que o repaint de um component com paintComponent customizado é chamado, é OBRIGATÓRIO limpar o component, então o paintComponent ficará assim:

@Override
public void paintComponent(Graphics g) {
	// ManipuladorMouse handler = new ManipuladorMouse();
	// this.addMouseListener(handler);

	// Limpa o component
	Graphics2D g2d = (Graphics2D) g.create();
	g2d.setBackground(getBackground());
	g2d.clearRect(0, 0, getWidth(), getHeight());

	g2d.setFont(new Font("Arial", Font.BOLD, 42));
	// Linhas Verticais
	g2d.drawLine(90, 10, 90, 250);
	g2d.drawLine(190, 10, 190, 250);
	// Linhas Horizontais
	g2d.drawLine(10, 90, 270, 90);
	g2d.drawLine(10, 180, 270, 180);
	
	// desenhar os X e O

	// X ou O
	// if(checkX && vetor[i] == 0){
	// g.drawString("X", x, y);
	// checkX = false;
	// checkO = true;
	// vetor[i] = 1;
	// }
	// else if(checkO && vetor[i] == 0){
	// g.drawString("O", x, y);
	// checkO = false;
	// checkX = true;
	// vetor[i] = 2;
	// }
	// whoWon();

	g2d.dispose();
}

Mas ao fazer a limpeza, tudo será apagado, então é necessário redesenhar os X e O, poderá usar o atributo vetor que armazena o estado do jogo para redesenhar.

  • ManipuladorMouse

Refaça todas as condições assim:

		int i = 0;
		// PRIMEIRO QUADRANTE
		if ((e.getX() > 0 && e.getX() < 90)
				&& (e.getY() > 0 && e.getY() < 90)) {
			i = 1;
		}

e no final acrescente:

		if (i == 0) {
			// clicou fora da area
			return;
		}
		// X ou O
		if (checkX && vetor[i] == 0) {
			// g.drawString("X", x, y);
			checkX = false;
			checkO = true;
			vetor[i] = 1;
		} else if (checkO && vetor[i] == 0) {
			// g.drawString("O", x, y);
			checkO = false;
			checkX = true;
			vetor[i] = 2;
		}
		repaint();
		whoWon();

Os atributos x,y e i se tornarão desnecessários e poderão ser removidos

1 curtida

Boa tarde! Muito obrigado pelas dicas!
Porém o x e y são para marcar as coordenadas de desenhar o “X” e “O” no meio do quadrante.
Onde eu estaria chamando a drawString então? O Vetor é salvo normalmente, porém não verifica se está ocupado ou não, sobrepondo os valores. E apenas desenha um X ou um O. Não é salvo o desenho anterior…

Estaria no paintComponent, seria mais ou menos assim:

if (vetor[1] == 1) {
    g2d.drawString("X", 30, 60);
} else if (vetor[1] == 2) {
    g2d.drawString("O", 30, 60);
}

O vetor está guardando o estado atual do jogo:

Se vetor[i] == 0, então está livre
Se vetor[i] == 1, então está com X
Se vetor[i] == 2, então está com O

Está sendo verificado no evento do clique:

	if (checkX && vetor[i] == 0) {
		// g.drawString("X", x, y);
		checkX = false;
		checkO = true;
		vetor[i] = 1;
	} else if (checkO && vetor[i] == 0) {
		// g.drawString("O", x, y);
		checkO = false;
		checkX = true;
		vetor[i] = 2;
	}
1 curtida

assim ele exclui a string anterior… mas muito obrigado!

Tratei o X,Y como vetores também e deu certo. Muito obrigado!