使用自定义按钮确保 Java 图形界面中的响应式文本大小

问题描述 投票:0回答:1

我需要 Java 项目的帮助,特别是关于图形部分。我创建了一个名为 RButton 的图形对象,它允许我创建自定义按钮。我使用 GridBagLayout 和 GridBagConstraints 将它们显示在网格上;但是,我有一个问题。当我稍微调整窗口大小时,文本完全消失,变成一个小方块,文本不可读,导致应用程序无法真正响应。如何确保文本大小始终相应调整?enter image description hereenter image description hereenter image description hereenter image description here

这是按钮的代码

package fr.riya.entity.graphic;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import static java.awt.Font.PLAIN;

/**
 * The type R button.
 */
public class RButton extends JButton {
    private int width;
    private int height;
    private int coordX = 0;
    private int coordY = 0;
    private String title;
    private boolean isBordered = false;
    private boolean isHovered = false;
    private int curved = 10;

    /**
     * Instantiates a new RButton.
     *
     * @param x     the x
     * @param y     the y
     * @param w     the w
     * @param h     the h
     * @param title the title
     */
    public RButton(int x, int y, int w, int h, String title) {
        this.coordX = x;
        this.coordY = y;
        this.width = w;
        this.height = h;
        this.title = title;
        curved = 10;

        setBounds(x, y, w, h);
        setContentAreaFilled(false);
        setFocusPainted(false);
        setBorderPainted(false);
        setOpaque(false);
        setActionCommand(title);


        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                isHovered = true;
                repaint();
            }

            @Override
            public void mouseExited(MouseEvent e) {
                isHovered = false;
                repaint();
            }
        });
    }

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

        Graphics2D g2 = (Graphics2D) g.create();
        g2.setColor(new Color(32, 25, 38));

        g2.fillRoundRect(0, 0, getWidth(), getHeight(), curved, curved);

        if(isBordered) {
            g2.setColor(new Color(0, 71, 79));
            g2.drawRoundRect(2, 2, getWidth()-3, getHeight()-3, curved, curved);
        } if(isHovered) {
            g2.setColor(new Color(255, 255, 255));
            g2.drawRoundRect(2, 2, getWidth()-3, getHeight()-3, curved, curved);
        }

        g2.setColor(Color.WHITE);
        Font font = new Font("Cabin", PLAIN, 48);
        g2.setFont(font);
        FontMetrics metrics = g2.getFontMetrics(font);
        g2.drawString(this.title, (getWidth() - metrics.stringWidth(this.title)) / 2,
                ((getHeight() - metrics.getHeight()) / 2) + metrics.getAscent());

        g2.dispose();
    }

    public String getTitle(){
        return this.title;
    }

    public void setCurved(int c){
        curved = c;
    }

    public void setBorder(boolean b) {
        isBordered = b;
    }
}

这是一个例子:

GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        gbc.anchor = CENTER;
        gbc.fill = NONE;
        gbc.weighty = 0;
        RButton profile = new RButton(0, 0, 256, 130, "Profile");
        profile.setPreferredSize(new Dimension(256, 130));
        profile.setCurved(0);
        add(profile, gbc);

        gbc.gridx = 1;
        RLine line = new RLine(0, 0, THICKNESS, 130, new Color(0, 71, 79));
        line.setPreferredSize(new Dimension(THICKNESS, 130));
        add(line, gbc);```

I tried to set a PreferedSize and think it is the problem. But if i don't use it, no button come out
java swing jbutton gridbaglayout
1个回答
0
投票

因此,您忽略的几件事之一是按钮将部分地根据标题文本和字体规格计算其首选大小,而您在“自定义”中实际上没有考虑到这些“工作流程。

JButton
已经有一个
Font
属性,已经支持“滚动”(或悬停)并且有一个
background
颜色属性,所有这些,你都忽略。

所以,你实际上可以做类似的事情......

public class RButton extends JButton {

    private int width;
    private int height;
    private int coordX = 0;
    private int coordY = 0;
    private String title;
    private boolean isBordered = false;
    private boolean isHovered = false;
    private int curved = 10;

    /**
     * Instantiates a new RButton.
     *
     * @param x the x
     * @param y the y
     * @param w the w
     * @param h the h
     * @param title the title
     */
    public RButton(int x, int y, int w, int h, String title) {
        this.coordX = x;
        this.coordY = y;
        this.width = w;
        this.height = h;
        this.title = title;
        curved = 10;

        // This is irrelevant and should otherwise be
        // ignored, the layout manager will make these
        // decisions for you, that's it's job
        //setBounds(x, y, w, h);
        setContentAreaFilled(false);
        setFocusPainted(false);
        setBorderPainted(false);
        setOpaque(false);
        setActionCommand(title);
        
        // I don't have your font, so I substituted my own
        setFont(new Font("Menlo", Font.PLAIN, 48));
        setForeground(Color.WHITE);
        setText(title);
        setRolloverEnabled(true);
        setBackground(new Color(32, 25, 38));
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setColor(getBackground());

        g2.fillRoundRect(0, 0, getWidth(), getHeight(), curved, curved);

        if (isBordered) {
            g2.setColor(new Color(0, 71, 79));
            g2.drawRoundRect(2, 2, getWidth() - 3, getHeight() - 3, curved, curved);
        }
        boolean isHovered = getModel().isRollover();
        if (isHovered) {
            g2.setColor(new Color(255, 255, 255));
            g2.drawRoundRect(2, 2, getWidth() - 3, getHeight() - 3, curved, curved);
        }

        g2.dispose();

        // This is a "trick" to ensure that the text is
        // rendered over our custom background, as the
        // test is rendered as part of paintComponent 
        // workflow
        super.paintComponent(g);
    }

    public String getTitle() {
        return this.title;
    }

    public void setCurved(int c) {
        curved = c;
        repaint();
    }

    public void setBorder(boolean b) {
        isBordered = b;
        repaint();
    }
}

话虽如此,您仍然会遇到问题,因为字体大小是固定的,因此无论您做什么,文本都将始终以该大小呈现。

动态字体缩放并不简单,而且是一项昂贵的操作,你可以看看当我调整我的应用程序大小时,组件会在已经绘制的组件中进行绘制,这会造成混乱使用ttf使文本宽度灵活font 了解如何实现这一目标的一些想法。

© www.soinside.com 2019 - 2024. All rights reserved.