java – 使用BorderLayout在JPanel上方浮动JPanel
我有一个名为pnlMain的JPanel,其布局设置为BorderLayout.在面板内部有三个JPanel添加到PAGE_START,CENTER和PAGE_END.现在,我的要求是如果单击“设置”按钮,它将在pnlMain上方显示透明的JPanel.然后,这个透明面板将包含一个不透明,较小的居中面板,它将包含设置内容.
我知道我可以使用JLayeredPane来做到这一点,但是看看tutorial它说你只能使用绝对定位放置不同深度的组件,我知道这是非常气馁的. 如果不使用绝对定位,还有其他方法吗? 解决方法
您可以使用父框架的玻璃窗格,这将允许您向其添加看似覆盖在主要内容上的组件.
基本上,我会创建一个JPanel并将其设置为透明(setOpaque(false)).我会将它的布局管理器设置为GridBagLayout(因为它将使用子组件的首选大小并将其自动居中在其父容器中). 在这个面板上,我将添加“设置”面板. 最后,我将父框架的玻璃窗格设置为第一个(支持)窗格并使其可见. frame.getRootPane().setGlassPane(backingPane); // Or similar 看看How to use Root Panes 更新 如果您不能自己使用顶层框架的玻璃窗格,那么您需要伪造它. 此示例基本上使用由GridBagLayout支持的JLayeredPane 如果将MouseListener和KeyListener添加到背景窗格,则可以使用转发到子组件的事件. import java.awt.BorderLayout; import java.awt.Color; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.EmptyBorder; public class FloatingPane { public static void main(String[] args) { new FloatingPane(); } public FloatingPane() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } final WorkPane workPane = new WorkPane(); JButton settings = new JButton("Settings"); settings.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { workPane.toggleSettings(); } }); JFrame frame = new JFrame("Testing"); frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(workPane); frame.add(settings,BorderLayout.SOUTH); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class WorkPane extends JLayeredPane { private final BackingPane backingPane; public WorkPane() { setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 1; gbc.weighty = 1; gbc.fill = GridBagConstraints.BOTH; add(createLabel("Center",Color.BLUE),gbc); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0; gbc.weighty = 0; gbc.fill = GridBagConstraints.VERTICAL; add(createLabel("Left",Color.RED),gbc); gbc.gridx = 2; add(createLabel("Right",Color.GREEN),gbc); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 1; gbc.weighty = 1; gbc.gridheight = GridBagConstraints.REMAINDER; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.BOTH; backingPane = new BackingPane(); backingPane.add(new SettingsPane()); backingPane.setVisible(false); add(backingPane,gbc); setLayer(backingPane,DEFAULT_LAYER + 1); } public void toggleSettings() { backingPane.setVisible(!backingPane.isVisible()); } protected JLabel createLabel(String text,Color bg) { JLabel label = new JLabel(text); label.setHorizontalAlignment(JLabel.CENTER); label.setOpaque(true); label.setBackground(bg); return label; } } public class BackingPane extends JPanel { public BackingPane() { setLayout(new GridBagLayout()); setOpaque(false); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(new Color(128,128,192)); g.fillRect(0,getWidth(),getHeight()); } } public class SettingsPane extends JPanel { public SettingsPane() { setBorder(new EmptyBorder(10,10,10)); add(new JLabel("Settings")); } } } 另一个解决方案可能是通过拍摄当前面板的快照并使用CardLayout伪装整个玻璃窗格,翻转到设置窗格,使用快照拍摄作为设置窗格的背景图像(然后可以将效果应用于喜欢灰色缩放和模糊) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |