Создание собственного JButton в Java

Есть ли способ создать JButtonсвой собственный графический элемент кнопки, а не только изображение внутри кнопки?

Если нет, есть ли другой способ создать кастом JButtonв Java?

5.08.2008 12:15:08
5 ОТВЕТОВ
РЕШЕНИЕ

Когда я впервые изучал 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()возвращая одно и то же значение. Я не слишком много экспериментировал с этим, но в зависимости от макета, который вы используете для своего графического интерфейса, ваша кнопка может выглядеть совершенно иначе.

И, наконец, исходный код . На случай, если я что-то пропустил.

90
27.10.2016 07:19:59
Привет, сначала спасибо за код! Я бы предложил добавить 'setActionComme (String Command)' в ваш код. это один из способов фильтрации событий в Swing. (но тогда вы можете утверждать, что есть 1001 вещь, которая может быть добавлена, чтобы сделать ее немного лучше: P)
Jason Rogers 13.12.2010 05:51:59
Чтобы создать штамп, который вы можете нажать, вы можете использовать обычный старый JButton (вместо того, чтобы создавать подклассы или создавать собственный JComponent), используя преимущества setIcon / setPressedIcon, а также другие функциональные возможности Icon в JButton
ControlAltDel 13.02.2017 15:14:43

Я не занимался разработкой SWING с ранних классов CS, но если бы он не был встроен, вы могли бы просто наследовать javax.swing.AbstractButtonи создавать свои собственные. Должно быть довольно просто соединить что-то с существующей структурой.

7
9.08.2018 09:56:03

Вы всегда можете попробовать Synth look & feel. Вы предоставляете 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

13
22.09.2014 17:28:03

Да, это возможно Одним из главных плюсов использования 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 динамичны и зависят от внешнего вида и ощущений, которые используются. Даже внешний вид металла по умолчанию изменился во всех версиях JRE. Было бы лучше реализовать AbstractButton и соответствовать рекомендациям Swing API. Хорошей отправной точкой является рассмотрение классов javax.swing.LookAndFeel и javax.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 полезно для написания элементов управления: создание собственного стиля

33
22.09.2014 17:33:24

Я, вероятно, проехал миллион миль по неправильному прямому пути (но я только молод: P). но вы не можете добавить графику на панель, а затем мышиный слой к графическому объекту, чтобы, когда пользователь на графике выполнял ваши действия.

8
20.08.2008 15:48:56
Это бы сработало, но я бы предпочел использовать стандартный JButton, чем создавать кнопки моего типа, если это возможно.
Anton 16.09.2008 01:18:57