Вопрос

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

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

Это было полезно?

Решение

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

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

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

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

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

Да, это возможно.Одним из главных плюсов использования 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);
    }

}

Обратите внимание, что, переопределяя Компонент краски что содержимое кнопки может быть изменено, но что граница закрашена пейнтБордер способ.Тот Самый getPreferredSize - получить предварительный размер методом также необходимо управлять, чтобы динамически поддерживать изменения в содержимом.Необходимо соблюдать осторожность при измерении метрик шрифта и размеров изображения.

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

Вы всегда можете попробовать синтезаторный 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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top