[java] 자바에서 사용자 지정 JButton 만들기

JButton버튼 내부의 이미지뿐만 아니라 자신의 버튼 그래픽으로을 만드는 방법이 있습니까?

그렇지 않은 경우 JButtonJava 에서 사용자 정의를 만드는 다른 방법이 있습니까?



답변

Java를 처음 배울 때 Yahtzee를 만들어야했고 모든 것을 하나에 그리는 대신 사용자 정의 Swing 구성 요소와 컨테이너를 만드는 것이 멋질 것이라고 생각했습니다 JPanel. Swing물론 구성 요소 를 확장 할 때 얻을 수있는 이점은 paint()방법으로 예쁜 그림을 인쇄하는 것만으로는 할 수없는 키보드 단축키 및 기타 접근성 기능에 대한 지원을 추가 할 수 있다는 것 입니다. 하지만 최선의 방법은 아니지만 좋은 출발점이 될 수 있습니다.

8/6 편집-이미지에서 명확하지 않은 경우 각 다이는 클릭 할 수있는 버튼입니다. DiceContainer아래 로 이동합니다 . 소스 코드를 보면 각 Die 버튼이 그 값에 따라 동적으로 그려지는 것을 알 수 있습니다.

대체 텍스트
대체 텍스트
대체 텍스트

다음은 기본 단계입니다.

  1. 확장되는 클래스 만들기 JComponent
  2. 생성자 super()에서 부모 생성자 호출
  3. 클래스 구현 확인 MouseListener
  4. 이것을 생성자에 넣으십시오.

    enableInputMethods(true);
    addMouseListener(this);
  5. 다음 메서드를 재정의합니다.

    public Dimension getPreferredSize()
    public Dimension getMinimumSize()
    public Dimension getMaximumSize()
  6. 이 메서드를 재정의합니다.

    public void paintComponent(Graphics g)

버튼을 그릴 때 작업해야하는 공간의 양은 동일한 값을 getPreferredSize()가정 getMinimumSize()하고 getMaximumSize()반환하는으로 정의됩니다 . 나는 이것으로 너무 많이 실험하지 않았지만 GUI에 사용하는 레이아웃에 따라 버튼이 완전히 다르게 보일 수 있습니다.

마지막으로 소스 코드 . 내가 놓친 것이 있다면.


답변

네, 가능합니다. Swing을 사용하는 주요 장점 중 하나는 추상 컨트롤을 쉽게 만들고 조작 할 수 있다는 것입니다.

다음은 기존 JButton 클래스를 확장하여 텍스트 오른쪽에 원을 그리는 빠르고 더러운 방법입니다.

package test;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MyButton extends JButton {

    private static final long serialVersionUID = 1L;

    private Color circleColor = Color.BLACK;

    public MyButton(String label) {
        super(label);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Dimension originalSize = super.getPreferredSize();
        int gap = (int) (originalSize.height * 0.2);
        int x = originalSize.width + gap;
        int y = gap;
        int diameter = originalSize.height - (gap * 2);

        g.setColor(circleColor);
        g.fillOval(x, y, diameter, diameter);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension size = super.getPreferredSize();
        size.width += size.height;
        return size;
    }

    /*Test the button*/
    public static void main(String[] args) {
        MyButton button = new MyButton("Hello, World!");

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);

        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new FlowLayout());
        contentPane.add(button);

        frame.setVisible(true);
    }

}

paintComponent 를 재정의 하면 버튼의 내용을 변경할 수 있지만 테두리는 paintBorder 메서드에 의해 그려집니다 . 로 getPreferredSize 방법은 컨텐츠에 동적으로 지원 변경을 위해 관리 할 필요가있다. 글꼴 메트릭 및 이미지 크기를 측정 할 때주의해야합니다.

신뢰할 수있는 컨트롤을 만드는 경우 위 코드는 올바른 접근 방식이 아닙니다. 치수와 색상은 Swing에서 동적이며 사용되는 모양과 느낌에 따라 다릅니다. 기본 Metal 모양도 JRE 버전에서 변경되었습니다. AbstractButton 을 구현 하고 Swing API가 설정 한 지침을 따르는 것이 좋습니다 . 좋은 출발점은 javax.swing.LookAndFeeljavax.swing.UIManager 클래스 를 살펴 보는 것 입니다.

http://docs.oracle.com/javase/8/docs/api/javax/swing/LookAndFeel.html

http://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html

LookAndFeel의 구조를 이해하면 컨트롤을 작성하는 데 유용합니다.
사용자 지정 모양과 느낌 만들기


답변

항상 Synth 룩앤필을 사용해 볼 수 있습니다. 사용하려는 이미지와 함께 일종의 스타일 시트 역할을하는 xml 파일을 제공합니다. 코드는 다음과 같습니다.

try {
    SynthLookAndFeel synth = new SynthLookAndFeel();
    Class aClass = MainFrame.class;
    InputStream stream = aClass.getResourceAsStream("\\default.xml");

    if (stream == null) {
        System.err.println("Missing configuration file");
        System.exit(-1);
    }

    synth.load(stream, aClass);

    UIManager.setLookAndFeel(synth);
} catch (ParseException pe) {
    System.err.println("Bad configuration file");
    pe.printStackTrace();
    System.exit(-2);
} catch (UnsupportedLookAndFeelException ulfe) {
    System.err.println("Old JRE in use. Get a new one");
    System.exit(-3);
}

거기에서 평소처럼 JButton을 추가하십시오. 유일한 변경 사항은 setName (string) 메서드를 사용하여 xml 파일에서 단추가 매핑되어야하는 항목을 식별한다는 것입니다.

xml 파일은 다음과 같습니다.

<synth>
    <style id="button">
        <font name="DIALOG" size="12" style="BOLD"/>
        <state value="MOUSE_OVER">
            <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
            <insets top="2" botton="2" right="2" left="2"/>
        </state>
        <state value="ENABLED">
            <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
            <insets top="2" botton="2" right="2" left="2"/>
        </state>
    </style>
    <bind style="button" type="name" key="dirt"/>
</synth>

여기에있는 bind 요소는 매핑 할 대상을 지정합니다 (이 예에서는 name 속성이 “dirt”로 설정된 모든 버튼에 해당 스타일을 적용합니다).

그리고 몇 가지 유용한 링크 :

http://javadesktop.org/articles/synth/

http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html


답변

나는 아마도 잘못된 방향으로 백만 마일을 갈 것입니다 (하지만 나는 젊습니다 : P). 그러나 그래픽을 패널에 추가 한 다음 그래픽 개체에 마우스 리스너를 추가하여 그래픽의 사용자가 작업을 수행 할 수 있도록 할 수는 없습니다.


답변

나는 초기 CS 수업 이후로 SWING 개발을하지 않았지만 그것이 내장되어 있지 않다면 그냥 상속 javax.swing.AbstractButton하고 직접 만들 수 있습니다. 기존 프레임 워크와 함께 무언가를 연결하는 것은 매우 간단해야합니다.


답변