Создание пользовательской кнопки JButton в Java

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
99
0
104 054
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

Вы всегда можете попробовать стиль 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 которых установлено на «грязь»).

И еще пара полезных ссылок:

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

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

Да, это возможно. Одним из основных плюсов использования 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 полезно для написания элементов управления: Создание индивидуального внешнего вида и ощущений

Ответ принят как подходящий

Когда я впервые изучал Java, нам нужно было создать Yahtzee, и я подумал, что было бы круто создать собственные компоненты и контейнеры Swing, а не просто рисовать все на одном JPanel. Преимущество расширения компонентов Swing, конечно, заключается в возможности добавления поддержки сочетаний клавиш и других специальных возможностей, которые вы не можете сделать, просто заставив метод paint() напечатать красивую картинку. Однако это может быть не лучшим способом, но это может быть хорошей отправной точкой для вас.

Редактировать 8/6 - Если это не было видно из изображений, каждый кубик - это кнопка, которую вы можете нажать. Это переместит его на DiceContainer ниже. Взглянув на исходный код, вы увидите, что каждая кнопка Die отрисовывается динамически в зависимости от ее значения.

alt text
alt text
alt text

Вот основные шаги:

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

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

Привет, сначала спасибо за код! Я бы предложил добавить в ваш код setActionComme (String Command). это один из способов фильтрации событий в Swing. (но тогда вы можете возразить, что есть 1001 вещь, которую можно было бы добавить, чтобы немного улучшить ситуацию: P)

Jason Rogers 13.12.2010 08:51

Чтобы создать штамп, который вы можете нажать, вы можете фактически использовать старый простой JButton (а не создавать подклассы или создавать собственный JComponent), используя преимущества setIcon / setPressedIcon, а также другие функции значков в JButton

ControlAltDel 13.02.2017 18:14

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

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

Anton 16.09.2008 05:18

Другие вопросы по теме