Problema em atualizar posição de JLabel

3 respostas
Tiago_Lemes_Daneluzz

Segue o método que atualiza a posição de um JLabel do meu programa:

public void move(){
    this.onde = this.coisaLabel.getLocation();    //Atributo da classe pra armazenar a posição atual
    this.coisaLabel.setLocation(onde.x+1,onde.y);        //Anda "1" pra direita
    this.coordX.setText(""+this.onde.x);       //Exibe a posição pro usuário
}

Depois que inseri a terceira linha, o JLabel atualiza seu x, mas em seguida volta para a posição inicial, e ele não “anda”. Quando eu comento essa terceira linha esse problema deixa de acontecer.

O método é chamado dentro de uma thread de outra classe:

public void run(){
    while (running){
        try {
            Thread.sleep(100);
            this.janela.move();   // <-------------------------- Aqui
        } catch (InterruptedException ex) {
            Logger.getLogger(Controlador.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
}

3 Respostas

D

O layout do parent component deve ser null:

// JComponent parent = (JComponent) coisaLabel.getParent(); // se não souber quer é o parent
parent.setLayout(null);

Caso não seja possível:

JPanel panel = new JPanel();
panel.setLayout(null);
panel.add(coisaLabel);
// panel.setPreferredSize(new Dimension(500,500)); // insere uma área para o label correr
// add o panel no lugar que estaria o label
Tiago_Lemes_Daneluzz

Aparentemente funcionou, a posição x está sendo alterada, mas a imagem que se move não aparece mais.

D

O parent component deve também ter um tamanho para o label correr, pois o parent funciona como clipping, por isso quando o label se posiciona fora do parent, ele some.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Tela extends JFrame {
    JLabel label;
    Thread thread;
    int direcao;
    boolean running;
    public Tela() {
        super();
        label = new JLabel("Teste");
        label.setOpaque(true);
        label.setBackground(Color.BLUE);
        label.setForeground(Color.WHITE);
        label.setSize(50,30);
        
        JPanel panel = new JPanel();
        panel.setLayout(null);
        panel.setPreferredSize(new Dimension(300,300));
        panel.add(label);
        
        label.setLocation(0,100);
        
        direcao = 10;
        
        getContentPane().add(panel);
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        thread = new Thread() {
            public void run(){
                while (running){
                    try {
                        Thread.sleep(100);
                        move();   // <-------------------------- Aqui
                    } catch (InterruptedException ex) {
                        //Logger.getLogger(Controlador.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    
                }
            }
        };
        
        running = true;
        
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                running = false;
            }
        });
    }
    
    public void move(){
        Point onde = this.label.getLocation();    //Atributo da classe pra armazenar a posição atual
        // vai e volta
        if (onde.x+direcao > 250) { // panel.width - label.width
            direcao = -10;
        } else if (onde.x+direcao < 0) {
            direcao = 10;
        }
        this.label.setLocation(onde.x+direcao,onde.y);        //Anda "1" pra direita
        // this.coordX.setText(""+this.onde.x);       //Exibe a posição pro usuário
    }
    
    public void iniciarThread() {
        thread.start();
    }
    
    public static void main(String[] args) {
        Tela tela = new Tela();
        tela.setVisible(true);
        tela.iniciarThread();
    }
}

Fazer um component se mover não é fácil, tem varias formas de fazer isso e depende muito do modo que vc está fazendo o seu projeto.

Acredito que a forma mais simples está descrita acima, mas tem vários problemas de se fazer dessa forma.

Isso acontece porque o LayoutManager tem a responsabilidade de posicionar os components, quando o layout é null, não existe um layout posicionando os components, permitindo usar o setLocation

Criado 7 de janeiro de 2017
Ultima resposta 12 de jan. de 2017
Respostas 3
Participantes 2