Java Swing: как установить текст на самостоятельно настроенную кнопку Jbutton?

Это мой код JButton:

JButton Savebtn = new JButton();//("Save");
Savebtn.setFont(btnFont);
Savebtn.setOpaque(false);
Savebtn.setContentAreaFilled(false);
Savebtn.setBorder(null);
Savebtn.setMargin(new Insets(0, 0, 0, 0));
Savebtn.setIcon(new ImageIcon("src/Pic2/menubtn0.png"));
Savebtn.setPressedIcon(new ImageIcon("src/Pic2/menubtn1.png"));
//Savebtn.setText("Save");

Эффект такой:

Java Swing: как установить текст на самостоятельно настроенную кнопку Jbutton?

Я пытался сделать это:

JButton Savebtn = new JButton();//("Save");
Savebtn.setFont(btnFont);
Savebtn.setOpaque(false);
Savebtn.setContentAreaFilled(false);
Savebtn.setBorder(null);
Savebtn.setMargin(new Insets(0, 0, 0, 0));
Savebtn.setIcon(new ImageIcon("src/Pic2/menubtn0.png"));
Savebtn.setPressedIcon(new ImageIcon("src/Pic2/menubtn1.png"));
Savebtn.setText("Save");

Java Swing: как установить текст на самостоятельно настроенную кнопку Jbutton?

Текст не появился, а справа образовалась белая полоса. Может ли кто-нибудь помочь мне с этим?

PS: я не могу просто поместить слова на свою картинку, потому что текст кнопки, который я хочу показать, связан с моей программой.

Изображение кнопки: Java Swing: как установить текст на самостоятельно настроенную кнопку Jbutton?

.. Доступ к встроенному ресурсу должен осуществляться по URL-адресу, а не через файл. Смотрите информацию . страница для встроенного ресурса о том, как сформировать URL.

Andrew Thompson 13.12.2020 06:40

4) Изучите общепринятую номенклатуру Java (соглашения об именах — например, EachWordUpperCaseClass, firstWordLowerCaseMethod(), firstWordLowerCaseAttribute, если это не UPPER_CASE_CONSTANT) и последовательно используйте ее. 5) Рассмотрите возможность использования фабричного метода для настройки этих кнопок. Используя аргументы метода, передайте текст кнопки и оба значка/пути к значку.

Andrew Thompson 13.12.2020 06:55

Очень извиняюсь за свои ошибки в размещении изображений и названии, и спасибо всем тем, кто помогал редактировать. А также извините, что был слишком занят, чтобы не проверить ответы как можно скорее. Сейчас я выбрал лучшее решение, оно очень простое и понятное. Надеюсь, это может помочь другим, у кого есть подобные проблемы!

Shuxin 15.12.2020 12:14
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
144
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я взял ваш фрагмент кода и поместил его в созданный мной графический интерфейс.

Вот что я придумал.

Теперь это не очень отзывчивая кнопка. Вы не можете сказать, нажата она или нет.

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

Затем я раскомментировал одну строку за раз и проверил.

Тест, тест, тест.

Вот код, который я тестировал.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CustomButtonGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new CustomButtonGUI());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Custom Button");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createButtonPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setPreferredSize(new Dimension(300, 100));
        
        Font font = panel.getFont().deriveFont(48f);
        
        JButton saveButton = new JButton("Save");
        saveButton.setFont(font);
        saveButton.setOpaque(false);
        saveButton.setContentAreaFilled(false);
        saveButton.setBorder(null);
        saveButton.setMargin(new Insets(0, 0, 0, 0));
//      saveButton.setIcon(new ImageIcon("src/Pic2/menubtn0.png"));
//      saveButton.setPressedIcon(new ImageIcon("src/Pic2/menubtn1.png"));
//      
        panel.add(saveButton, BorderLayout.CENTER);
        
        return panel;
    }

}

Просто из интереса, как это отвечает на вопрос ОП? Вы закомментировали 2 строки, которые, по словам ОП, вызывали проблему? Так что не уверен в сути ответа

David Kroukamp 13.12.2020 16:25

@David Kroukamp: Вопрос на момент написания этого комментария: «Как установить текст на самонастраиваемый JButton?» Я отобразил текст на настроенной JButton. Если ОП хочет, чтобы я использовал изображения. ОП должен предоставить изображения. Во всяком случае, мой ответ остается в силе. Тест, тест, тест, тест.

Gilbert Le Blanc 13.12.2020 17:20

Ах, я вижу ... ладно, круто, просто интересно, приятель! Благодарю за разъяснение. И да, тестируйте, отлаживайте, комментируйте и еще немного тестируйте😅 жизнь программирования, лол. +1

David Kroukamp 13.12.2020 17:22

Я думаю, что вы используете JButton неправильно, setIcon и setPressedIcon буквально для значка рядом с JButton, однако для игры вы, вероятно, хотите, чтобы фон менялся при нажатии с одного изображения на другое, что по умолчанию класс JButton делает не поддерживается.

Вот такой кастом JButton я сделал, который позволяет именно это:

CustomJButton.java:

import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.JButton;

public class CustomJButton extends JButton {

    private final BufferedImage normalIcon;
    private final BufferedImage selectedIcon;

    public CustomJButton(BufferedImage normalImage, BufferedImage selectedImage) {
        super();
        setOpaque(false);
        setContentAreaFilled(false);
        setBorder(null);
        setFocusPainted(false);
        setMargin(new Insets(0, 0, 0, 0));
        this.normalIcon = normalImage;
        this.selectedIcon = selectedImage;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(normalIcon.getWidth(), normalIcon.getHeight());
    }

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

        Graphics2D g2d = (Graphics2D) g;

        // lets anti-alias for better quality
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        // lets anti-alias for text too
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // lets draw the correct image depending on if the button is pressed or not
        if (getModel().isPressed()) {
            g2d.drawImage(selectedIcon, 0, 0, getWidth(), getHeight(), this);
        } else {
            g2d.drawImage(normalIcon, 0, 0, getWidth(), getHeight(), this);
        }

        // calc string x and y position
        Font font = getFont();
        String text = getText();
        FontMetrics metrics = g2d.getFontMetrics(font);
        int textWidth = metrics.stringWidth(text);
        int textHeight = metrics.getHeight();
        int textY = getWidth() / 2 - textWidth / 2;
        int textX = getHeight() / 2 - textHeight / 2 + metrics.getAscent();

        // draw the text
        g2d.drawString(text, textY, textX);
    }
}

Который вы затем использовали бы следующим образом:

CustomJButton button = new CustomJButton(ImageIO.read(new URL("https://i.stack.imgur.com/xCGQQ.png")), ImageIO.read(new URL("https://i.stack.imgur.com/R9i1s.png")));
button.setFont(new Font("Jokerman", Font.BOLD, 22));
button.setForeground(Color.WHITE);
button.setText("Press Me!");
button.addActionListener((ActionEvent e) -> {
    JOptionPane.showMessageDialog(frame, "You pressed me");
});
Ответ принят как подходящий

Текст не появился, а справа образовалась белая полоса.

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

По умолчанию текст будет отображаться справа от значка. Итак, вы видите свою иконку, а затем промежуток между иконкой и текстом.

Вам нужно настроить кнопку для отображения текста по центру значка (а не справа от значка):

JButton button = new JButton( "Save" );
button.setIcon(...);
button.setPressedIcon(...);   
button.setHorizontalTextPosition(JLabel.CENTER);
button.setVerticalTextPosition(JLabel.CENTER);

Хороший ответ без необходимости расширения класса, как у меня. +1 к этому.

David Kroukamp 13.12.2020 17:21

Я использовал это так очень легко применить. Спасибо за код и объяснение, вы мне очень помогли!

Shuxin 15.12.2020 12:12

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