web-dev-qa-db-fra.com

Java Swing - Comment afficher un panneau par-dessus un autre panneau?

Je souhaite avoir une boîte de dialogue interne (hors fenêtre) pour demander la contribution des membres. Je voudrais que le dialogue soit placé de manière centrale sur un JPanel existant.

J'ai examiné layeredpanes et ceux-ci semblent inutilisables car ils n'ont qu'un seul gestionnaire de disposition (ou aucun gestionnaire de disposition) dans tous les volets. Je suppose que je pourrais essayer de remplacer JLayeredPane et de fournir une mise en page personnalisée, mais cela semble extrême.

Les vitres ne semblent pas être appropriées non plus.

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

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

MODIFIER

La raison pour laquelle les volets superposés ne convenaient pas était due à l'absence d'un gestionnaire de disposition par couche. Le panneau est redimensionnable, le panneau A doit rester à 100% de la surface et le panneau B doit rester centralisé.

30
Pool

Je pense que LayeredPane est votre meilleur pari ici. Vous auriez cependant besoin d'un troisième panneau pour contenir A et B. Ce troisième panneau serait le layeredPane et les panneaux A et B pourraient toujours avoir un Nice LayoutManagers. Tout ce que vous auriez à faire est de centrer B sur A et il y a beaucoup d'exemples dans le sentier Swing sur la façon de le faire. 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 setBounds pour positionner les panneaux dans le volet superposé et également pour définir leurs tailles.

Modifier pour refléter les modifications apportées à la publication d'origine Vous devrez ajouter des écouteurs de composant qui détectent le redimensionnement du conteneur parent, puis modifier de manière dynamique les limites des panneaux A et B.

34

Je pensais juste que j'ajouterais qu'il y a est une notion d'ordre Z dans Swing, voir [Java.awt.Component # setComponentZOrder] [1]

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

Notez que vous devez remplacer javax.swing.JComponent # isOptimizedDrawingEnabled pour renvoyer false dans le conteneur parent afin que vos composants superposés soient correctement repeints, faute de quoi leurs repeints se gêneront mutuellement. (JComponents n'assume aucun chevauchement d'enfants sauf si isOptimizedDrawingEnabled renvoie false)

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

5
CarlG

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
mavroprovato

Utilisez un GridLayout 1 sur 1 sur le JPanel existant, puis ajoutez votre panneau à ce JPanel. Le seul problème avec un GridLayout qui est 1 par 1 est que vous ne pourrez pas placer d'autres éléments sur le JPanel. Dans ce cas, vous devrez trouver un agencement approprié. Chaque panneau que vous utilisez peut utiliser sa propre disposition pour éviter tout problème.

Est-ce que je comprends bien cette question?

1
AlbertoPL

Il y a un autre gestionnaire de disposition qui peut être intéressant ici: Superposition Layout Voici un tutoriel simple: OverlayLayout: pour la gestion de la disposition des composants superposés . La superposition Layout permet vous placez les panneaux les uns sur les autres et définissez 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, c'est parce que je suis tombé sur le même problème et que très peu de mentions ont été faites sur la disposition de superposition sur StackOverflow, bien qu'elle semble être assez bien documentée. autre qui continue à chercher.)

0
AgataB

JOptionPane.showInternalInputDialog fait probablement ce que vous voulez. Sinon, il serait utile de comprendre ce qui manque.

0
Yishai