2012-04-11 33 views

cevap

7

Orada birkaç seçenek vardır ve bunların her biri kendi artıları ve eksileri vardır ...

  1. özel şekilli bir pencere oluşturma - Bu yaklaşım ile bazı sistemler arkasında ek gölge oluşturmak mümkün olacak şekilli pencere, aynı zamanda bu sistemlerin çoğunda çalışır (linux JDK'larda bile çalışmalıdır). Bu yaklaşımla ilgili kötü olan şey (aslında onu kullanılamaz hale getirir), hizalanmamış şekil kenar çizgisidir - eğer elips biçimli bir pencere oluşturursanız, kenarları pürüzlü görünecektir.

  2. Çizilmiş şekli olmayan opak olmayan, kaplamasız bir pencere oluşturun - bu yaklaşım, (1) yaklaşımının temel sorununu çözecektir. Tamamen şeffaf bir pencerede çizdiğiniz şekli değiştirebilirsiniz. Bununla ilgili kötü olan şey sadece Win ve Mac sistemlerinde çalışabilmesi. Herhangi bir linux sisteminde (çoğunlukla), bir dikdörtgen elde edilen pencere ve desteklenmeyen işlemler ile ilgili hatalar göreceksiniz.

  3. Java penceresinin içine özel şekilli bir pencere açın ve pencere katmanına veya cam bölmelere yerleştirin. Bu, herhangi bir uyumluluk probleminden tam olarak kaçınmanıza ve (2) yaklaşımın faydalarından yararlanmanıza izin verecektir. Bu yaklaşımla ilgili kötü bir şey olsa da - bu tür pencereleri yalnızca pencere kök bölme sınırları içinde görüntüleyebilirsiniz. Bu durum, çoğu durumda iki farklı yoldan daha iyidir, çünkü daha az kaynak kullanır, ek pencereler oluşturmaz ve açılır pencerenin her parçasını kontrol edebilirsiniz. 3 yaklaşımın Hakkında

- bir gölge-efekti ile özel şekilli yarı saydam ipuçları görüntülemek için pencere camı bölmesini kullanır - Eğer ben kendi projesi WebLookAndFeel oluşturduğunuz TooltipManager kontrol edebilirsiniz. Ayrıca yakında "iç" pencere açılır pencereleri hızlı oluşturulmasını sağlayacak pencere PopupManager ekleyeceğim. İşte

yaklaşımların bazı örnekler:

şekil oluşturmak için

Yöntem örneklerin tümünde önde kullanılan kod Biraz:

private static Area createShape() 
{ 
    Area shape = new Area (new RoundRectangle2D.Double (0, 20, 500, 200, 20, 20)); 

    GeneralPath gp = new GeneralPath (GeneralPath.WIND_EVEN_ODD); 
    gp.moveTo (230, 20); 
    gp.lineTo (250, 0); 
    gp.lineTo (270, 20); 
    gp.closePath(); 
    shape.add (new Area (gp)); 

    return shape; 
} 

Fare adaptörü verir Bileşeni sürükleyerek pencereyi taşımak için:

public static class WindowMoveAdapter extends MouseAdapter 
{ 
    private boolean dragging = false; 
    private int prevX = -1; 
    private int prevY = -1; 

    public WindowMoveAdapter() 
    { 
     super(); 
    } 

    public void mousePressed (MouseEvent e) 
    { 
     if (SwingUtilities.isLeftMouseButton (e)) 
     { 
      dragging = true; 
     } 
     prevX = e.getXOnScreen(); 
     prevY = e.getYOnScreen(); 
    } 

    public void mouseDragged (MouseEvent e) 
    { 
     if (prevX != -1 && prevY != -1 && dragging) 
     { 
      Window w = SwingUtilities.getWindowAncestor (e.getComponent()); 
      if (w != null && w.isShowing()) 
      { 
       Rectangle rect = w.getBounds(); 
       w.setBounds (rect.x + (e.getXOnScreen() - prevX), 
         rect.y + (e.getYOnScreen() - prevY), rect.width, rect.height); 
      } 
     } 
     prevX = e.getXOnScreen(); 
     prevY = e.getYOnScreen(); 
    } 

    public void mouseReleased (MouseEvent e) 
    { 
     dragging = false; 
    } 
} 

1 yaklaşım örneği: -: Şimdi

public static void main (String[] args) 
{ 
    JFrame frame = new JFrame(); 
    frame.setUndecorated (true); 

    final Area shape = createShape(); 
    JPanel panel = new JPanel() 
    { 
     protected void paintComponent (Graphics g) 
     { 
      super.paintComponent (g); 

      Graphics2D g2d = (Graphics2D) g; 
      g2d.setRenderingHint (RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 

      g2d.setPaint (Color.BLACK); 
      g2d.fill (shape); 
     } 
    }; 
    panel.setOpaque (false); 
    WindowMoveAdapter wma = new WindowMoveAdapter(); 
    panel.addMouseListener (wma); 
    panel.addMouseMotionListener (wma); 
    frame.getContentPane().add (panel); 

    AWTUtilities.setWindowOpaque (frame, false); 
    frame.setSize (shape.getBounds().getSize()); 
    frame.setLocationRelativeTo (null); 

    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
    frame.setVisible (true); 
} 

public static void main (String[] args) 
{ 
    JFrame frame = new JFrame(); 
    frame.setUndecorated (true); 

    JPanel panel = new JPanel(); 
    panel.setBackground (Color.BLACK); 
    WindowMoveAdapter wma = new WindowMoveAdapter(); 
    panel.addMouseListener (wma); 
    panel.addMouseMotionListener (wma); 
    frame.getContentPane().add (panel); 

    Area shape = createShape(); 
    AWTUtilities.setWindowShape (frame, shape); 
    frame.setSize (shape.getBounds().getSize()); 
    frame.setLocationRelativeTo (null); 

    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
    frame.setVisible (true); 
} 

Gördüğünüz gibi yuvarlak şeklin köşeleri iyi görünümlü

2 yaklaşım oldukça kaba ve olmayan Mükemmel görünmelidir - tek sorun, bu sadece Windows ve Mac'de düzgün çalışacaktır (1.6.x JDK'da atleast). Son bir saat önce çeşitli işletim sistemlerinde kontrol ettiğimde yaklaşık bir ay oldu.

public static void main (String[] args) 
{ 
    JFrame frame = new JFrame(); 

    JPanel panel = new JPanel (new BorderLayout()); 
    panel.setOpaque (false); 
    WindowMoveAdapter wma = new WindowMoveAdapter(); 
    panel.addMouseListener (wma); 
    panel.addMouseMotionListener (wma); 
    frame.getContentPane().add (panel); 

    panel.add (new JButton ("Test")); 

    final Area shape = createShape(); 

    JPanel glassPane = new JPanel (null) 
    { 
     public boolean contains (int x, int y) 
     { 
      // This is to avoid cursor and mouse-events troubles 
      return shape.contains (x, y); 
     } 
    }; 
    glassPane.setOpaque (false); 
    frame.setGlassPane (glassPane); 
    glassPane.setVisible (true); 

    JComponent popup = new JComponent() 
    { 
     protected void paintComponent (Graphics g) 
     { 
      super.paintComponent (g); 

      Graphics2D g2d = (Graphics2D) g; 
      g2d.setRenderingHint (RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 

      g2d.setPaint (Color.BLACK); 
      g2d.fill (shape); 
     } 
    }; 
    popup.addMouseListener (new MouseAdapter() 
    { 
     // To block events on the popup 
    }); 
    glassPane.add (popup); 
    popup.setBounds (shape.getBounds()); 
    popup.setVisible (true); 

    frame.setSize (800, 500); 
    frame.setLocationRelativeTo (null); 

    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
    frame.setVisible (true); 
} 

Bu cam bölmeli yerleştirilen açılan basit bir örneğidir 3 yaklaşım. Gördüğünüz gibi sadece JFrame'in içinde var, ancak diğer tarafa sahip ve herhangi bir işletim sistemi üzerinde düzgün çalışıyor.

+0

çok iyi bir cevap 1 – mKorbel

+0

Ben zaten sorun fark ve metni değiştirdi yaklaşımlar –

+0

tümüne kod örnekleri eklemiş ama ipucu için teşekkürler :) –

İlgili konular