2012-09-02 44 views
3

我可以在我的JDialog中添加一個圓角邊框,如How to create a rounded title border in Java Swing。但它仍然是一種顏色。我想讓邊框看起來像3D。如何爲帶有圓角的JDialog設置3D邊框?

以下是我的嘗試。

Graphics2D g2d = (Graphics2D) g; 
     Color c1 = getBackground(); 
     Color c2 = color1.darker(); 
     int w = getWidth(); 
     int h = getHeight(); 

     GradientPaint gp = new GradientPaint(
       0, 0, c1, 
       0, h, c2); 

     g2d.setPaint(gp); 
     g2d.fill3DRect(0,0, w, h,true); 

然後,沒有3D的外觀,但邊界已經擴大了更多的邊界顏色。
我該如何做到這一點?

任何示例代碼或鏈接將受到高度讚賞。

+0

您需要的顏色漸變影子 –

+0

是不是對你的時間[接受了一個答案](http://meta.stackexchange.com/a/65088/155831)這個問題? –

回答

5

這是否足夠?

enter image description here

它遠非完美,但其基本思想工作......

public class MyRoundedBorder implements Border { 

    protected static final Insets DEFAULT_INSETS = new Insets(4, 4, 4, 4); 

    @Override 
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 

     Graphics2D g2d = (Graphics2D) g.create(); 

     g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 
     g2d.setColor(Color.WHITE); 
     Shape corner = new RoundedShape(width - 8, height - 8); 
     g2d.translate(x + 2, y + 2); 
     g2d.draw(corner); 
     g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(180), (width - 8)/2, (height - 8)/2)); 
     g2d.setColor(Color.LIGHT_GRAY); 
     g2d.draw(corner); 

     g2d.dispose(); 

    } 

    @Override 
    public Insets getBorderInsets(Component c) { 

     return DEFAULT_INSETS; 

    } 

    @Override 
    public boolean isBorderOpaque() { 

     return true; 

    } 

    public class RoundedShape extends Path2D.Float { 

     public RoundedShape(int width, int height) { 

      moveTo(0, height - 20); 
      append(new Arc2D.Float(0, height - 20, 20, 20, 180, 45, Arc2D.CHORD), false); 
      lineTo(0, 20); 
      curveTo(0, 0, 0, 0, 20, 0); 
      lineTo(width - 10, 0); 
      append(new Arc2D.Float(width - 20, 0, 20, 20, 90, -45, Arc2D.CHORD), false); 

     } 

    } 

} 
+0

當!在16分鐘內擊敗我!我會看看我能否找到一個5個月大的孩子來打字,儘管我保持着自己的流口水。 ;) –

+0

@AndrewThompson和6個月沒有睡覺:P – MadProgrammer

6

3D Border

import java.awt.*; 
import java.awt.geom.*; 
import javax.swing.*; 
import javax.swing.border.*; 

public class ThreeDimensionalBorder extends AbstractBorder { 

    private static final long serialVersionUID = 1L; 
    private Color color; 
    private int thickness = 8; 
    private int radii = 8; 
    private Insets insets = null; 
    private BasicStroke stroke = null; 
    private int strokePad; 
    RenderingHints hints; 
    int shadowPad = 3; 

    ThreeDimensionalBorder(Color color) { 
     this(color, 128, 8); 
    } 

    ThreeDimensionalBorder(Color color, int transparency, int shadowWidth) { 
     this.color = color; 
     shadowPad = shadowWidth; 

     stroke = new BasicStroke(thickness); 
     strokePad = thickness/2; 

     hints = new RenderingHints(
       RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 

     int pad = radii + strokePad; 
     int bottomPad = pad + strokePad + shadowPad; 
     int rightPad = pad + strokePad + shadowPad; 
     insets = new Insets(pad,pad,bottomPad+shadowPad,rightPad); 
    } 

    @Override 
    public Insets getBorderInsets(Component c) { 
     return insets; 
    } 

    @Override 
    public Insets getBorderInsets(Component c, Insets insets) { 
     return getBorderInsets(c); 
    } 

    @Override 
    public void paintBorder(
      Component c, 
      Graphics g, 
      int x, int y, 
      int width, int height) { 

     Graphics2D g2 = (Graphics2D)g; 

     int bottomLineY = height-thickness-shadowPad; 

     RoundRectangle2D.Double bubble = new RoundRectangle2D.Double(
       0+strokePad, 
       0+strokePad, 
       width-thickness-shadowPad, 
       bottomLineY, 
       radii, 
       radii 
       ); 

     Area area = new Area(bubble); 

     g2.setRenderingHints(hints); 

     g2.setColor(color); 
     g2.setStroke(stroke); 
     g2.draw(area); 

     Area shadowArea = new Area(new Rectangle(0,0,width,height)); 
     shadowArea.subtract(area); 
     g.setClip(shadowArea); 
     Color shadow = new Color(color.getRed(),color.getGreen(),color.getBlue(),128); 
     g2.setColor(shadow); 
     g2.translate(shadowPad,shadowPad); 
     g2.draw(area); 
     AffineTransform at = g2.getTransform(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       JPanel p = new JPanel(); 
       String t = "The quick brown fox jumps over the lazy dog!"; 

       JLabel l1 = new JLabel(t); 
       l1.setBorder(new ThreeDimensionalBorder(Color.MAGENTA.darker(),128,4)); 
       p.add(l1); 

       JLabel l2 = new JLabel(t); 
       l2.setBorder(new ThreeDimensionalBorder(Color.BLACK,200,5)); 
       p.add(l2); 

       JLabel l3 = new JLabel(t); 
       l3.setBorder(new ThreeDimensionalBorder(Color.BLUE,40,6)); 
       p.add(l3); 

       JOptionPane.showMessageDialog(null, p); 
      } 
     }); 
    } 
} 
+0

+1不錯,可能要偷; – MadProgrammer

+0

@MadProgrammer我更喜歡3D邊框的視覺效果。 'ThreeDimensionalBorder'(可能更好的叫做'ShadowBorder')比較起來是粗獷和粗俗的。 –