Uma dúvida sobrre CardLayout. Painéis não aparecem no Frame

Pessoal, boa noite. Essa é minha nova conta aqui no GUJ, pois perdi a senha e o email da outra bem antiga que tinha.
Bem, resolvi estudar Java novamente, pois tenho um aplicativo pequeno para fazer. Então estou com uma dúvida grande com componentes Swing, especificamente com CardLayout.
Pesquisei no fórum, mas não encontrei a resposta para o problema.
Pois bem, vamos ao problema. Para praticar estou desenvolvendo uma calculadora de Juros Compostos ue em um CardLayout calcula o Montante de uma aplicação após um certo período informando-se o capital e a taxa. Em outros dois CardLayouts essa aplicação deve calcular o capital informando os outros parâmetros e no terceiro CardLayout o período da aplicação informado-se os outros parâmetros.
O probelma que estou tendo é que apenas o painel CardLayout para se calcular o capital aparece no BordeLayout. O painel para se calcular o Montante aparece apenas o botão para se calcular tal Montante, mas não aperece nem os JLabels e nem os TextFields para se informar os parêmetros. Esse mesmo problema ocorre com o painel para se calcular o período, sendo que quando o peinel para o cálculo do capital está visível ao se clicar no botão período não ocorre nada, porém se clicarmos no botão para apresentação do painel montante o Frame é limpo, ou seja, o botão montante serve para se limpar to Frame.
Também gostaria de saber como posso limitar o tamanho dos botões, pois eles preenchem toda a área do BorderLayout.
O código da Classe está abaixo, caso algém possa avaliá-lo e detectar o probelma, ficaria muito grato.

package jurosCompostos;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class JurosCompostos extends JFrame implements ActionListener
{
	JPanel painelEscolha, painelCard, painelMontante, painelPeriodo, painelCapital,
	       painelSuperior, painelCardCampos, painelCardBotao, painelCardResults,
	       painelGridCapital, painelGridMontante, painelGridPeriodo;
	
	JButton botaoCalcular, botaoLimpar, botaoMontante, botaoPeriodo, botaoCapital,
			botaoCalculaMontante, botaoCalculaPeriodo, botaoCalculaCapital;
	
	JLabel labelCapital, labelPeriodo, labelPercentual, labelMontante, labelDesejo;
	
	JTextField tfCapital, tfPeriodo, tfPercentual, tfMontante;
	
	JurosCompostos()
	{
		setTitle("Calculando Propriedades Dos Juros Compostos");
		setBounds(500, 250, 280, 200);
		getContentPane().setBackground(Color.BLUE);
		getContentPane().setLayout(new BorderLayout());
		
		// Botões para calcular os parâmetros desejados
		botaoCalculaMontante = new JButton("Calcular Montante"); // botaoCalcular.addActionListener(this);
		//botaoCalculaMontante.setPreferredSize(new Dimension(150, 25));
		botaoCalculaPeriodo = new JButton("Calcular Período");
		botaoCalculaCapital = new JButton("Calcular Capital");
		
		// Botão para limpar os campos e botões para se escolher o que se deseja calcular
		botaoLimpar = new JButton("Limpar"); // botaoLimpar.addActionListener(this);
		botaoMontante = new JButton("Montante"); botaoMontante.addActionListener(this);
		botaoPeriodo = new JButton("Período"); botaoPeriodo.addActionListener(this);
		botaoCapital = new JButton("Capital"); botaoCapital.addActionListener(this);
		
		// Labels para se informar os parâmetros a serem digitados
		labelCapital = new JLabel("Capital");
		labelPeriodo = new JLabel("Período");
		labelPercentual = new JLabel("Percentual");
		labelMontante = new JLabel("Montante");
		labelDesejo = new JLabel("O que deseja calcular", JLabel.CENTER);
		
		// TextFields para se digitar os parâmetros
		tfCapital = new JTextField(8);
		tfPeriodo = new JTextField(3);
		tfPercentual = new JTextField(2);
		tfMontante = new JTextField(8);
		
		// Painel superior. Tem o objetivo de apresentar a mensagem perguntando o que se deseja calcular
		// e também contém o painel que contém os botões para a escolha.
		painelSuperior = new JPanel(); painelSuperior.setLayout(new GridLayout(2, 1));
		painelSuperior.add(labelDesejo);
		
		// Painel escolha. Esse painel contém os botões para a escolha e será inserido no painelSuperior.
		painelEscolha = new JPanel(); painelEscolha.setLayout(new GridLayout(1, 3));
		painelEscolha.add(botaoMontante); painelEscolha.add(botaoCapital); painelEscolha.add(botaoPeriodo);
		
		
		painelSuperior.add(painelEscolha); // Adiciona o painelEscolha no painelSuperior
		
		// painelGridMontante. Contém os Labels e os TextFields para se calcular o montante.
		// Esse paniel será inserido no painelMontante a seguir.
		painelGridMontante = new JPanel(); painelGridMontante.setLayout(new GridLayout(4, 2));
		painelGridMontante.add(labelCapital); painelGridMontante.add(tfCapital);
		painelGridMontante.add(labelPercentual); painelGridMontante.add(tfPercentual);
		painelGridMontante.add(labelPeriodo); painelGridMontante.add(tfPeriodo);
		painelGridMontante.add(labelMontante); painelGridMontante.add(tfMontante);
		
		// painelMontante. Esse painel contém o painelGridMontante e o botão que receberá o evento para tal cálculo.
		painelMontante = new JPanel(); painelMontante.setLayout(new BorderLayout());
		painelMontante.add("North", painelGridMontante);
		painelMontante.add("Center", botaoCalculaMontante);
		
		// painelGridPeriodo. Contém os Labels e os TextFields para se calcular o período.
		painelGridPeriodo = new JPanel(); painelGridPeriodo.setLayout(new GridLayout(4, 2));
		painelGridPeriodo.add(labelCapital); painelGridPeriodo.add(tfCapital);
		painelGridPeriodo.add(labelMontante); painelGridPeriodo.add(tfMontante);
		painelGridPeriodo.add(labelPercentual); painelGridPeriodo.add(tfPercentual);
		painelGridPeriodo.add(labelPeriodo); painelGridPeriodo.add(tfPeriodo);
		
		// painelPeriodo. Esse painel contém o painel gridPeriodo e o botão para se calcular o período.
		painelPeriodo = new JPanel(); painelPeriodo.setLayout(new BorderLayout());
		painelPeriodo.add("North", painelGridPeriodo);
		painelPeriodo.add("Center", botaoCalculaPeriodo);
		
		// painelGridCapital. Contém os Labels e os TextFields para se calcular o capital.
		// Esse painel será inserido no painelCapital a seguir.
		painelGridCapital = new JPanel(); painelGridCapital.setLayout(new GridLayout(4, 2));
		painelGridCapital.add(labelMontante); painelGridCapital.add(tfMontante);
		painelGridCapital.add(labelPercentual); painelGridCapital.add(tfPercentual);
		painelGridCapital.add(labelPeriodo); painelGridCapital.add(tfPeriodo);
		painelGridCapital.add(labelCapital); painelGridCapital.add(tfCapital);
		
		// painelCapital. Esse painel contém o painelGridCapital e o botão para se calcular o capital.
		painelCapital = new JPanel(); painelCapital.setLayout(new BorderLayout());
		painelCapital.add("North", painelGridCapital);
		painelCapital.add("Center", botaoCalculaCapital);
		
		
		// painelCard. Esse painel recebe os painéis painelMontante, painelCapital e painelPeriodo.
		painelCard = new JPanel(); painelCard.setLayout(new CardLayout());
		painelCard.add(painelMontante, "Montante");
		painelCard.add(painelCapital, "Capital");
		painelCard.add(painelPeriodo, "Período");
		
		// Insere no Frame o peinelSuperior e o painelCard. 
		getContentPane().add("North", painelSuperior);
		getContentPane().add("South", painelCard);
	}
	
	public void actionPerformed(ActionEvent e)
	{
		CardLayout card = (CardLayout) painelCard.getLayout();
		
		if(e.getSource() == botaoMontante)
			card.show(painelCard, "Montante");
		
		if(e.getSource() == botaoCapital)
			card.show(painelCard, "Capital");
		
		if(e.getSource() == botaoPeriodo)
			card.show(painelCard, "Periodo");
	}
}

E então, algué pode dar uma ajuda?
Agradeço desde já a colaboração. Muito obrigado.

As posições BorderLayout.NORTH e BorderLayout.SOUTH só respeitam o preferedHeight do componente e esticam ele completamente na horizontal.

As posições BorderLayout.EAST e BorderLayout.WEST só respeitam o preferedWidth do componente e esticam ele completamente na vertical.

A posição BorderLayout.CENTER não respeita nada e estica o componente tanto na horizontal quanto na vertical.

Para fazer telas elaboradas, você precisa criar composições de painéis com diferentes layouts cada painel, leva um tempo pra aprender, mas uma vez dominando, fica sensacional a responsividade das telas.

1 curtida

Opa, obrigado pela resposta. Só não entendi o porque esticando os componentes não se apresenta os Cardlayout para o Montante e para o Período e sim para o Capital.
Mas tudo bem, obrigado pela dica, tentarei elaborar um Layout diferente para cada caso, é isso quue o livro que estou acomoanhando faz. Não será difícil, pois já tenho conhecimento sobre os outros gerenciadores de Layout, tentarei um com FlowLayout e outro com GridLayout.
Depois volto falar sobre o resultado

O problema não era a expansão do BorderLayout, mas sim porque eu estava usando os mesmos Jlabels e JTextFields para os três painéis. É preciso usar JTextFields e JLabels diferentes para os três peinéis. Modifiquei o código e deu certo, aparecem os três painéis certinhos no Frame.
Agora fica a dúvida ainda, por que somente o painel do Capital aparecia se incluí ele após o painel Montante.
Antes de tentar com JLabels e JTextFields diferentes tentei com JTabbedPane e deu o MESMÍSSIMO problema!!! :dizzy_face:, incrível, não?
Agora só falta implementar os cálculos, mas isso é fácil :grinning: :rofl:
Bem, o código modificado do novo aplicativo está aí abaixo para quem quiser comparar e para os que estão iniciando os estudos com componentes Swing e AWT:

package jurosCompostos;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class JurosCompostos extends JFrame implements ActionListener
{
	JPanel painelEscolha, painelCard, painelMontante, painelPeriodo, painelCapital,
	       painelSuperior, painelCardCampos, painelCardBotao, painelCardResults,
	       painelGridCapital, painelGridMontante, painelGridPeriodo;
	
	JButton botaoCalcular, botaoLimpar, botaoMontante, botaoPeriodo, botaoCapital,
			botaoCalculaMontante, botaoCalculaPeriodo, botaoCalculaCapital;
	
	JLabel labelCapitalCapital, labelPeriodoCapital, labelPercentualCapital, labelMontanteCapital,
		   labelCapitalMontante, labelMontanteMontante, labelPercentualMontante, labelPeriodoMontante,
		   labelCapitalPeriodo, labelMontantePeriodo, labelPercentualPeriodo, labelPeriodoPeriodo, labelDesejo;
	
	JTextField tfCapitalMontante, tfPeriodoMontante, tfPercentualMontante, tfMontanteMontante,
				tfMontanteCapital, tfPeriodoCapital, tfPercentualCapital,tfCapitalCapital,
				tfMontantePeriodo, tfCapitalPeriodo, tfPercentualPeriodo, tfPeriodoPeriodo;
	
	JurosCompostos()
	{
		setTitle("Calculando Propriedades Dos Juros Compostos");
		setBounds(500, 250, 280, 200);
		getContentPane().setBackground(Color.BLUE);
		getContentPane().setLayout(new BorderLayout());
		
		// Botões para calcular os parâmetros desejados
		botaoCalculaMontante = new JButton("Calcular Montante"); // botaoCalcular.addActionListener(this);
		//botaoCalculaMontante.setPreferredSize(new Dimension(150, 25));
		botaoCalculaPeriodo = new JButton("Calcular Período");
		botaoCalculaCapital = new JButton("Calcular Capital");
		
		// Botão para limpar os campos e botões para se escolher o que se deseja calcular
		botaoLimpar = new JButton("Limpar"); // botaoLimpar.addActionListener(this);
		botaoMontante = new JButton("Montante"); botaoMontante.addActionListener(this);
		botaoPeriodo = new JButton("Período"); botaoPeriodo.addActionListener(this);
		botaoCapital = new JButton("Capital"); botaoCapital.addActionListener(this);
		
		// Labels para se informar os parâmetros a serem digitados
		labelCapitalCapital = new JLabel("Capital");
		labelPeriodoCapital = new JLabel("Período");
		labelPercentualCapital = new JLabel("Percentual");
		labelMontanteCapital = new JLabel("Montante");
		
		labelCapitalMontante = new JLabel("Capital");
		labelPeriodoMontante = new JLabel("Perído");
		labelPercentualMontante = new JLabel("Percentual");
		labelMontanteMontante = new JLabel("Montante");
		
		labelCapitalPeriodo = new JLabel("Capital");
		labelMontantePeriodo = new JLabel("Montante");
		labelPercentualPeriodo = new JLabel("Percentual");
		labelPeriodoPeriodo = new JLabel("Período");
		labelDesejo = new JLabel("O que deseja calcular", JLabel.CENTER);
		
		// TextFields para se digitar os parâmetros
		tfCapitalMontante = new JTextField(8);
		tfPeriodoMontante = new JTextField(3);
		tfPercentualMontante = new JTextField(2);
		tfMontanteMontante = new JTextField(8);
		tfMontanteCapital = new JTextField(8);
		tfPeriodoCapital = new JTextField(3);
		tfPercentualCapital = new JTextField(2);
		tfCapitalCapital = new JTextField(8);
		tfMontantePeriodo = new JTextField(8);
		tfCapitalPeriodo = new JTextField(8);
		tfPercentualPeriodo = new JTextField(2);
		tfPeriodoPeriodo = new JTextField(2);
		
		// Painel superior. Tem o objetivo de apresentar a mensagem perguntando o que se deseja calcular
		// e também contém o painel que contém os botões para a escolha.
		painelSuperior = new JPanel(); painelSuperior.setLayout(new GridLayout(2, 1));
		painelSuperior.add(labelDesejo);
		
		// Painel escolha. Esse painel contém os botões para a escolha e será inserido no painelSuperior.
		painelEscolha = new JPanel(); painelEscolha.setLayout(new GridLayout(1, 3));
		painelEscolha.add(botaoMontante); painelEscolha.add(botaoCapital); painelEscolha.add(botaoPeriodo);
		
		
		painelSuperior.add(painelEscolha); // Adiciona o painelEscolha no painelSuperior
		
		// painelGridMontante. Contém os Labels e os TextFields para se calcular o montante.
		// Esse paniel será inserido no painelMontante a seguir.
		painelGridMontante = new JPanel(); painelGridMontante.setLayout(new GridLayout(4, 2));
		painelGridMontante.add(labelCapitalMontante); painelGridMontante.add(tfCapitalMontante);
		painelGridMontante.add(labelPercentualMontante); painelGridMontante.add(tfPercentualMontante);
		painelGridMontante.add(labelPeriodoMontante); painelGridMontante.add(tfPeriodoMontante);
		painelGridMontante.add(labelMontanteMontante); painelGridMontante.add(tfMontanteMontante);
		
		// painelMontante. Esse painel contém o painelGridMontante e o botão que receberá o evento para tal cálculo.
		painelMontante = new JPanel(); painelMontante.setLayout(new BorderLayout());
		painelMontante.add("North", painelGridMontante);
		painelMontante.add("Center", botaoCalculaMontante);
		
		// painelGridPeriodo. Contém os Labels e os TextFields para se calcular o período.
		painelGridPeriodo = new JPanel(); painelGridPeriodo.setLayout(new GridLayout(4, 2));
		painelGridPeriodo.add(labelCapitalPeriodo); painelGridPeriodo.add(tfCapitalPeriodo);
		painelGridPeriodo.add(labelMontantePeriodo); painelGridPeriodo.add(tfMontantePeriodo);
		painelGridPeriodo.add(labelPercentualPeriodo); painelGridPeriodo.add(tfPercentualPeriodo);
		painelGridPeriodo.add(labelPeriodoPeriodo); painelGridPeriodo.add(tfPeriodoPeriodo);
		
		// painelPeriodo. Esse painel contém o painel gridPeriodo e o botão para se calcular o período.
		painelPeriodo = new JPanel(); painelPeriodo.setLayout(new BorderLayout());
		painelPeriodo.add("North", painelGridPeriodo);
		painelPeriodo.add("Center", botaoCalculaPeriodo);
		
		// painelGridCapital. Contém os Labels e os TextFields para se calcular o capital.
		// Esse painel será inserido no painelCapital a seguir.
		painelGridCapital = new JPanel(); painelGridCapital.setLayout(new GridLayout(4, 2));
		painelGridCapital.add(labelMontanteCapital); painelGridCapital.add(tfMontanteCapital);
		painelGridCapital.add(labelPercentualCapital); painelGridCapital.add(tfPercentualCapital);
		painelGridCapital.add(labelPeriodoCapital); painelGridCapital.add(tfPeriodoCapital);
		painelGridCapital.add(labelCapitalCapital); painelGridCapital.add(tfCapitalCapital);
		
		// painelCapital. Esse painel contém o painelGridCapital e o botão para se calcular o capital.
		painelCapital = new JPanel(); painelCapital.setLayout(new BorderLayout());
		painelCapital.add("North", painelGridCapital);
		painelCapital.add("Center", botaoCalculaCapital);
		
		
		// painelCard. Esse painel recebe os painéis painelMontante, painelCapital e painelPeriodo.
		painelCard = new JPanel(); painelCard.setLayout(new CardLayout());

		painelCard.add(painelMontante, "Montante");
		painelCard.add(painelCapital, "Capital");
		painelCard.add(painelPeriodo, "Periodo");
		
		// Insere no Frame o peinelSuperior e o painelCard. 
		getContentPane().add("North", painelSuperior);
		getContentPane().add("South", painelCard);
	}
	
	public void actionPerformed(ActionEvent e)
	{
		CardLayout card = (CardLayout) painelCard.getLayout();
		
		if(e.getSource() == botaoMontante)
			card.show(painelCard, "Montante");
		
		if(e.getSource() == botaoCapital)
			card.show(painelCard, "Capital");
		
		if(e.getSource() == botaoPeriodo)
			card.show(painelCard, "Periodo");
	}
}