Java Swing - como mostrar um painel em cima de outro painel?
Pergunta
eu gostaria de ter um diálogo interno (não janela) para pedir a entrada membro. Gostaria de diálogo para ser colocado centralmente em um JPanel existente.
Eu olhei layeredpanes e estes parecem devido inutilizável para ter apenas um gerente único layout (ou nenhum gerenciador de layout) em todos os painéis. Eu acho que eu poderia tentar substituir JLayeredPane e fornecer um layout personalizado, mas isso parece extremo.
painéis de vidro não parecem ser apropriado qualquer um.
Como isso pode ser feito? Será que não há conceito de utilização de z-índices em Swing?
Editar
A razão Layered Panes não eram apropriados foi devido à falta de um gerenciador de layout por camada. O painel é redimensionável, painel A deve ficar em 100% da área e Painel B deve ficar centralizado.
Solução
Eu acho LayeredPane é sua melhor aposta aqui. Você precisaria de um terceiro painel embora para conter A e B. Este terceiro painel seria o layeredPane e, em seguida, o painel A e B ainda pode ter um bom LayoutManagers. Tudo que você tem a fazer é o centro B sobre A e há um monte de exemplos na trilha balanço sobre como fazer isso. Tutorial para posicionar sem LayoutManager .
public class Main {
private JFrame frame = new JFrame();
private JLayeredPane lpane = new JLayeredPane();
private JPanel panelBlue = new JPanel();
private JPanel panelGreen = new JPanel();
public Main()
{
frame.setPreferredSize(new Dimension(600, 400));
frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
lpane.setBounds(0, 0, 600, 400);
panelBlue.setBackground(Color.BLUE);
panelBlue.setBounds(0, 0, 600, 400);
panelBlue.setOpaque(true);
panelGreen.setBackground(Color.GREEN);
panelGreen.setBounds(200, 100, 100, 100);
panelGreen.setOpaque(true);
lpane.add(panelBlue, new Integer(0), 0);
lpane.add(panelGreen, new Integer(1), 0);
frame.pack();
frame.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main();
}
}
Você usa setBounds para posicionar os painéis dentro do painel em camadas e também para definir seus tamanhos.
Editar para refletir as mudanças post original Você vai precisar adicionar ouvintes de componentes que detectam quando o recipiente pai está sendo redimensionada e, em seguida, alterar dinamicamente os limites do painel A e B.
Outras dicas
Eu apenas pensei que eu gostaria de acrescentar que há é a noção de ordem Z em Swing, consulte [Java.awt.Component # setComponentZOrder] [1]
que afeta as posições de um componente em seus pais variedade de componentes, que determina a ordem pintura.
Note que você deve substituir javax.swing.JComponent # isOptimizedDrawingEnabled para false retorno no recipiente pai para obter seus componentes sobrepostos para repintar corretamente, caso contrário seus repaints vai espancar uns aos outros. (JComponents não assumem sobreposição crianças a menos isOptimizedDrawingEnabled retorna false)
[1]: http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Container.html#setComponentZOrder (java.awt.Component , int)
Você pode adicionar um JDialog undecorated assim:
import java.awt.event.*;
import javax.swing.*;
public class TestSwing {
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame("Parent");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setVisible(true);
final JDialog dialog = new JDialog(frame, "Child", true);
dialog.setSize(300, 200);
dialog.setLocationRelativeTo(frame);
JButton button = new JButton("Button");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
dialog.add(button);
dialog.setUndecorated(true);
dialog.setVisible(true);
}
}
Use a 1 por 1 GridLayout no JPanel existente, em seguida, adicione o seu Painel para que JPanel. O único problema com um GridLayout que é 1 por 1 é que você não será capaz de colocar outros itens no JPanel. Neste caso, você terá que descobrir um layout que é adequado. Cada painel que você usa pode usar seu próprio layout para que não seria um problema.
Am I compreender esta pergunta corretamente?
JOptionPane.showInternalInputDialog provavelmente faz o que quiser. Se não, seria útil para entender o que está faltando.
Há um outro gerenciador de layout que podem ser de interesse aqui: Overlay layout Aqui está um tutorial simples: OverlayLayout: para gerenciamento de layout de componentes que se encontram em cima um do outro . Overlay layout permite painéis de posição no topo de um outro, e definir um layout dentro de cada painel. Você também são capazes de tamanho e posição de cada painel separadamente set.
(A razão que eu estou respondendo a esta pergunta de anos atrás é porque me deparei com o mesmo problema, e tenho visto muito poucas menções à disposição Overlay em StackOverflow, enquanto ele parece estar muito bem documentado. Esperemos que este pode ajudar alguém que continua a procurá-lo.)