JavaでカスタムJButtonを作成する


97

JButtonボタン内の画像だけでなく、独自のボタングラフィックでを作成する方法はありますか?

そうでない場合JButton、Javaでカスタムを作成する別の方法はありますか?

回答:


91

私が最初にJavaを学んでいたとき、私たちはYahtzeeを作らなければならなかったので、すべてを1つに描画するのではなく、カスタムSwingコンポーネントとコンテナーを作成するのがクールだと思いましたJPanelSwingもちろん、コンポーネントを拡張する利点は、paint()メソッドにきれいな画像を印刷させるだけでは実行できないキーボードショートカットやその他のユーザー補助機能のサポートを追加できることです。ただし、最善の方法ではないかもしれませんが、それはあなたにとって良い出発点になるかもしれません。

編集8/6-画像からそれが明らかでない場合、各ダイはクリックできるボタンです。これで下に移動しDiceContainerます。ソースコードを見ると、各ダイボタンがその値に基づいて動的に描画されていることがわかります。

代替テキスト
代替テキスト
代替テキスト

基本的な手順は次のとおりです。

  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に使用するレイアウトによっては、ボタンの外観がまったく異なる場合があります。

そして最後に、ソースコード。何かを逃した場合に備えて。


1
こんにちは、まずコードに感謝します!コードに「setActionComme(String Command)」を追加することをお勧めします。これは、Swingでイベントをフィルタリングする方法の1つです。(しかし、あなたは物事を少し良くするために追加できる1001の物があると主張することができます:P)
Jason Rogers

1
押すことができるダイを作成するには、setIcon / setPressedIconとJButtonの他のアイコン機能を利用することで、実際に(カスタムJComponentをサブクラス化したり作成したりするのではなく)単純な古いJButtonを使用できます
ControlAltDel

34

はい、可能です。Swingを使用する主な長所の1つは、抽象コントロールを簡単に作成および操作できることです。

以下は、既存の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では寸法と色は動的であり、使用されているルックアンドフィールに依存します。デフォルトのメタルの外観でさえ、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の構造を理解することは、コントロールを作成するのに役立ちます。 カスタムルックアンドフィールの作成


13

いつでもシンセのルックアンドフィールを試すことができます。使用する画像とともに、一種のスタイルシートとして機能する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>

バインド要素は、マップ先を指定します(この例では、nameプロパティが "dirt"に設定されているボタンにそのスタイルを適用します)。

そして、いくつかの便利なリンク:

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

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


8

私はおそらく間違ったダイレクトで100万マイルを行きます(しかし、私は若いだけです:P)。しかし、グラフィックをパネルに追加し、次にマウスリスナーをグラフィックオブジェクトに追加して、ユーザーがグラフィックを操作したときにアクションが実行されるようにすることはできませんでした。


1
これは機能しますが、可能であれば、私のタイプのボタンを作成するよりも、標準のJButtonを使用したいと思います。
アントン

7

私は初期のCSクラス以来SWING開発を行っていませんが、それが組み込まれていない場合はjavax.swing.AbstractButton、独自に継承して作成できます。既存のものと一緒に何かを接続するのはかなり簡単なはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.