2012-01-03 66 views
4

是否可以为单个JFrame添加多个GlassPane,或者是否必须使用具有Opacity属性的令人不舒服的LayeredPane在根容器中分层多个GlassPane

我附上了一些代码,显示了我想要做的事情(由@camickr提供)。

import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.border.*; 

public class MultiplayGlassPane { 

    private static final long serialVersionUID = 1L; 
    private JFrame frame = new JFrame("frameTitle"); 
    private JPanel fPanel = new JPanel(); 
    private Random random = new Random(); 
    private final static Border MESSAGE_BORDER = new EmptyBorder(10, 10, 10, 10); 
    private JLabel message = new JLabel(); 
    private ArrayList<Star> stars = new ArrayList<Star>(); 

    public MultiplayGlassPane() { 

     MyGlassPane glass = new MyGlassPane(); 
     for (int i = 0; i < 35; i++) { 
      Star star = new Star(new Point(random.nextInt(580), random.nextInt(550))); 
      star.setColor(Color.orange); 
      star.setxIncr(-3 + random.nextInt(7)); 
      star.setyIncr(-3 + random.nextInt(7)); 
      glass.add(star); 
     } 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(glass, BorderLayout.CENTER); 
     frame.setLocation(20, 20); 
     frame.pack(); 
     frame.setVisible(true); 

     DisabledGlassPane1 glassPane = new DisabledGlassPane1(); 
     JRootPane rootPane = SwingUtilities.getRootPane(frame); 
     rootPane.setGlassPane(glassPane); 
     glassPane.activate(""); 
    } 

    private class MyGlassPane extends JLabel { 

     private static final long serialVersionUID = 1L; 
     private ArrayList<Star> stars = new ArrayList<Star>(); 
     private javax.swing.Timer timer = new javax.swing.Timer(20, new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Star star : stars) { 
        star.move(); 
       } 
       repaint(); 
      } 
     }); 

     public void stopAnimation() { 
      if (timer.isRunning()) { 
       timer.stop(); 
      } 
     } 

     public void startAnimation() { 
      if (!timer.isRunning()) { 
       timer.start(); 
      } 
     } 

     @Override 
     public void addNotify() { 
      super.addNotify(); 
      timer.start(); 
     } 

     @Override 
     public void removeNotify() { 
      super.removeNotify(); 
      timer.stop(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(new Dimension(620, 620)); 
     } 

     public MyGlassPane() { 
      this.setPreferredSize(new Dimension(620, 620)); 
     } 

     public void add(Star star) { 
      stars.add(star); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      for (Star star : stars) { 
       g.setColor(star.getColor()); 
       g.fillPolygon(star); 
      } 
     } 
    } 

    class DisabledGlassPane1 extends JComponent implements KeyListener { 

     private static final long serialVersionUID = 1L; 

     public DisabledGlassPane1() { 
      setOpaque(false); 
      Color base = UIManager.getColor("inactiveCaptionBorder"); 
      Color background = new Color(base.getRed(), base.getGreen(), base.getBlue(), 128); 
      setBackground(background); 
      setLayout(new GridBagLayout()); 
      add(message, new GridBagConstraints()); 
      message.setOpaque(true); 
      message.setBorder(MESSAGE_BORDER); 
      addMouseListener(new MouseAdapter() { 
      }); 
      addMouseMotionListener(new MouseMotionAdapter() { 
      }); 
      addKeyListener(this); 
      setFocusTraversalKeysEnabled(false); 
      Random random = new Random(); 
      for (int i = 0; i < 50; i++) { 
       Star star = new Star(new Point(random.nextInt(490), random.nextInt(490))); 
       star.setColor(Color.magenta); 
       star.setxIncr(-3 + random.nextInt(7)); 
       star.setyIncr(-3 + random.nextInt(7)); 
       add(star); 
      } 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      for (Star star : stars) { 
       g.setColor(star.getColor()); 
       g.fillPolygon(star); 
      } 
     } 

     @Override 
     public void setBackground(Color background) { 
      super.setBackground(background); 
      Color messageBackground = new Color(background.getRGB()); 
      message.setBackground(messageBackground); 
     } 

     public void keyPressed(KeyEvent e) { 
      e.consume(); 
     } 

     public void keyTyped(KeyEvent e) { 
     } 

     public void keyReleased(KeyEvent e) { 
      e.consume(); 
     } 

     public void activate(String text) { 
      if (text != null && text.length() > 0) { 
       message.setVisible(true); 
       message.setText(text); 
       message.setForeground(getForeground()); 
      } else { 
       message.setVisible(false); 
      } 
      setVisible(true); 
      //setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 
      requestFocusInWindow(); 
     } 

     public void deactivate() { 
      setCursor(null); 
      setVisible(false); 
     } 
     private javax.swing.Timer timer = new javax.swing.Timer(15, new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Star star : stars) { 
        star.move(); 
       } 
       repaint(); 
      } 
     }); 

     public void stopAnimation() { 
      if (timer.isRunning()) { 
       timer.stop(); 
      } 
     } 

     public void startAnimation() { 
      if (!timer.isRunning()) { 
       timer.start(); 
      } 
     } 

     @Override 
     public void addNotify() { 
      super.addNotify(); 
      timer.start(); 
     } 

     @Override 
     public void removeNotify() { 
      super.removeNotify(); 
      timer.stop(); 
     } 

     public void add(Star star) { 
      stars.add(star); 
     } 
    } 

    private class Star extends Polygon { 

     private static final long serialVersionUID = 1L; 
     private Point location = null; 
     private Color color = Color.YELLOW; 
     private int xIncr, yIncr; 
     static final int WIDTH = 600, HEIGHT = 600; 

     Star(Point location) { 
      int x = location.x; 
      int y = location.y; 
      this.location = location; 
      this.addPoint(x, y + 8); 
      this.addPoint(x + 8, y + 8); 
      this.addPoint(x + 11, y); 
      this.addPoint(x + 14, y + 8); 
      this.addPoint(x + 22, y + 8); 
      this.addPoint(x + 17, y + 12); 
      this.addPoint(x + 21, y + 20); 
      this.addPoint(x + 11, y + 14); 
      this.addPoint(x + 3, y + 20); 
      this.addPoint(x + 6, y + 12); 
     } 

     public void setColor(Color color) { 
      this.color = color; 
     } 

     public void move() { 
      if (location.x < 0 || location.x > frame.getContentPane().getWidth() - 20) { 
       xIncr = -xIncr; 
      } 
      if (location.y < 0 || location.y > frame.getContentPane().getHeight() - 20) { 
       yIncr = -yIncr; 
      } 
      translate(xIncr, yIncr); 
      location.setLocation(location.x + xIncr, location.y + yIncr); 
     } 

     public void setxIncr(int xIncr) { 
      this.xIncr = xIncr; 
     } 

     public void setyIncr(int yIncr) { 
      this.yIncr = yIncr; 
     } 

     public Color getColor() { 
      return color; 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       MultiplayGlassPane Mpgp = new MultiplayGlassPane(); 
      } 
     }); 
    } 
} 
+0

我不知道“Multiplaying”是什么。你能解释一下吗? – parasietje 2012-01-13 16:23:04

+0

@parasietje为一个JFrame创建&声明并添加两个或更多GlassPanes,默认情况下,JFrame只有一个GlassPane/RootPane – mKorbel 2012-01-13 16:24:33

+0

@Down_Voter可以请您分享原因吗? – mKorbel 2012-01-13 16:31:05

回答

1

请参阅http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html以获取关于根窗格的解释以及玻璃窗格的实际内容。

玻璃窗格只是添加一个具有根窗格大小并阻止所有输入事件的组件的便捷方式。这使您可以捕捉与组件的任何交互,以创建“请稍候...”屏幕。

每个根容器只有一个玻璃板。 无法层叠玻璃窗格

如果您想在当前玻璃窗格上分层,您可以用其他方法替换玻璃窗格的内容。您还可以将JPanel设置为玻璃窗格,这允许您在玻璃窗格中布置多个组件。

通常,您应该只使用玻璃窗格来阻止用户输入(并在必要时显示某种“请稍候”的信息)。你能提供一个用例来说明为什么你想把玻璃窗格放在另一个玻璃窗格上吗?

+0

'为什么你想把玻璃窗格放在另一个上面'为了在三层或更多层上绘制模糊的透明阴影以获得更好的3D效果,我不同意你的GlassPane的概念,但是+1 – mKorbel 2012-01-13 18:44:38

+0

我想你是在例子中被术语弄糊涂了。 “MyGlassPane”根本不是一个玻璃窗格,它只是一个JComponent。您应该将其重命名为“StarPanel”。它被添加到JFrame容器中。作为旁注,使用JFrame.add()是非法的,您应该使用frame.getContentPane()。add()将MyGlassPane添加到根容器中。 – parasietje 2012-01-16 10:48:24

+0

您的示例只是一个绘制漂亮星星的JComponent和一个禁用单击面板的GlassPane的组合。如果您想将JComponents层叠在一起,那么您应该确实使用LayeredPane(http://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html) – parasietje 2012-01-16 10:49:23