Pergunta

Para colocá-lo simples, há um aplicativo Java Swing simples que consiste em JFrame com alguns componentes na mesma. Um dos componentes é um JPanel que se destina a ser substituído por outro JPanel na ação do usuário.

Então, qual é a maneira correta de fazer tal coisa um? Eu tentei

panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();

mas isso não vai funcionar. O que você sugere?

Foi útil?

Solução

O seu caso de uso, parece perfeito para CardLayout .

No layout do cartão você pode adicionar vários painéis no mesmo lugar, mas, em seguida, mostrar ou esconder, um painel de cada vez.

Outras dicas

1) Definir o primeiro painel:

JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());

2) Substituindo o painel:

frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());

Além disso, observe que você deve fazer isso no Tópico do evento, para garantir que esta utilização do SwingUtilities.invokeLater ou o SwingWorker

frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.

Lembre-se, o uso Java 'referência cópia por valor' passagem de argumento. Assim, alterando a variável não mudará cópias da referência passado para outros métodos.

Também nota JFrame é muito confuso em nome da usabilidade. Adicionando um componente ou definir um layout (geralmente) executa a operação no painel de conteúdo. Curiosamente, ficando o layout realmente dar-lhe gerenciador de layout do quadro.

Hope este pedaço de código lhe dar uma idéia de mudar JPanels dentro de um JFrame.

public class PanelTest extends JFrame {

        Container contentPane;

        public PanelTest()  {
           super("Changing JPanel inside a JFrame");
           contentPane=getContentPane();
        }

        public void createChangePanel() {
           contentPane.removeAll();
           JPanel newPanel=new JPanel();
           contentPane.add(newPanel);
           System.out.println("new panel created");//for debugging purposes
           validate();
           setVisible(true);
        }
}

Na ação do usuário:

// você tem que fazer algo ao longo das linhas de

myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()

myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()

Depois, você pode redimensionar a sua wndow conforme necessário.

Tudo depende de como a sua vai ser usado. Se você vai querer alternar entre estes dois painéis, em seguida, usar um CardLayout. Se você está apenas mudança da primeira para a segunda de uma vez (e não voltar), então eu usaria Telcontar sugestão s e apenas substituí-lo. Embora se o JPanel não é a única coisa em seu quadro que eu usaria (java .awt.Component) vez de removeAll.

Se você está em algum lugar entre esses dois casos é basicamente uma troca no tempo-espaço. O CardLayout vai lhe poupar tempo, mas ocupam mais memória por ter que manter todo este outro painel na memória em todos os momentos. Mas se você apenas substituir o painel quando necessário e construí-lo sob demanda, você não tem que manter isso em torno meory mas é preciso mais tempo para switch.

Além disso, você pode tentar um JTabbedPane de guias de uso em vez (o seu ainda mais fácil do que CardLayout porque ele lida com a exibição / escondendo automitically)

Os outros indivíduos responderam a pergunta. Quero sugerir que você use um JTabbedPane em vez de substituir o conteúdo. Como regra geral, é ruim ter elementos visuais de sua aplicação desaparecer ou ser substituído por outro conteúdo. Certamente existem exceções para cada regra, e só você e sua comunidade de usuários pode decidir a melhor abordagem.

Problema :. Meu componente não aparece depois de eu ter adicionado ao recipiente

Você precisa invocar revalidate e repaint depois de adicionar um componente antes que ele vai aparecer em seu recipiente.

Fonte: http://docs.oracle.com/javase/ tutorial / uiswing / layout / problems.html

Eu estava tendo exatamente o mesmo problema !! Increadible !! A solução que encontrei foi:

  1. A adição de todos os componentes (JPanels) para o recipiente;
  2. Usando o método setVisible (false) para todas elas;
  3. Na ação do usuário, estabelecendo setVisible (true) para o painel que eu queria show.
// Hiding all components (JPanels) added to a container (ex: another JPanel)
for (Component component : this.container.getComponents()) {
      component.setVisible(false);
}
// Showing only the selected JPanel, the one user wants to see
panel.setVisible(true);

No revalidate (), não validate (), não CardLayout necessário.

A resposta layout.replace () só existe / trabalha no GroupLayout Manager.

Outros LayoutManagers (CardLayout, BoxLayout etc) não suportam esse recurso, mas exigem que você primeiro RemoveLayoutComponent (e, em seguida, AddLayoutComponent (de volta novamente. :-) [Apenas definir o recorde reta]

Eu sugiro que você adicione ambos painel na criação de quadros, em seguida, mudar o painel visível chamando setVisible (true / false) em ambos. Ao chamar setVisible, o pai será notificado e convidado a redesenhar propriamente dito.

class Frame1 extends javax.swing.JFrame {

    remove(previouspanel); //or getContentPane().removeAll();

    add(newpanel); //or setContentPane(newpanel);

    invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate();

    repaint(); //DO NOT FORGET REPAINT

}

Às vezes você pode fazer o trabalho sem usar a revalidação e, por vezes, sem usar o uso repaint.My aconselhar ambos.

Apenas chamar o método pack () depois de definir o ContentPane, (java 1.7, talvez mais velhos) como este:

JFrame frame = new JFrame();  
JPanel panel1 = new JPanel(); 
JPanel panel2 = new JPanel(); 
....
frame.setContentPane(panel1);
frame.pack();
...

frame.setContentPane(panel2);
frame.pack();
...

Você pode usar o método de um layout substituir:

layout.replace(existingComponent, newComponent)

os JPanels existentes e novos componentes podem ser também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top