Retornar uma varíavel a partir de um novo JFrame

11 respostas
Victor_Noleto

Bem, sou novo no fórum e já fiz alguns tópicos sobre algumas dúvidas que tive. Felizmente, todas elas foram resolvidas e fico muito feliz com isso. Estou desenvolvendo um pequeno e bem simples jogo como trabalho de escola, e estou estudando a interface fora da escola.

Estou quase terminando o jogo, preciso ajeitar apenas algumas coisas. Estou com dúvida agora, por exemplo, na criação do personagem. Consegui um código usando RadioButton etc, e está tudo perfeito, apenas quero fazer uma "modificação" na parte de escolher os personagens. No código atual, ao escolher o personagem e clicar "Selecionar este personagem", aparecerá uma JOptionPane perguntando se o usuário quer criar o Jogador 1 ou o Jogador 2.

Esta JOptionPane recebe a variavel op, se o usuário digitar 1 na tela será criado um novo Jogador 1, e se digitar 2 será criado um Jogador 2. Algo bem simples mesmo, de fácil entendimento.

Apenas uma parte do código ilustrando o que acabei de dizer: ok = botão [Selecionar este personagem]. arqueiroButton = representa um dos personagens no RadioButton.
ok.addActionListener(new ActionListener() {
    		
    		@Override
    		public void actionPerformed(ActionEvent arg0) {
    			
    			if (arqueiroButton.isSelected()) {
    				
    				String resposta = JOptionPane.showInputDialog("Escolher esse personagem para Player 1 ou Player 2?", op);
    				op = Integer.parseInt(resposta);
    				
    				if (op == 1) {
    					p1 = new Arqueiro();
    					player = "Player 1";
    				} else {
    					p2 = new Arqueiro();
    					player = "Player 2";
    				} 
    				
    				JOptionPane.showMessageDialog(null, String.format("%s", "Você escolheu o " + arqueiroString + " como " + player));
    			}

Ok, e aqui entra a minha dúvida. Como estou estudando interface grafico, quero que meu jogo tenha o máximo de interação "sem esforço" do usuário. Queria substituir esse JOptionPane por um novo JFrame, que contém 2 botões: Player 1 e Player 2. Se o usuário clicar em Player 1, a variavel op será 1, se clicar em Player 2, op = 2, mesma coisa.

[img]http://i.imgur.com/d8zEr6c.gif[/img]

A imagem representa bem o que eu desejo fazer. Eu até cheguei a criar uma nova classe (chamada Option) contendo esse JFrame dos botões Player 1 e Player 2, só que eu não consigo/não sei como devo fazer para passar a variavel int op criada na classe CharCreate para a classe Option e fazer que logo após que o usuário clique em um dos dois botões o código volte para a classe CharCreate com a variavel op definida nos botões.

Eu tentei chamar a classe Option na hora da escolha, mas começa a dar uns erros sobre a variavel op. Então, não sei o que fazer, =|

ok.addActionListener(new ActionListener() {
    		
    		@Override
    		public void actionPerformed(ActionEvent arg0) {
    			
    			if (arqueiroButton.isSelected()) {
    				
    				new Option(op);
    				
    				if (op == 1) {
    					p1 = new Arqueiro();
    					player = "Player 1";
    				} else {
    					p2 = new Arqueiro();
    					player = "Player 2";
    				} 
    				
    				JOptionPane.showMessageDialog(null, String.format("%s", "Você escolheu o " + arqueiroString + " como " + player));
    			}

Fiz este tópico bem organizado, realmente para facilitar o entendimento da minha dúvida!
Se puderem me ajudar, facilitará muito!
Obrigado desde já!

[size=9]Para não poluir a tela com os códigos, aqui está o Pastebin das classes CharCreate e Option:
- CharCreate: [url]http://pastebin.com/c4JpfkcK[/url]
- Option: [url]http://pastebin.com/ujbAPQsi[/url][/size]

11 Respostas

YoungCaesar

Oi Victor tudo bom?

Você pode fazer uma variável global do tipo Option na classe CharCreate e colocar o parâmetro CharCreate dentro do construtor da classe Option para vincular as duas classes. Tipo assim:

//  Classe CharCreate
   public Option opcao;
   

   public class CharCreate(){
   ...
   ok = new JButton("Selecionar este personagem.");
   ok.setActionCommand("SelecionarPersonagem");   //  você utiliza o Action Command para definir ações diferentes para vários botões
   ... 
   public void actionPerformed(ActionEvent arg0){
    if(arg0.getActionCommand().equals("SelecionarPersonagem")){  // se o usuário clicou no botão selecionar personagem
         opcao = new Option(this);    //  Instancia a variavel opcao utilizando o parâmetro "this" (Esta classe)
    }
    
   }
//  Classe Option
    public CharCreate classePai;
    public Option(CharCreate classePai){
      this.classePai = classePai;

Assim que o usuário clicar em “Selecionar este personagem” você instancia essa variável e armazena a opção que ele escolher (Jogador 1 ou Jogador 2) na variável selected que você já criou, para acessá-la é só fazer a chamada CharCreate.opcao.selected

Experimenta ai e retorne se deu certo! ^^

ViniGodoy

Veja o exemplo: http://www.guj.com.br/java/55710-jdialog-devolvendo-valor-pra-jinternalframe#292687

Victor_Noleto

MarcoAurelio, obrigado pela sua resposta, mas infelizmente está dando um erro quando tento levar o "this" como parametro ao instanciar uma nova Option.

ok.addActionListener(new ActionListener() {
    		
    		@Override
    		public void actionPerformed(ActionEvent arg0) {
    			
    			if (arqueiroButton.isSelected()) {
    				
    				opcao = new Option(this); //O erro é aqui!
    				String resposta = JOptionPane.showInputDialog("Escolher esse personagem para Player 1 ou Player 2?", op);
    				op = Integer.parseInt(resposta);
    				
    				if (op == 1) {
    					p1 = new Arqueiro();
    					player = "Player 1";
    				} else {
    					p2 = new Arqueiro();
    					player = "Player 2";
    				} 
    				
    				JOptionPane.showMessageDialog(null, String.format("%s", "Você escolheu o " + arqueiroString + " como " + player));
    			}

A minha classe Option ficou assim (resumida):
O erro é que quando vou instanciar um opcao = new Option(this); na classe CharCreate, diz que eu devo passar como parametro na classe Option um ActionListener e não um CharCreate.

public class Option extends JFrame {
	
	public JButton op1;
	public JButton op2;
	public int selected;
	
	public CharCreate classePai;
	

	public Option(CharCreate classPai) {
		
	    setFocusable(true);
	    Container c = getContentPane();
	    c.setLayout(null);

		op1 = new JButton("Player 1");
		c.add(op1);
		
		op2 = new JButton("Player 2");
		c.add(op2);
		
		op1.addActionListener(new ActionListener(){
	
			@Override
			public void actionPerformed(ActionEvent e) {
				CharCreate.playerselect = 1;
			}});
		
		op2.addActionListener(new ActionListener(){
			
			@Override
			public void actionPerformed(ActionEvent e) {
				CharCreate.playerselect = 1;
				
			}});

O que devo fazer? =|

YoungCaesar

Victor

Eu vacilei na montagem da classe, pode colocar como tava que ta certo…

public class CharCreate extends JPanel implements ActionListener {

Esse erro está acontecendo porque a classe Option esta usando a CharCreate como uma ActionListener, ou seja, os eventos vão ser executados na CharCreate.

Na classe Option, insira esse código depois do construtor:

classePai = classPai; //  Assim você vai referenciar essa classe à anterior, caso contrário gera exceção de ponteiro nulo

Mudando isso ai deve concertar!

Victor_Noleto

Eu não entendi muito bem, desculpe. Tentei adicionar apenas o classePai = classePai, mas o erro persiste.
O código (resumido) ficou assim:

Classe CharCreate
public class CharCreate extends JPanel implements ActionListener {
    
    static int playerselect = 1;
    public int op;
    private static JButton ok;
    
    public Option opcao;
    
    public CharCreate() {


   	ok.addActionListener(new ActionListener() {
    		
    		@Override
    		public void actionPerformed(ActionEvent arg0) {
    			
    			if (arqueiroButton.isSelected()) {
    				
    				opcao = new Option();
    				String resposta = JOptionPane.showInputDialog("Escolher esse personagem para Player 1 ou Player 2?", op);
    				op = Integer.parseInt(resposta);
    				
    				if (op == 1) {
    					p1 = new Arqueiro();
    					player = "Player 1";
    				} else {
    					p2 = new Arqueiro();
    					player = "Player 2";
    				} 
    				
    				JOptionPane.showMessageDialog(null, String.format("%s", "Você escolheu o " + arqueiroString + " como " + player));
    			}}}

Classe Option:

package jogo;

import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;

import jogo.CharCreate;

public class Option extends JFrame {
	
	public JButton op1;
	public JButton op2;
	public int selected;
	
	public CharCreate classePai;
	

	public Option(CreateChar classePai) {
		
		classePai = classePai;
		
		setFocusable(true);
	    Container c = getContentPane();
	    c.setLayout(null);
		
		op1 = new JButton("Player 1");
		c.add(op1);
		
		op2 = new JButton("Player 2");
		c.add(op2);
		
		op1.addActionListener(new ActionListener(){
	
			@Override
			public void actionPerformed(ActionEvent e) {
				CharCreate.playerselect = 1;
			}});
		
		op2.addActionListener(new ActionListener(){
			
			@Override
			public void actionPerformed(ActionEvent e) {
				CharCreate.playerselect = 1;
				
			}});
		
		setTitle("Definir personagem para: ");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 100);
		setLocationRelativeTo(null);
		setResizable(false);
		setVisible(true);
		add(c);
	}
}

Eu consegui rodar o programa e tudo, só não sei ainda como vou fazer uma variavel do tipo int ser definida na classe Option e fazer essa variavel voltar para a classe CharCreate (no caso a variavel op, ou selected, etc)

YoungCaesar

Outra coisa, nesse bloco:

Victor Noleto:
op1.addActionListener(new ActionListener(){
	
			@Override
			public void actionPerformed(ActionEvent e) {
				CharCreate.playerselect = 1;
			}});
		
		op2.addActionListener(new ActionListener(){
			
			@Override
			public void actionPerformed(ActionEvent e) {
				CharCreate.playerselect = 1;
				
			}});

você pode seguir o que eu te falei usando o setActionCommand pra ficar mais organizado também...

Mais outra coisa (rsrs), nessa parte:

ok.addActionListener(new ActionListener() {  
      
    @Override  
    public void actionPerformed(ActionEvent arg0) {  
          
        if (arqueiroButton.isSelected()) {  
              
            opcao = new Option(this); //O erro é aqui!  
            String resposta = JOptionPane.showInputDialog("Escolher esse personagem para Player 1 ou Player 2?", op);  
            op = Integer.parseInt(resposta);  
              
            if (op == 1) {  
                p1 = new Arqueiro();  
                player = "Player 1";  
            } else {  
                p2 = new Arqueiro();  
                player = "Player 2";  
            }   
              
            JOptionPane.showMessageDialog(null, String.format("%s", "Você escolheu o " + arqueiroString + " como " + player));  
        }

O método ActionPerformed só está servindo para verificar qual radioButton está selecionado? Se sim, para deixar seu código mais enxuto faça assim:

ok.addActionListener(new ActionListener() {  
      
    @Override  
    public void actionPerformed(ActionEvent arg0) {  
           opcao = new Option(this); 
           String resposta = JOptionPane.showInputDialog("Escolher esse personagem para Player 1 ou Player 2?", op);  
           op = Integer.parseInt(resposta);
           String classeString;

        if (arqueiroButton.isSelected()) {
            classeString = arqueiroString;
            if (op == 1) {  
                p1 = new Arqueiro();  
                player = "Player 1";  
            } else {  
                p2 = new Arqueiro();  
                player = "Player 2";  
            }   
        }else if (outraClasseButton.isSelected()) { 
            classeString = outraClasseString;
            if (op == 1) {  
                p1 = new outraClasse();  
                player = "Player 1";  
            } else {  
                p2 = new outraClasse();  
                player = "Player 2";  
            }   
 JOptionPane.showMessageDialog(null, String.format("%s", "Você escolheu o " + classeString + " como " + player));  
         }

Assim fica com menos código repetido. Isso é uma coisa interessante quando se trabalha com linguagem orientada a objetos, igual meu professor falava:
"Se você em algum momento usar Ctrl+C e Ctrl+V em Java significa que você tem que mudar alguma coisa para otimizar seu código"

Victor_Noleto

Certo Marco, obrigado pelas dicas!
Mas tipo, a terceira dica faria que primeiro o usuario decidisse o player, e depois o personagem, que não é o que eu quero, =3

Vou deixar o download do meu projeto aqui, e SE você puder/quiser editá-lo e depois me mandar, ficaria muito grato, porque vendo no código mesmo eu conseguiria entender de uma vez por toda!

YoungCaesar

Victor,

Eu alterei essas duas classes a partir dos primeiros arquivos que você mandou. Aqui funcionou perfeitamente, eu deixei a maioria de minhas alterações comentadas para você ir entendendo na medida que for lendo o código.

Como você falou que esta estudando e parece interessado eu vou te aconselhar a depois que entender esse projeto por completo continuar a implementando ele com Enum, Padrão Java Bean, Encapsulamento, hierarquia, polimorfismo… enfim tente refazer o projeto com menos linhas e mais organização esse é um ótimo meio para aprender mais.

Valeu!

Victor_Noleto

Marco, todos os “obrigados” do mundo não seria suficientes para demonstrar minha gratificação!
Realmente, muito obrigado por tudo, por ter tido paciencia em me ajudar e por ter feito isso!

Muito obrigado mesmo!
Estarei lendo o código, e assim entenderei o que você fez!

YoungCaesar

Nada que isso! :oops:

Qualquer coisa da um toque ae!

Abrçs :smiley:

Victor_Noleto

Agora meu “jogo” já está quase pronto! Só falta desenhar os personagens referentes ao Player 1 e Player 2 na tela na hora que é chamada a Arena! XD

Criado 16 de abril de 2013
Ultima resposta 16 de abr. de 2013
Respostas 11
Participantes 3