2009-05-12 20 views
30

Deseo tener un diálogo interno (sin ventana) para solicitar la entrada de miembro. Me gustaría que el diálogo se coloque centralmente en un JPanel existente.Java Swing: ¿cómo mostrar un panel en la parte superior de otro panel?

He visto layeredpanes y estos parecen inutilizables debido a que solo tienen un único administrador de diseño (o ningún administrador de diseño) en todos los paneles. Supongo que podría intentar anular JLayeredPane y proporcionar un diseño personalizado, pero esto parece extremo.

Glass panes no parecen ser apropiadas.

¿Cómo se puede hacer esto? ¿No hay un concepto utilizable de z-indexes en Swing?

http://i42.tinypic.com/30tkuvk.jpg

EDITAR

La razón LayeredPane no eran apropiados se debió a la falta de un controlador de disposición por capa. El panel puede redimensionarse, el Panel A debe permanecer al 100% del área y el Panel B debe permanecer centralizado.

+0

Vea, como una opción, cómo (muy simple) extender JLayeredPane para aceptar cualquier tipo de LayouManager. http://stackoverflow.com/questions/42413590/jlayeredpane-and-gridbagconstraints – Mischa

Respuesta

34

Creo que LayeredPane es su mejor apuesta aquí. Sin embargo, necesitaría un tercer panel para contener A y B. Este tercer panel sería el Panel estratificado y, a continuación, los paneles A y B aún podrían tener un bonito LayoutManagers. Todo lo que tendrías que hacer es centrar B sobre A y hay bastantes ejemplos en el sendero Swing sobre cómo hacer esto. Tutorial for positioning without a 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(); 
    } 

} 

Utiliza setBounds para colocar los paneles dentro del panel de capas y también para establecer sus tamaños.

Edición para reflejar los cambios en post original Usted tendrá que añadir detectores de componentes que detectan cuando el contenedor primario se está cambiando el tamaño y luego cambiar dinámicamente los límites del panel A y B.

+0

Hola, esta es la avenida que inicialmente estaba buscando, pero no puedo entender cómo hacer que A y B se comporten sin usar setBounds. Los documentos para JLayeredPane mencionan "Todos los administradores de disposición proporcionados por la plataforma Java organizan los componentes como si estuvieran en una sola capa". – Pool

+0

Sí, eso es correcto. Para posicionar A y B necesitas usar setBounds. Los paneles A y B aún pueden tener el LayoutManager en el que desee colocar los componentes dentro de ellos. Eso responde tu pregunta? – willcodejavaforfood

+1

La razón por la que estaba tratando de usar un administrador de diseño sobre setBounds es que se puede cambiar el tamaño del panel. Posiblemente extender JLayeredPane, escuchar los cambios de componentes y llamar a setBounds en sus hijos es una forma correcta de resolver esto. (Voy a editar la pregunta original para aclarar esto también.) – Pool

1

Usa un GridLayout 1 por 1 en el JPanel existente, luego agrega tu Panel a ese JPanel. El único problema con un GridLayout que es 1 por 1 es que no podrá colocar otros elementos en el JPanel. En este caso, tendrá que descubrir un diseño que sea adecuado. Cada panel que use puede usar su propio diseño para que no sea un problema.

¿Estoy entendiendo esta pregunta correctamente?

+0

Gracias, he agregado un diagrama de arriba para aclarar. Básicamente es colocar los componentes uno encima del otro (índice z) de lo que no estoy seguro. – Pool

+0

Oh ok Ya veo, mi error. Gracias por la aclaración adicional. – AlbertoPL

0

JOptionPane.showInternalInputDialog probablemente haga lo que quiera. De lo contrario, sería útil comprender lo que falta.

+0

Gracias, como lo entiendo esto mostraría un Marco interno que tendría una apariencia de ventana. Realmente necesito la personalización completa que un panel ofrecería. – Pool

4

Se puede añadir una sin decorar JDialog así:

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); 
    } 
} 
+0

Gracias, desafortunadamente esto crea una nueva ventana, +1 para sin embargo, muy buen efecto. – Pool

+0

¿Y por qué esto es un problema? Ahora que veo tu pregunta por segunda vez, es posible que desees que el diálogo no sea modal y lo reposicione cuando se cambia el tamaño del cuadro principal. – mavroprovato

+0

Es un requisito. Un diálogo/ventana no tendría sentido para este panel. – Pool

5

sólo pensé que me gustaría añadir que hay es una noción de orden Z en swing, veo [java.awt.Component # setComponentZOrder] [1]

que afecta las posiciones de un componente en la matriz de componentes principales, que determina el orden de la pintura.

Tenga en cuenta que debe anular javax.swing.JComponent#isOptimizedDrawingEnabled para devolver falso en el contenedor primario para obtener que los componentes superpuestos se vuelvan a pintar correctamente, de lo contrario sus repintados se golpearán entre sí.(JComponents suponen ningún niño se superponen a menos isOptimizedDrawingEnabled devuelve false)

[1]: http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Container.html#setComponentZOrder(java.awt.Component, int)

0

Hay otro controlador de distribución que pueda ser de interés aquí: Overlay Layout Aquí hay una explicación sencilla: OverlayLayout: for layout management of components that lie on top of one another. Diseño superpuesto le permite colocar paneles uno sobre otro y establecer un diseño dentro de cada panel. También puede configurar el tamaño y la posición de cada panel por separado.

(La razón por la que voy a responder a esta pregunta desde hace años es porque me he topado con el mismo problema, y ​​he visto muy pocas menciones de la Disposición de superposición en StackOverflow, si bien parece estar bastante bien documentado. Con suerte esto puede ayudar a alguien más que lo sigue buscando.)

Cuestiones relacionadas