Java Swing 둥근 테두리 버튼 만들기

2018. 1. 1. 18:55프로그래밍/Java

반응형

 안녕하세요. 오늘은 Java Swing의 JButton을 둥근 형태로 만들어보려고 합니다. 저는 보통 개발을 할 때 기본적인 모양을 주로 썼는데요. 점점 디자인을 바꿔보고 싶어지더라구요. 가장 만만한 버튼부터 변형시켜보려 했는데, 이게 생각처럼 잘 안 돼서 여러 번 삽질을 한 기억이 있습니다. 이번에는 기록도 할 겸 블로그에 기록을 좀 해보려고 합니다.

둥근 버튼 미리보기

 좌측의 버튼은 기본적인 JButton의 모양입니다. 다소 밋밋하고, 올드한 느낌이 없잖아 있죠. 그리고 우측은 제가 임의로 모양을 바꾼 버튼입니다. 이번에는 요 버튼을 만들어볼 예정입니다. 그렇게 어렵지 않습니다!

public class RoundedButton extends JButton {

    public RoundedButton() {
        super();
    }

    public RoundedButton(String text) {
        super(text);
    }

    public RoundedButton(Action action) {
        super(action);
    }

    public RoundedButton(Icon icon) {
        super(icon);
    }

    public RoundedButton(String text, Icon icon) {
        super(text, icon);
    }
}

 먼저 JButton을 상속받는 클래스를 하나 만듭니다. 이 클래스가 둥근 버튼을 만들 거기 때문에 이름을 RoundedButton라고 했습니다. 이 상태로 버튼을 만들면 그냥 일반적인 JButton 모양이 됩니다. 먼저 기본 모양에 있는 테두리를 없애버리고, 반드시 불투명하도록 만들어보겠습니다.

public class RoundedButton extends JButton {


    public RoundedButton() {
        super();
        decorate();
    }

    public RoundedButton(String text) {
        super(text);
        decorate();
    }

    public RoundedButton(Action action) {
        super(action);
        decorate();
    }

    public RoundedButton(Icon icon) {
        super(icon);
        decorate();
    }

    public RoundedButton(String text, Icon icon) {
        super(text, icon);
        decorate();
    }

    protected void decorate() {
        setBorderPainted(false);
        setOpaque(false);
    }
}

 decorate()라는 함수를 만들어 간단하게 처리했습니다. 이제 버튼 모양을 만들어봐야겠죠? 버튼의 모양은 해당 컴포넌트를 그리는 paintComponent 메소드를 오버라이드 하여 처리할 수 있습니다. 그러면 결과물처럼 만들 수 있도록 수정한 paintComponent 코드를 볼 수 있도록 하겠습니다.

@Override
protected void paintComponent(Graphics g) {
    int width = getWidth();
    int height = getHeight();

    Graphics2D graphics = (Graphics2D) g;

    graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    if (getModel().isArmed()) {
        graphics.setColor(getBackground().darker());
    } else if (getModel().isRollover()) {
        graphics.setColor(getBackground().brighter());
    } else {
        graphics.setColor(getBackground());
    }

    graphics.fillRoundRect(0, 0, width, height, 10, 10);

    FontMetrics fontMetrics = graphics.getFontMetrics();
    Rectangle stringBounds = fontMetrics.getStringBounds(this.getText(), graphics).getBounds();

    int textX = (width - stringBounds.width) / 2;
    int textY = (height - stringBounds.height) / 2 + fontMetrics.getAscent();

    graphics.setColor(getForeground());
    graphics.setFont(getFont());
    graphics.drawString(getText(), textX, textY);
    graphics.dispose();

    super.paintComponent(g);
}

 요 paintComponent 메소드를 클래스 안에 위치시키면 됩니다. 일단 한 줄씩 차례대로 살펴보도록 하겠습니다. widthheight는 편의를 위해 가져오도록 했고, graphics는 2D의 그래픽을 그릴 수 있도록 형 변환을 하여 가져왔습니다. setRenderingHint를 통해 배경의 사각형을 부드럽게 그릴 수 있도록 처리합니다.

 다음으로는 버튼에 마우스가 올려진 상태인지(isRollover()), 눌러진 상태인지(isArmed())와 기본적인 상태에 따라 배경의 색을 선택합니다. getBackground()를 통해 색을 가져와서 밝게, 또는 어둡게 처리했습니다. 그리고 난 후, fillRoundRect 메소드를 통해 가로, 세로 크기만큼 10의 둥글기를 가지게 하여 배경을 그립니다.

 다음부터는 버튼의 글자를 새길 차례입니다. FontMetricsRectangle를 통해 글자가 그려지는 사각형의 크기를 구합니다. 그런 이후 글자가 새겨질 위치를 구한 이후에 글자의 색(getForeground())과 폰트(getFont())를 가져와 drawString를 통해 그리면 됩니다. 이후에 graphicsdispose() 해주면 됩니다. 마지막 과정을 해주지 않을 경우엔 약간 조잡한 버튼의 모양이 되니 꼭 해주셔야 깔끔한 모양이 됩니다!

둥근 버튼 기본 상태둥근 버튼 마우스 오버둥근 버튼 클릭

 이렇게 테두리가 둥근 버튼을 만들어봤습니다. 응용하면 시작 부분과 끝 부분이 완전히 둥근도 만들 수 있습니다. 요런 글이 처음이라 시간도 오래 걸리고 글 퀄리티도 만족스럽지는 않네요. 버튼 색이 변하는 모습을 GIF로 만들어보고 싶었으나 이미 시간을 너무 많이 소비한 상태라 그냥 이미지로 첨부하는 점 양해 부탁드립니다. ㅠㅠ 다음에는 더 좋은 퀄리티의 글로 찾아뵐 수 있도록 할게요!

 오늘도 블로그 들러주셔서 감사합니다! 다음에도 또 들러주세요!

반응형