Java Swing - comment afficher un panneau sur un autre panneau?

je souhaite avoir une boîte de dialogue interne (non window) pour demander la contribution des membres. Je voudrais que le dialogue soit centralisé sur un JPanel existant.

j'ai regardé layeredpanes et ceux-ci semblent inutilisables en raison de n'avoir qu'un seul layout manager (ou pas layout manager) dans tous les volets. Je suppose que je pourrais essayer d'outrepasser JLayeredPane et fournir une mise en page personnalisée, mais cela semble extrême.

Verre ne semble pas être approprié soit.

Comment cela peut-il être fait? N'y a-t-il pas de concept utilisable de z-indexes dans Swing?

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

EDIT

la raison pour laquelle les panneaux multicouches n'étaient pas appropriés était due à l'absence d'un gestionnaire de mise en page par couche. Le panneau est redimensionnable, le Panneau A devrait rester à 100% de la surface et le panneau B devrait rester centralisé.

30
demandé sur Pool 2009-05-12 16:55:08

6 réponses

je pense que LayeredPane est votre meilleur pari ici. Vous auriez besoin d'un troisième panneau bien que pour contenir A et B. Ce troisième panneau serait le layeredPane et puis le panneau A et B pourrait encore avoir un bon LayoutManagers. Tout ce que vous auriez à faire est Centre B au-dessus de A et il ya beaucoup d'exemples dans le Swing trail sur la façon de faire cela. tutoriel pour le positionnement sans 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();
    }

}

vous utilisez des réglages pour positionner les panneaux à l'intérieur de la vitre stratifiée et aussi pour définir leurs tailles.

Modifier pour refléter les modifications apportées à l'original post Vous aurez besoin d'ajouter des écouteurs de composants qui détectent quand le conteneur parent est redimensionné et qui changent ensuite dynamiquement les limites du panneau A et B.

34
répondu willcodejavaforfood 2009-05-12 14:09:33

j'ai juste pensé que je voudrais ajouter qu'il y a une notion de Z-ordre dans le Swing, voir [Java.awt.Component#setComponentZOrder][1]

qui affecte les positions d'un composant dans son tableau de composants parents, qui détermine l'ordre de la peinture.

Notez que vous devez remplacer javax.swing.JComponent#isoptimized drawingenabled pour retourner false dans le conteneur parent pour obtenir vos composants se chevauchant à repeindre correctement, sinon leur repeint va tabasser les uns des autres. (JComponents suppose pas de chevauchement des enfants à moins que isOptimizedDrawingEnabled retourne false)

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

5
répondu CarlG 2009-05-13 16:15:13

Vous pouvez ajouter un JDialog non décoré comme ceci:

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);
  }
}
4
répondu mavroprovato 2009-05-12 14:11:46

utilisez un GridLayout 1 par 1 sur le JPanel existant, puis ajoutez votre panneau à ce JPanel. Le seul problème avec un GridLayout qui est de 1 par 1 est que vous ne serez pas en mesure de placer d'autres articles sur le JPanel. Dans ce cas, vous devrez trouver une mise en page appropriée. Chaque panneau que vous utilisez peut utiliser leur propre disposition de sorte que ce ne serait pas un problème.

ai-je bien compris cette question?

1
répondu AlbertoPL 2009-05-12 13:04:18

JOptionPane.showInternalInputDialog fait probablement ce que vous voulez. Si non, il serait utile de comprendre ce qu'il est manquant.

0
répondu Yishai 2009-05-12 13:16:31

Il y a un autre gestionnaire de mise en page qui peuvent être d'intérêt ici: Disposition De Superposition Voici un tutoriel simple: OverlayLayout: pour la mise en page de gestion de composants qui se trouvent sur le dessus de l'un à l'autre. La disposition de superposition vous permet de placer des panneaux les uns sur les autres, et de définir une disposition à l'intérieur de chaque panneau. Vous pouvez également définir la taille et la position de chaque panneau séparément.

(la raison pour laquelle je réponds à cette question d'il y a des années est que j'ai trébuché sur le même problème, et j'ai vu très peu de mentions de la disposition de superposition sur StackOverflow, alors qu'il semble être assez bien documenté. Espérons que cela puisse aider quelqu'un d'autre qui continue à le chercher.)

0
répondu AgataB 2016-07-21 08:40:32