在Java中,Gradient color 有LinearGradientPaint 和 RadialGradientPaint可以直接使用,但是现在如果要
在这个黑色区域画出渐变颜色,比如颜色就是从里面的圆角矩形边框以黑色开始渐变到外面的圆角矩形边框到白色。求高手解答!!!

解决方案 »

  1.   

    java图形界面的功能真的是很弱的。
    重写绘图的方法应该可以实现。
    不过感觉挺麻烦的,直接弄一个现成的图片(ps生成)贴上多省事。
      

  2.   

    我就是想怎么用重写绘图的方法实现。直接贴图片的话,Component大小改变时容易失真啊
      

  3.   

    能说具体点吗。 JavaSE中没有找到像JavaFX中的BlendMode,能说说怎么用多个图形组合吗?其实我觉得本质还是继承Paint,自己写一个GradientPaint出来,可以参照下LinearGradientPaint 和 RadialGradientPaint是怎么写的。。但是研究了下不怎么懂怎么实现Paint接口。。
      

  4.   

    网上的例子 http://www.java3z.com/cwbwebhome/article/article5a/588.html
      

  5.   


    这个没做过
    可以查看一下:
    Stroke 接口的 Shape createStrokedShape(Shape s) 方法
    Graphics2D 的clipe(Shape s) 方法然后参考用 GradientPaint 实现
      

  6.   

    你是想绘制阴影效果么?阴影效果一般用模糊实现,不用渐变,因为渐变太“清晰”了如果是要为某个Component实现某种border效果,可以查看一下 javax.swing.border.Border 接口
      

  7.   

    另外我参看了一下 javax.swing.border.Border 接口,发现如果是非JPanel以外的JComponent想要设置Border的话,一般把它放到Jpanel中,然后设置JPanel的border。Border的各种样式中我没有发现可以达到模糊边框或者渐变边框的效果啊
      

  8.   


    试了一下,可以为“透明”控件加“投影”的border
      

  9.   

    Border的实现代码,使用了第三方jar来绘制高斯模糊http://www.jhlabs.com/ip/blurring.htmlimport com.jhlabs.image.GaussianFilter;
    import java.awt.AlphaComposite;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Insets;
    import java.awt.Rectangle;
    import java.awt.geom.Area;
    import java.awt.image.BufferedImage;
    import javax.swing.border.Border;/**
     *
     * @date   08/11/2012
     */
    public class ShadowBorder implements Border {
      
      private static final Color SHADOW_COLOR = Color.BLACK;
      private static final float SHADOW_ALPHA = 0.5f;
      
      private int size;
      public ShadowBorder(int size) {
        
        if( size < 0 )
          throw new IllegalArgumentException();
        
        this.size = size;
      }
      
      @Override
      public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        
        int widthFix = width - (size * 2);
        int heightFix = height - (size * 2);
        
        BufferedImage shadow = new BufferedImage(
                size * 2 + width, 
                size * 2 + height, 
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D imgGraphics = shadow.createGraphics();
        imgGraphics.setColor(SHADOW_COLOR);
        
        imgGraphics.fillRect(size, size, widthFix, heightFix);
        
        imgGraphics.setComposite(AlphaComposite.getInstance(
                AlphaComposite.SRC_IN, SHADOW_ALPHA));
        imgGraphics.fillRect(0, 0, shadow.getWidth(), shadow.getHeight());
        imgGraphics.dispose();
        
        GaussianFilter filter = new GaussianFilter(size * 2);
        shadow = filter.filter(shadow, null);
        
        Area shadowArea = new Area(new Rectangle(0, 0, width, height));
        shadowArea.subtract(new Area(new Rectangle(0, 0, widthFix, heightFix)));
        
        @SuppressWarnings("unchecked")
        Graphics2D gg = (Graphics2D)g.create();
        gg.setClip(shadowArea);
        gg.drawImage(shadow, 0, 0, c);
        gg.dispose();
      }  @Override
      public Insets getBorderInsets(Component c) {
        
        return new Insets(0, 0, size * 2, size * 2);
      }  @Override
      public boolean isBorderOpaque() {
        
        return false;
      }
    }
      

  10.   

    截图用的测试代码
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Insets;
    import javax.swing.BorderFactory;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;/**
     *
     * @date   08/11/2012
     */
    public class TestShadowBorder extends JPanel {
      
      public static void main(String[] args) {
        
        SwingUtilities.invokeLater(new Runnable() {      @Override
          public void run() {
            
            JFrame f = new JFrame("Test Shadow Border");
            f.getContentPane().add(new TestShadowBorder(), BorderLayout.CENTER);
            f.pack();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLocationRelativeTo(null);
            f.setVisible(true);
          }
        });
      }
      
      TestShadowBorder() {
        
        super(new FlowLayout(FlowLayout.CENTER, 20, 20));
        
        JPanel inner = new JPanel() {
          
          @Override
          protected void paintComponent(Graphics g) {
            
            Insets in = getInsets();
            
            @SuppressWarnings("unchecked")
            Graphics2D gg = (Graphics2D)g.create();
            gg.setBackground(getBackground());
            gg.clearRect(in.left, in.top, getWidth()-in.left-in.right, getHeight()-in.top-in.bottom);
          }
        };
        inner.setOpaque(false); // hack
        inner.setBackground(Color.GREEN.darker());
        inner.setBorder(BorderFactory.createCompoundBorder(
                
                new ShadowBorder(3),
                BorderFactory.createLineBorder(inner.getBackground().darker())
        ));
        inner.setPreferredSize(new Dimension(300, 200));
        
        add(inner);
      }
    }
      

  11.   


    谢谢!! 你的 答复很好的实现了模糊效果在边框上应用。呵呵。但是还是回到Java绘制渐变颜色的问题上,在 gradient paint上,Java只提供了LinearGradientPaint和RadialGradientPaint,我们现在想实现一个比如EllipseGradientPaint或者RectangleGradientPaint又该如何实现呢?谢谢讨论 Thanks
      

  12.   

    分段绘制我试过,比如对于RectangleGradientPaint的实现(即在一个矩形Area中从中心开始颜色以矩形方式扩散渐变至我们的矩形边框),不行。我估计还是要通过AffineTransform, extends MultipleGradientPaint类然后implement Paint接口。但是具体实施还需讨论。
      

  13.   

    解决了诸多问题,我发上自己使用paintComponent()方法绘制的各种Button:
    正常状态:获得焦点状态:被按下状态:被释放状态:
    由于每帖的字数限制,代码发到了CSDN博客上。大家有兴趣可以去看看,如果能发表下修改意见那将非常高兴。
      

  14.   

    希望大家继续讨论哈:Java绘制渐变颜色的问题上,在 gradient paint上,Java只提供了LinearGradientPaint和RadialGradientPaint,我们现在想实现一个比如EllipseGradientPaint或者RectangleGradientPaint又该如何实现呢?谢谢讨论 Thanks