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)
вы можете добавить 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, в то время как он, кажется, довольно хорошо документирован. Надеюсь, это может помочь кому-то еще, кто продолжает искать его.)