【问题标题】:Using a GlassPane in a JPanel在 JPanel 中使用 GlassPane
【发布时间】:2015-05-22 14:51:55
【问题描述】:

我想在加载数据期间使用 glassPane 函数停用面板中的组件。我知道玻璃板只能在框架中使用。在我的应用程序中,我无法访问框架。我只想停用框架中的单个面板。

我试图通过覆盖面板的 paint 或 paintComponent 方法在面板上绘制一个 ractangle。问题是底层组件仍然可用。

谁能给我一个建议,我该如何解决这个问题?

问候

dbausnnd

【问题讨论】:

  • 一种可能性:使用 JLayeredPane,从而创建您自己的 glasspane。另一个——递归禁用 JPanel 持有的所有组件。

标签: java swing events


【解决方案1】:

在我的应用程序中,我无法访问框架。我只想停用框架中的单个面板。

您可以随时使用:

Window frame = SwingUtilities.windowForComponent(...);

我只想停用框架中的单个面板。

或者您可以尝试使用Disabled Panel。它允许您简单地禁用特定面板上的组件。

第二种绘制禁用外观的方法可能会出现问题,因为您在创建 GUI 时需要使用禁用面板。

【讨论】:

    【解决方案2】:

    一种可能性 - 使用 JLayeredPane 包裹 JPanel,然后激活位于其上方的 JPanel 层,让它窃取焦点和 MouseListener。例如:

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    import java.awt.event.MouseAdapter;
    
    import javax.swing.*;
    
    public class MyGlassPaneWrapper extends JLayeredPane {
       private JPanel glassPanel = new JPanel();
    
       public MyGlassPaneWrapper(JComponent myPanel) {
          glassPanel.setOpaque(false);
          glassPanel.setVisible(false);
          glassPanel.addMouseListener(new MouseAdapter() {});
          glassPanel.setFocusable(true);
    
          myPanel.setSize(myPanel.getPreferredSize());
          add(myPanel, JLayeredPane.DEFAULT_LAYER);
          add(glassPanel, JLayeredPane.PALETTE_LAYER);
    
          glassPanel.setPreferredSize(myPanel.getPreferredSize());
          glassPanel.setSize(myPanel.getPreferredSize());
          setPreferredSize(myPanel.getPreferredSize());
       }
    
       public void activateGlassPane(boolean activate) {
          glassPanel.setVisible(activate);
          if (activate) {
             glassPanel.requestFocusInWindow();
             glassPanel.setFocusTraversalKeysEnabled(false);
          } 
       }
    
       private static void createAndShowGui() {
          final MyPanel myPanel = new MyPanel();
          final MyGlassPaneWrapper myGlassPaneWrapper = new MyGlassPaneWrapper(myPanel);
          final String activateGlassPane = "Activate GlassPane";
          final String deactivateGlassPane = "Deactivate GlassPane";
    
          JToggleButton toggleButton = new JToggleButton(activateGlassPane);
          toggleButton.addItemListener(new ItemListener() {
    
             @Override
             public void itemStateChanged(ItemEvent e) {
                AbstractButton source = (AbstractButton) e.getSource();
                if (e.getStateChange() == ItemEvent.SELECTED) {
                   source.setText(deactivateGlassPane);
                   myGlassPaneWrapper.activateGlassPane(true);
                } else {
                   source.setText(activateGlassPane);
                   myGlassPaneWrapper.activateGlassPane(false);
                }
             }
          });
          JPanel buttonPanel = new JPanel();
          buttonPanel.add(toggleButton);
    
          JFrame frame = new JFrame("MyGlassPane");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().add(myGlassPaneWrapper);
          frame.getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    
    class MyPanel extends JPanel {
    
       public MyPanel() {
          add(new JTextField(5));
          add(new JComboBox<String>(new String[]{"Monday", "Tuesday", "Wednesday"}));
          add(new JButton(new AbstractAction("Push Me") {
    
             @Override
             public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(MyPanel.this, "Button Pushed");
             }
          }));
       }
    }
    

    【讨论】:

    • 1+,用户可以使用Tab键重新获得焦点。您可以通过添加来防止这种情况:glassPanel.setFocusTraversalKeysEnabled(false);
    • @camickr:谢谢——做出了改变!我已经把你的好答案提高了 1 倍,但似乎 OP 还没有。
    【解决方案3】:

    可以通过将玻璃窗格包装在JRootPane 的内容窗格中来将玻璃窗格添加到JPanel。然后,您可以使用半透明玻璃窗格捕获鼠标和键盘事件以在数据加载期间停用它,请参阅https://tips4java.wordpress.com/2008/11/07/disabled-glass-pane/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-01
      • 2021-03-30
      • 2011-08-07
      • 2012-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多