Java Swing为基本音乐播放器绘制PlayButton

时间:2017-06-06 07:40:17

标签: java swing jbutton

也许我的情况是一个简单的想法混乱。如何使用Shape绘制这样的按钮?

enter image description here

我不介意圆角,这是我对圆角按钮的看法。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;

import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JComponent;
import javax.swing.plaf.basic.BasicButtonUI;

public class PlayButtonUI extends BasicButtonUI{

    protected Shape shape;

    @Override
    protected void installDefaults(AbstractButton b) {
        super.installDefaults(b);
        b.setOpaque(false);//removes that annoying default background
    }

    @Override public void paint(Graphics g, JComponent c) {
        Graphics2D g2 = (Graphics2D)g;
        AbstractButton b = (AbstractButton) c;
        ButtonModel model = b.getModel();
        drawButtonShape(b);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);//smoth borders
        if(model.isArmed()) {
            g2.setColor(Color.RED);//color when button is pressed
        }else{
            g2.setColor(Color.GREEN);//default button color
        }
        g2.fill(shape);//aplying color
        super.paint(g2, c);
    }

    private void drawButtonShape(JComponent c) {
        //button shape is drawn here, 16 are the border radius
        shape = new RoundRectangle2D.Float(0, 0, c.getWidth()-1, c.getHeight()-1,16, 16);
    }

}

我根本不知道如何绘制任何东西,这个类是我在某个地方发现的一个混乱的例子的结果,然后我自己简化直到它工作,我留下一些评论的重要线条

我一直在寻找,并在oracle文档中找到了这个例子。 https://docs.oracle.com/javase/tutorial/2d/geometry/arbitrary.html

我真的不知道如何将Graphics2D转换为Shape,请告诉我,我是否采取了错误的方式。

1 个答案:

答案 0 :(得分:3)

所以,我今天花了好头来对付这个问题,尝试做一大堆魔术......我甚至不能做简单的卡片技巧:P

然后我意识到,我还有其他技巧......

Play me

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicButtonUI;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                JButton btn = new JButton();
                btn.setUI(new PlayButtonUI());
                frame.add(btn);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class PlayButtonUI extends BasicButtonUI {

        @Override
        public Dimension getPreferredSize(JComponent c) {
            return new Dimension(200, 200);
        }

        @Override
        public void paint(Graphics g, JComponent c) {
            Graphics2D g2 = (Graphics2D) g;
            AbstractButton b = (AbstractButton) c;
            ButtonModel model = b.getModel();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);//smoth borders
            if (model.isArmed()) {
                g2.setColor(Color.BLACK);//color when button is pressed
            } else {
                g2.setColor(Color.GRAY);//default button color
            }

            float thinkness = Math.min(c.getWidth(), c.getHeight()) * 0.1f;

            Shape shape = shapeFor(c, thinkness);
            g2.setStroke(new BasicStroke(thinkness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2.fill(shape);//aplying color
            g2.draw(shape);

            super.paint(g2, c);
        }

        private Shape shapeFor(JComponent c, float thickness) {
            GeneralPath gp = new GeneralPath();

            double width = c.getWidth();
            double height = c.getHeight();
            double vPos = height / 2.0;
            double hPos = width - thickness;

            gp.moveTo(0.0 + thickness, 0.0 + thickness);
            gp.lineTo(hPos, vPos);
            gp.lineTo(0.0 + thickness, height - thickness);
            gp.closePath();

            return gp;
        }

    }
}

所以,这是一个轻微的欺骗"。这实际上做的是使用Stroke的属性来生成圆边,而不是尝试使用curveTo或复合形状

有关详细信息,请查看Stroking and Filling Graphics Primitives