Atualizar um JPanel

10 respostas
ZombieW

Olá a todos, sou novo no fórum, e estou desenvolvendo meu TCC com Java.
Não sou expert e nem newbie, mas vivo cheio de dúvidas! =P

Bom vamos ao meu caso: estou desenvolvendo um Batalha Naval com interface gráfica, e separo toda parte do projeto em vários .java

A Main, constitue em chamar o metodo Tabuleiro, que por sua vez constitue em chamar um Painel pra cada parte do BorderLayout.

No PainelDireito, eu crio 100 botões representando a matriz 10x10 do tabuleiro.

No PainelSul, eu tenho um botão, onde o usuário clica e define onde ficará suas embarcações, ele digita através de um InputBox.

No tratador de evento de click desse botão, eu faço todas as verificações que preciso, e chamo uma função que está no PainelDireito que tem que colorir os botões passados como parâmetro.

É passado corretamente as posições para a função, que colori os botões, porém, não é atualizado as cores nos botões.

Não coloco o código do projeto todo aqui, porque ficaria muito extenso.

Segue o código do PainelDireito, lembrando novamente que é passado corretamente qual botão deve ser colorido na função “pintaBotao”.

Obrigado.

package BS;
import java.awt.GridLayout;
import java.awt.Color;
import java.awt.event.ComponentEvent;
import javax.swing.JButton;
import javax.swing.JPanel;

public class PainelDireito extends JPanel{
    private JButton [][] botaoMatrizJ2;
    private TratadorClickDir click;
    public PainelDireito(){
        setLayout(new GridLayout(10,10));
        botaoMatrizJ2 = new JButton [10][10];
        click = new TratadorClickDir(botaoMatrizJ2);
        for(int i=65;i<75;i++){
            for(int j=0;j<10;j++){
                char a = (char)i;
                String aux = a+"",aux2 = (aux+(j+1));
                botaoMatrizJ2[i-65][j] = new JButton(aux2);
                botaoMatrizJ2[i-65][j].setSize(20, 20);
                Color azul2 = new Color(0,0,160);
                Color azul1 = new Color(0,64,128);
                if(i%2==0){
                    if(j%2==0){
                        botaoMatrizJ2[i-65][j].setBackground(azul1);
                        botaoMatrizJ2[i-65][j].setForeground(Color.WHITE);
                    }else{
                        botaoMatrizJ2[i-65][j].setBackground(azul2);
                        botaoMatrizJ2[i-65][j].setForeground(Color.BLACK);
                    }
                }else{
                    if(j%2==1){
                        botaoMatrizJ2[i-65][j].setBackground(azul1);
                        botaoMatrizJ2[i-65][j].setForeground(Color.WHITE);
                    }else{
                        botaoMatrizJ2[i-65][j].setBackground(azul2);
                        botaoMatrizJ2[i-65][j].setForeground(Color.BLACK);
                    }
                }
                botaoMatrizJ2[i-65][j].addActionListener(click);
                add(botaoMatrizJ2[i-65][j]);
            }
        }
    }
    public void pintaBotao(int i,int j, Color corFundo, Color corLetra){
        botaoMatrizJ2[i-65][j-1].setBackground(corFundo);
        botaoMatrizJ2[i-65][j-1].setForeground(corLetra);
    }
}

10 Respostas

juno.rr

Já tentou dar um repaint no botão?

ZombieW

Então, logo após o código que digitei acima, tentei fazer isso:

public void componentResized(ComponentEvent ce){ repaint(); }
Mas como nunca usei esse método, corri pro fórum! rs

Pode me dar um exemplo?

E agradeço o interesse em ajudar! ^^

Eric_Yuzo

Chame o repaint direto no método pintaBotao:

public void pintaBotao(int i,int j, Color corFundo, Color corLetra){ botaoMatrizJ2[i-65][j-1].setBackground(corFundo); botaoMatrizJ2[i-65][j-1].setForeground(corLetra); botaoMatrizJ2[i-65][j-1].repaint(); }

ZombieW

Obrigado.
Mas não funcionou, então creio que ainda não é aí o problema... :(

Vamos tentar detalhar mais:

Quando clico no botão "bSubmarino", ele abre esse tratador:
package BS;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JOptionPane;

public class TratadorSubmarino implements ActionListener{
    private JButton botaoSubmarino;
    Color vinho = new Color(128,0,0);
    PainelDireito teste = new PainelDireito();
    TratadorSubmarino(JButton botaoTratadorSubmarino, Color vinho) {
        botaoSubmarino = botaoTratadorSubmarino;
    }
    public void actionPerformed(ActionEvent ae){
        String[] vetSubmarino = new String[4];
        int[] vetNum1Submarino = new int[4];
        int[] vetNum2Submarino = new int[4];
        int VLN_ConfirmSubmarino;
        for(int i=0;i<vetSubmarino.length;i++){
            vetSubmarino[i] = JOptionPane.showInputDialog(null,"Escreva as posições de onde ficarão seus Submarinos!\n" +
                    "Submarino número "+(i+1),"Atenção!",JOptionPane.INFORMATION_MESSAGE);
        }
        if(vetSubmarino[0].toUpperCase().equals(vetSubmarino[1].toUpperCase())
                || vetSubmarino[0].toUpperCase().equals(vetSubmarino[2].toUpperCase())
                || vetSubmarino[0].toUpperCase().equals(vetSubmarino[3].toUpperCase())
                || vetSubmarino[1].toUpperCase().equals(vetSubmarino[2].toUpperCase())
                || vetSubmarino[1].toUpperCase().equals(vetSubmarino[3].toUpperCase())
                || vetSubmarino[2].toUpperCase().equals(vetSubmarino[3].toUpperCase())){
            JOptionPane.showMessageDialog(null,"Por favor refaça a operação, os dados estão incorretos!","Atenção!",JOptionPane.INFORMATION_MESSAGE);
        }else{
            //ConfirmDialog: Sim = 0 / Não = 1 / Cancel = 2
            VLN_ConfirmSubmarino = JOptionPane.showConfirmDialog(null,"Posições:\nSubmarino 1: "+vetSubmarino[0].toUpperCase()+
                    "\nSubmarino 2: "+vetSubmarino[1].toUpperCase()+"\nSubmarino 3: "+vetSubmarino[2].toUpperCase()+
                    "\nSubmarino 4: "+vetSubmarino[3].toUpperCase()+"\nConfirma?","Atenção!",JOptionPane.YES_NO_OPTION);
            if(VLN_ConfirmSubmarino==0){
                JOptionPane.showMessageDialog(null,"Seus Submarinos foram posicionados!","Atenção!",JOptionPane.INFORMATION_MESSAGE);
                //chamar metodo para colorir as posições
                botaoSubmarino.setEnabled(false);
            }else{
                JOptionPane.showMessageDialog(null,"Por favor refaça a operação com os dados corretos!","Atenção!",JOptionPane.INFORMATION_MESSAGE);
            }
        }
        for(int k=0;k<vetSubmarino.length;k++){
            char var1 = vetSubmarino[k].toUpperCase().charAt(0);
            vetNum1Submarino[k] = (int)var1;
            vetNum2Submarino[k] = Integer.parseInt(vetSubmarino[k].substring(1));
            teste.pintaBotao(vetNum1Submarino[k],vetNum2Submarino[k],vinho,Color.WHITE);
        }
    }
}

E a partir dele que quero pintar os botões, a chamada está incorreta?

Eric_Yuzo

Não sei se é o mais indicado, mas quando faço modificações em componentes de um JPanel eu costumo usar updateUI:

public void pintaBotao(int i,int j, Color corFundo, Color corLetra){ botaoMatrizJ2[i-65][j-1].setBackground(corFundo); botaoMatrizJ2[i-65][j-1].setForeground(corLetra); updateUI(); }

ZombieW

Nem com o update, nem com o repaint, ou ambos, deu certo…

Creio que seja mesmo na segunda classe que postei…

Tem alguma falha nela?

Eric_Yuzo

Na classe TratadorSubmarino você está instanciando um objeto PainelDireito e invocando o método a partir dele.

Provavelmente deve haver outra instância de PainelDireito adicionado ao formulário principal, que não está sofrendo a alteração.

Dê uma verificada no método Tabuleiro que você citou no primeiro post pra ver se é isso mesmo.

ZombieW

Ok, não queria chegar a tanto, mas vamos lá;

Main:
package BS;
public class Main {
    public static void main(String[] args) {
        new Tabuleiro();
    }
}
Tabuleiro:
package BS;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JOptionPane;

public class Tabuleiro extends JFrame implements KeyListener{
    private PainelNorte pn;
    private PainelEsquerdo pe;
    private PainelCentral pc;
    private PainelDireito pd;
    private PainelSul ps;
    
    public Tabuleiro(){
        super("BattleShips");
        this.addKeyListener(this);
        setLayout(new BorderLayout(10,5));
        pn = new PainelNorte();
        pe = new PainelEsquerdo();
        pc = new PainelCentral();
        pd = new PainelDireito();
        ps = new PainelSul();
        add(pn, BorderLayout.NORTH);
        add(pe, BorderLayout.WEST);
        add(pc, BorderLayout.CENTER);
        add(pd, BorderLayout.EAST);
        add(ps, BorderLayout.SOUTH);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        Dimension dimensao = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(dimensao);
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setVisible(true);
    }
    public void keyTyped(KeyEvent ke){}
    public void keyPressed(KeyEvent ke){}
    public void keyReleased(KeyEvent ke){
        if(ke.getKeyCode() == KeyEvent.VK_ESCAPE){
            JOptionPane.showMessageDialog(null,"Saindo...","Atenção!",JOptionPane.INFORMATION_MESSAGE);
            System.exit(0);
        }
    }
}
PainelDireito:
package BS;
import java.awt.GridLayout;
import java.awt.Color;
import java.awt.event.ComponentEvent;
import javax.swing.JButton;
import javax.swing.JPanel;

public class PainelDireito extends JPanel{
    private JButton [][] botaoMatrizJ2;
    private TratadorClickDir click;
    public PainelDireito(){
        setLayout(new GridLayout(10,10));
        botaoMatrizJ2 = new JButton [10][10];
        click = new TratadorClickDir(botaoMatrizJ2);
        for(int i=65;i<75;i++){
            for(int j=0;j<10;j++){
                char a = (char)i;
                String aux = a+"",aux2 = (aux+(j+1));
                botaoMatrizJ2[i-65][j] = new JButton(aux2);
                botaoMatrizJ2[i-65][j].setSize(20, 20);
                Color azul2 = new Color(0,0,160);
                Color azul1 = new Color(0,64,128);
                if(i%2==0){
                    if(j%2==0){
                        botaoMatrizJ2[i-65][j].setBackground(azul1);
                        botaoMatrizJ2[i-65][j].setForeground(Color.WHITE);
                    }else{
                        botaoMatrizJ2[i-65][j].setBackground(azul2);
                        botaoMatrizJ2[i-65][j].setForeground(Color.BLACK);
                    }
                }else{
                    if(j%2==1){
                        botaoMatrizJ2[i-65][j].setBackground(azul1);
                        botaoMatrizJ2[i-65][j].setForeground(Color.WHITE);
                    }else{
                        botaoMatrizJ2[i-65][j].setBackground(azul2);
                        botaoMatrizJ2[i-65][j].setForeground(Color.BLACK);
                    }
                }
                botaoMatrizJ2[i-65][j].addActionListener(click);
                add(botaoMatrizJ2[i-65][j]);
            }
        }
    }
    public void pintaBotao(int i,int j, Color corFundo, Color corLetra){
        botaoMatrizJ2[i-65][j-1].setBackground(corFundo);
        botaoMatrizJ2[i-65][j-1].setForeground(corLetra);
        botaoMatrizJ2[i-65][j-1].repaint();
        updateUI();
    }
}

PainelSul:

package BS;
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.FlowLayout;
import javax.swing.JLabel;

public class PainelSul extends JPanel{
    private JButton bSubmarino;
    private TratadorSubmarino submarino;
    private JButton bCruzador;
    private TratadorCruzador cruzador;
    private JButton bHidroAviao;
    private TratadorHidroAviao hidroAviao;
    private JButton bCargueiro;
    private TratadorCargueiro cargueiro;
    private JButton bEncouracado;
    private TratadorEncouracado encouracado;
    private JButton bPortaAviao;
    private TratadorPortaAviao portaAviao;
    public PainelSul(){
        setLayout(new FlowLayout());

        JLabel lSubmarino = new JLabel("Submarino");
        add(lSubmarino);
        bSubmarino = new JButton(" ");
        Color vinho = new Color(128,0,0);
        bSubmarino.setBackground(vinho);
        submarino = new TratadorSubmarino(bSubmarino,vinho);
        bSubmarino.addActionListener(submarino);
        add(bSubmarino);

        JLabel lCruzador = new JLabel("Cruzador");
        add(lCruzador);
        bCruzador = new JButton(" ");
        bCruzador.setBackground(Color.YELLOW);
        cruzador = new TratadorCruzador(bCruzador);
        bCruzador.addActionListener(cruzador);
        add(bCruzador);

        JLabel lHidroAviao = new JLabel("Hidro-Avião");
        add(lHidroAviao);
        bHidroAviao = new JButton(" ");
        bHidroAviao.setBackground(Color.LIGHT_GRAY);
        hidroAviao = new TratadorHidroAviao(bHidroAviao);
        bHidroAviao.addActionListener(hidroAviao);
        add(bHidroAviao);

        JLabel lCargueiro = new JLabel("Cargueiro");
        add(lCargueiro);
        bCargueiro = new JButton(" ");
        Color laranjaEscuro = new Color(225,113,0);
        bCargueiro.setBackground(laranjaEscuro);
        cargueiro = new TratadorCargueiro(bCargueiro);
        bCargueiro.addActionListener(cargueiro);
        add(bCargueiro);

        JLabel lEncouracado = new JLabel("Encouraçado");
        add(lEncouracado);
        bEncouracado = new JButton(" ");
        bEncouracado.setBackground(Color.DARK_GRAY);
        encouracado = new TratadorEncouracado(bEncouracado);
        bEncouracado.addActionListener(encouracado);
        add(bEncouracado);

        JLabel lPortaAviao = new JLabel("Porta-Avião");
        add(lPortaAviao);
        bPortaAviao = new JButton(" ");
        Color roxo = new Color(128,0,128);
        bPortaAviao.setBackground(roxo);
        portaAviao = new TratadorPortaAviao(bPortaAviao);
        bPortaAviao.addActionListener(portaAviao);
        add(bPortaAviao);
    }
}
TratadorSubmarino:
package BS;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JOptionPane;

public class TratadorSubmarino implements ActionListener{
    private JButton botaoSubmarino;
    Color vinho = new Color(128,0,0);
    PainelDireito teste = new PainelDireito();
    TratadorSubmarino(JButton botaoTratadorSubmarino, Color vinho) {
        botaoSubmarino = botaoTratadorSubmarino;
    }
    public void actionPerformed(ActionEvent ae){
        String[] vetSubmarino = new String[4];
        int[] vetNum1Submarino = new int[4];
        int[] vetNum2Submarino = new int[4];
        int VLN_ConfirmSubmarino;
        for(int i=0;i<vetSubmarino.length;i++){
            vetSubmarino[i] = JOptionPane.showInputDialog(null,"Escreva as posições de onde ficarão seus Submarinos!\n" +
                    "Submarino número "+(i+1),"Atenção!",JOptionPane.INFORMATION_MESSAGE);
        }
        if(vetSubmarino[0].toUpperCase().equals(vetSubmarino[1].toUpperCase())
                || vetSubmarino[0].toUpperCase().equals(vetSubmarino[2].toUpperCase())
                || vetSubmarino[0].toUpperCase().equals(vetSubmarino[3].toUpperCase())
                || vetSubmarino[1].toUpperCase().equals(vetSubmarino[2].toUpperCase())
                || vetSubmarino[1].toUpperCase().equals(vetSubmarino[3].toUpperCase())
                || vetSubmarino[2].toUpperCase().equals(vetSubmarino[3].toUpperCase())){
            JOptionPane.showMessageDialog(null,"Por favor refaça a operação, os dados estão incorretos!","Atenção!",JOptionPane.INFORMATION_MESSAGE);
        }else{
            //ConfirmDialog: Sim = 0 / Não = 1 / Cancel = 2
            VLN_ConfirmSubmarino = JOptionPane.showConfirmDialog(null,"Posições:\nSubmarino 1: "+vetSubmarino[0].toUpperCase()+
                    "\nSubmarino 2: "+vetSubmarino[1].toUpperCase()+"\nSubmarino 3: "+vetSubmarino[2].toUpperCase()+
                    "\nSubmarino 4: "+vetSubmarino[3].toUpperCase()+"\nConfirma?","Atenção!",JOptionPane.YES_NO_OPTION);
            if(VLN_ConfirmSubmarino==0){
                JOptionPane.showMessageDialog(null,"Seus Submarinos foram posicionados!","Atenção!",JOptionPane.INFORMATION_MESSAGE);
                //chamar metodo para colorir as posições
                botaoSubmarino.setEnabled(false);
            }else{
                JOptionPane.showMessageDialog(null,"Por favor refaça a operação com os dados corretos!","Atenção!",JOptionPane.INFORMATION_MESSAGE);
            }
        }
        for(int k=0;k<vetSubmarino.length;k++){
            char var1 = vetSubmarino[k].toUpperCase().charAt(0);
            vetNum1Submarino[k] = (int)var1;
            vetNum2Submarino[k] = Integer.parseInt(vetSubmarino[k].substring(1));
            teste.pintaBotao(vetNum1Submarino[k],vetNum2Submarino[k],vinho,Color.WHITE);
        }
    }
}

Desculpe postar tudo, mas realmente já não sei onde possa estar o erro... :( :(

Eric_Yuzo

Na classe Tabuleiro existe a variável pd com uma referência de PainelDireito. Este objeto é o que está sendo exibido no formulário.

Na classe TratadorSubmarino existe a variável teste com uma referência de outra instância de PainelDireito. O método pintarBotao está setando a cor de fundo do botão contido em teste. Enquanto você está visualizando no formulário o conteúdo de pd da classe Tabuleiro, que não sofreu a modificação.

ZombieW

Ok, entendi meu erro…

No “TratadorSubmarino”, mudei a chamada para:

Mas estou recebendo essa mensagem do compilador:

non-static method pintaBotao(int,int,java.awt.Color,java.awt.Color) cannot be referenced from a static context.

E se no “PainelDireito” eu mudo o método de:

Para:

O erro no “TratadorSubmarino” desaparece, porém, no “PainelDireito” acusa em todas as variáveis:

non-static variavel “nome da variavel” cannot be referenced from a static context.

E empaquei de novo. :?

:@EDIT

Funcionou galera…por tentativa e erro, fuçando aos poucos…

Tentei isso:

O erro parou de acusar, e meu método funcionou!!

Agradeço a ajuda, e em breve postarei mais dúvidas!! :smiley:

Criado 4 de setembro de 2010
Ultima resposta 5 de set. de 2010
Respostas 10
Participantes 3