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
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;
}
assim ele exclui a string anterior… mas muito obrigado!
Tratei o X,Y como vetores também e deu certo. Muito obrigado!