Java Swing-как Показать панель поверх другой панели?

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

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

стекла кажется, нет и уместно.

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

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

редактировать

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

6 ответов


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


Я просто подумал, что я бы добавил, что там is понятие Z-порядка в Swing, см. [ява.ОУ.Компонент#setComponentZOrder][1]

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

обратите внимание, что вы должны переопределить javax.качать.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)


вы можете добавить undecorated 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 на 1 GridLayout на существующей JPanel, затем добавьте свою панель в эту JPanel. Единственная проблема с GridLayout, который 1 на 1, заключается в том, что вы не сможете разместить другие элементы на JPanel. В этом случае вам придется придумать подходящий макет. Каждая панель, которую вы используете, может использовать свой собственный макет, чтобы это не было проблемой.

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


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


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

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