Problemas com JFrame

7 respostas
Rpozza

Estou montando um programa que vai aplicar rotação, translação e escala em um polígono, no caso triângulo. Mas o JFrame que eu montei e que acredito estar correto não carrega corretamente quando executo, cada vez carrega de um jeito. Seguem o código e 3 screens. Se alguém puder ajudar ficarei grato :)

PS: O mesmo código foi executado nessas 3 imagens.

package Poligono;

//Imports
import java.awt.*;
import Poligono.Triangulo;
import javax.swing.*;
import javax.swing.border.LineBorder;

import java.awt.event.*;
import java.awt.geom.Line2D;


//Classe Poligono
public class TelaPrincipal extends JFrame
					implements ActionListener{
	
	Triangulo triangulo;	
	//Botões do Frame
	JButton btRotacao, btLimpar, btEscala, btSair; 
	
	//Campos
	JTextField tfNovoX, tfNovoY, tfAngulo, tfPosA, tfPosB, tfPosC;
	
	//Labels dos Botões
	JLabel lbNovoX, lbNovoY, lbAngulo, lbPosA, lbPosB, lbPosC;
	
	/*Constantes para posicionar Labels do triangulo
	O posicionamento consiste em: Coordenada + constante
	Ex: Label A: CoordX + AX, CoordY + AY
	*/
	public static final int AX = -15;
	public static final int AY = 20;
	public static final int BX = 10;
	public static final int BY = 20;
	public static final int CX = -5;
	public static final int CY = -10;
	
	
	public TelaPrincipal(){
		
		//Instancia o triangulo
		triangulo = new Triangulo();
		
		//Cria um Container
		Container container = getContentPane();
		container.setLayout(new BorderLayout());
		
		//Cria um painel para os botões
		Container pBotoes = new Container();
		pBotoes.setLayout(new GridLayout(4, 1));
		
		//Configura e acrescenta os botões no Painel de Botões
		btRotacao = new JButton();
		btRotacao.setText("Rotação");
		pBotoes.add(btRotacao);
		
		btEscala = new JButton();
		btEscala.setText("Escala");
		pBotoes.add(btEscala);
		
		btLimpar = new JButton();
		btLimpar.setText("Limpar");
		pBotoes.add(btLimpar);
		
		btSair = new JButton();
		btSair.setText("Sair");
		pBotoes.add(btSair);
		
		//Posiciona o Painel de Botões ao Oeste do Frame
		container.add(pBotoes, BorderLayout.WEST);
		
		//Cria um painel para os campos do Sul
		Container pCamposSul = new Container();
		pCamposSul.setLayout(new GridLayout(2, 3));
		
		//Configura e Acrescenta os Campos ao Painel Sul 
		lbNovoX = new JLabel();
		lbNovoX.setText("Posição X: ");
		tfNovoX = new JTextField();		
				
		lbNovoY = new JLabel();
		lbNovoY.setText("Posição Y: ");
		tfNovoY = new JTextField();
		
		
		lbAngulo = new JLabel();
		lbAngulo.setText("Ângulo: ");
		tfAngulo = new JTextField();
		
		pCamposSul.add(lbNovoX);
		pCamposSul.add(lbNovoY);
		pCamposSul.add(lbAngulo);
		
		pCamposSul.add(tfNovoX);
		pCamposSul.add(tfNovoX);			
		pCamposSul.add(tfAngulo);
				
		//Posiciona o Painel de Campos Sul ao Sul do Frame
		container.add(pCamposSul, BorderLayout.SOUTH);
		
		//Cria um painel para Desenhos e posiciona no centro
		JPanel pDesenho = new JPanel();
		pDesenho.getGraphics();	
		container.add(pDesenho, BorderLayout.CENTER);
	
		//Cria um painel para Campos ao Norte
		Container pCamposNorte = new Container();
		pCamposNorte.setLayout(new GridLayout(2, 3));
		
		//Configura e Acrescenta os campos no Painel de Campos Norte
		lbPosA = new JLabel();
		lbPosA.setText("Posição atual do Ponto A: ");
		tfPosA = new JTextField();
		
		lbPosB = new JLabel();
		lbPosB.setText("Posição atual Ponto B: ");
		tfPosB = new JTextField();
		
		lbPosC = new JLabel();
		lbPosC.setText("Posição atual Ponto C: ");
		tfPosC = new JTextField();
				
		pCamposNorte.add(lbPosA);
		pCamposNorte.add(lbPosB);
		pCamposNorte.add(lbPosC);
		pCamposNorte.add(tfPosA);		
		pCamposNorte.add(tfPosB);		
		pCamposNorte.add(tfPosC);
		
		//Posiciona o Painel de Campos Norte ao Norte do Frame
		container.add(pCamposNorte, BorderLayout.NORTH);
		
		//Adiciona os Botões ao ActionListener
		btSair.addActionListener(this);
		btRotacao.addActionListener(this);
		btLimpar.addActionListener(this);
		btEscala.addActionListener(this);
		
		
		//Ajustes do Frame Principal
		setVisible(true);
		//Desenha o triangulo
		paint(pDesenho.getGraphics());
		setSize(900, 700);
		setResizable(false);
		setLocationRelativeTo(null); 
		setTitle("Polígono");
		pDesenho.repaint();
		
		//Seta a posição atual dos pontos e "locka" os text fields
		tfPosA.setText("(" + triangulo.getPontoA().getCoordX() + ", " + triangulo.getPontoA().getCoordY() + ")");
		tfPosA.setEnabled(false);
		tfPosB.setText("(" + triangulo.getPontoB().getCoordX() + ", " + triangulo.getPontoB().getCoordY() + ")");
		tfPosB.setEnabled(false);
		tfPosC.setText("(" + triangulo.getPontoC().getCoordX() + ", " + triangulo.getPontoC().getCoordY() + ")");
		tfPosC.setEnabled(false);

	}
	
	public void paint(Graphics g){
		
		g.drawString("A", triangulo.getPontoA().getCoordX() + AX, triangulo.getPontoA().getCoordY() + AY);
		g.drawString("B", triangulo.getPontoB().getCoordX() + BX, triangulo.getPontoB().getCoordY() + BY);
		g.drawString("C", triangulo.getPontoC().getCoordX() + CX, triangulo.getPontoC().getCoordY() + CY);
		
		//Objeto graphics2D com o contexto gráfico atual
		Graphics2D g2d = (Graphics2D) g.create();
		
				
		int xPoints[] = {triangulo.getPontoA().getCoordX(), triangulo.getPontoB().getCoordX(),
				triangulo.getPontoC().getCoordX()};
		
		int yPoints[] = {triangulo.getPontoA().getCoordY(), triangulo.getPontoB().getCoordY(),
				triangulo.getPontoC().getCoordY()};
		
		g2d.setColor(Color.BLUE);
		g2d.drawPolygon(xPoints, yPoints, 3);
		g2d.dispose();
		
	}
	
	//Método actionPerformed da interface ActionListener
	public void actionPerformed(ActionEvent evento){
		
		if(evento.getSource() == btSair){
			
			//Sai da "Aplicação"
			this.dispose();
			System.exit(0);
			
		}else if(evento.getSource() == btLimpar){
			
			//Retorna à configuração default do Triangulo
			triangulo.setPontoA(new Ponto(250, 300));
			triangulo.setPontoB(new Ponto(450, 300));
			triangulo.setPontoC(new Ponto(350, 150));
			
			//Desenha novamente
			repaint();
			
		}else if(evento.getSource() == btRotacao){
			
			aplicarRotacao(Integer.parseInt(tfAngulo.getText()));
			
		}
	}
	
	//Método responsável pela rotação do triângulo
	public void aplicarRotacao(int angulo){
		JOptionPane.showMessageDialog(null, "Rotação Aplicada!");
		// TODO implentar aplicarRotacao()
	}
	

	
	public static void main(String args[]){
		
		TelaPrincipal telaPrincipal = new TelaPrincipal();
		telaPrincipal.setDefaultCloseOperation(EXIT_ON_CLOSE);
		
	}
}

[img]http://img233.imageshack.us/img233/7237/screenshot087a.png[/img]

[img]http://img69.imageshack.us/img69/5554/screenshot088f.png[/img]

[img]http://img69.imageshack.us/img69/101/screenshot089.png[/img]

7 Respostas

ViniGodoy

Não tem como ver imagens do ImageShack. Use outro serviço de imagem, ou use o botão de imagens para anexar as imagens ao seu post mesmo.

ViniGodoy

Outra coisa. O método paint é responsável por toda a pintura do JFrame, inclusive dos componentes que vão sobre ele.

Se você quer pintar só uma área do JFrame, o jeito mais fácil é criando um filho de JComponent, e sobrescrevendo seu método paintComponent. Aí vc posiciona esse novo componente sobre o JFrame, como você fez com os botões, labels, etc.

No seu código, no mínimo você deveria ter chamado super.paint(g); na primeira linha do seu método paint, para que o JFrame fizesse sua pintura normal, antes de fazer a sua personalizada.

Eu criaria um objeto chamado AreaDePintura, filho de JComponent.

Além disso, considere fortemente a possibilidade de criar uma classe para representar vetores matemáticos e uma classe para representar as matrizes de transformação 3D (isso se você não for usar a AffineTransform, do próprio Java).

Rpozza

ViniGodoy:
Outra coisa. O método paint é responsável por toda a pintura do JFrame, inclusive dos componentes que vão sobre ele.

Se você quer pintar só uma área do JFrame, o jeito mais fácil é criando um filho de JComponent, e sobrescrevendo seu método paintComponent. Aí vc posiciona esse novo componente sobre o JFrame, como você fez com os botões, labels, etc.

No seu código, no mínimo você deveria ter chamado super.paint(g); na primeira linha do seu método paint, para que o JFrame fizesse sua pintura normal, antes de fazer a sua personalizada.

Eu criaria um objeto chamado AreaDePintura, filho de JComponent.

Além disso, considere fortemente a possibilidade de criar uma classe para representar vetores matemáticos e uma classe para representar as matrizes de transformação 3D (isso se você não for usar a AffineTransform, do próprio Java).

Olá ViniGodoy,

Anexei as imagens no Post, veja como os componentes não estão sendo carregados corretamente. Detalhe que testei em 2 IDE’s e o mesmo problema ocorre, tentei no Eclipse e no JGrasp.

Vou seguir suas sugestões, vou chamar o paint(g) através do panel do centro do Frame e acrescentar o super no paint(). Assim que corrigir postarei os resultados.

Quanto aos cálculos matematicos vou fazer em uma classe específica sim, mas não pretendo utilizar a API, o professor que solicitou quer ver uma implementação de Rotação, Translação e Escala.

Muito obrigado.

Rpozza

Funcionando, muito obrigado :slight_smile:

ViniGodoy

Se você vai fazer sua própria implementação, então é importantíssimo criar uma classe para representar vetores (que representarão os pontos) e, claro, uma classe para matrizes 3D, no sistema homogêneo.

Aí vai ficar bem fácil fazer essas três operações. Se seu prof. ainda não ensinou as matrizes 3D, então vc monta uma classe que combina 1 matriz 2D + 1 vetor, o último representando a transformação de escala.

Rpozza

Aparentemente o problema era em não chamar o super…

Os valores dos pontos estão sendo armazenados na instancia da classe triângulo mesmo. Estou utilizando tbm esta solução de combinar de Matriz 2D com 1 vetor. :smiley:

ViniGodoy

Eu vi, mas em computação gráfica é muito vantajoso usar vetores para armazenar pontos, e não valores soltos como você fez. A diferença pode parecer sutil à princípio, mas depois que vc começar a ver vetores em todo lugar, vai ver que dá uma baita diferença. :slight_smile:

Criado 8 de março de 2011
Ultima resposta 8 de mar. de 2011
Respostas 7
Participantes 2