Java Swing - как показать панель поверх другой панели? - PullRequest
30 голосов
/ 12 мая 2009

Я хотел бы иметь внутренний (не оконный) диалог, чтобы запросить ввод членов. Я хотел бы, чтобы диалог был размещен по центру на существующей JPanel.

Я посмотрел на слоистых панелей , и они кажутся непригодными из-за наличия только одного менеджера макета (или без менеджера макета) на всех панелях. Я думаю, я мог бы попытаться переопределить JLayeredPane и предоставить пользовательский макет, но это кажется чрезвычайным.

Стеклянные панели тоже не подходят.

Как это можно сделать? Нет ли в Swing полезной концепции z-индексов?

EDIT

Причина, по которой многослойные панели были неподходящими, была связана с отсутствием менеджера компоновки для каждого слоя. Размер панели можно изменять, панель А должна занимать 100% площади, а панель В. должна оставаться централизованной.

Ответы [ 6 ]

35 голосов
/ 12 мая 2009

Я думаю, LayeredPane - ваш лучший выбор здесь. Вам понадобится третья панель, хотя она будет содержать A и B. Эта третья панель будет слоистой панелью, а затем панель A и B все еще может иметь хорошие LayoutManager. Все, что вам нужно сделать, это центр B над A, и в следе Swing есть немало примеров, как это сделать. Учебник по позиционированию без 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();
    }

}

Вы используете setBounds для размещения панелей внутри многоуровневой панели, а также для установки их размеров.

Изменить, чтобы отразить изменения в исходном сообщении Вам нужно будет добавить компонентные прослушиватели, которые определяют, когда размер родительского контейнера изменяется, а затем динамически изменять границы панелей A и B.

5 голосов
/ 13 мая 2009

Я просто подумал, что добавлю, что - это понятие Z-порядка в Swing, см. [Java.awt.Component # setComponentZOrder] [1]

, который влияет на позиции компонента в массиве родительских компонентов, который определяет порядок рисования.

Обратите внимание, что вы должны переопределить javax.swing.JComponent # isOptimizedDrawingEnabled , чтобы возвратить false в родительском контейнере, чтобы заставить ваши перекрывающиеся компоненты перекрашиваться правильно, иначе их перерисовки будут перекрывать друг друга. (JComponents не предполагают перекрывающихся дочерних элементов, если isOptimizedDrawingEnabled не возвращает false)

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

4 голосов
/ 12 мая 2009

Вы можете добавить неокрашенный JDialog, например:

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);
  }
}
1 голос
/ 12 мая 2009

JOptionPane.showInternalInputDialog, вероятно, делает то, что вы хотите. Если нет, то было бы полезно понять, чего не хватает.

1 голос
/ 12 мая 2009

Используйте 1 к 1 GridLayout на существующей JPanel, затем добавьте свою панель к этой JPanel. Единственная проблема с GridLayout, который 1 к 1, состоит в том, что вы не сможете разместить другие элементы на JPanel. В этом случае вам нужно будет найти подходящий макет. Каждая панель, которую вы используете, может использовать свой собственный макет, чтобы не было проблем.

Правильно ли я понимаю этот вопрос?

0 голосов
/ 21 июля 2016

Здесь может быть интересен еще один менеджер раскладки: Оверлейная раскладка Вот простое руководство: OverlayLayout: для управления компоновкой компонентов, лежащих друг на друге . Макет наложения позволяет размещать панели друг над другом и устанавливать макет внутри каждой панели. Вы также можете установить размер и положение каждой панели отдельно.

(Причина, по которой я отвечаю на этот вопрос несколько лет назад, заключается в том, что я наткнулся на ту же проблему, и я видел очень мало упоминаний о Overlay Layout в StackOverflow, хотя, похоже, это довольно хорошо задокументировано. Надеюсь, это может помочь кому-то, кто продолжает его искать.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...