当前位置: 首页 > 知识库问答 >
问题:

如何根据JButton的大小更改字体大小?

柳宏深
2023-03-14

我有一个java应用程序-一个计算器。我想通过调整应用程序窗口的大小来动态调整按钮的字体大小。如何实现?

我的想法是使用ComponentEvents。我有应用程序窗口的初始大小和初始字体的大小。我想根据按钮的大小改变字体大小,受窗口大小变化的影响。问题是如何在覆盖方法中使用比例[初始窗口大小]/[初始字体大小]?每个字体的比例都不同。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

public class Main extends JFrame {
    public Main() {
        super("Test");

        JPanel cPane = (JPanel) getContentPane();
        cPane.setLayout(new BorderLayout());
        MyButton sampleButton = new MyButton("Sample text");
        sampleButton.setFont(new Font("Sans Serif", Font.PLAIN, 20));

        MyButton a, b, c, d;
        a = new MyButton("a");
        b = new MyButton("b");
        c = new MyButton("c");
        d = new MyButton("d");




        cPane.add(a, BorderLayout.PAGE_START);
        cPane.add(b, BorderLayout.PAGE_END);
        cPane.add(c, BorderLayout.LINE_START);
        cPane.add(d, BorderLayout.LINE_END);

        cPane.add(sampleButton, BorderLayout.CENTER);
        setSize(300, 200);
        setResizable(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String... args) {
        new Main();
    }

    class MyButton extends JButton implements ComponentListener {
        public MyButton(String title) {
            super(title);
        }

        @Override
        public void componentResized(ComponentEvent e) {
            //resizing font
        }

        @Override
        public void componentMoved(ComponentEvent e) {

        }

        @Override
        public void componentShown(ComponentEvent e) {

        }

        @Override
        public void componentHidden(ComponentEvent e) {

        }
    }
}

共有2个答案

沈俊晤
2023-03-14

比较这里和这里显示的方法。前者使用可用的< code > jcomponent . size variant 。

后者引用了一个使用<code>FontMentrics</code>的示例。

或者< code>TextLayout。

勾长卿
2023-03-14

看看您如何使用GlyphVector来使用此代码来确定适合的最大字体

  • GUI 有点摇晃,除非在设置可见帧和添加组件接收器之间有延迟。我通过使用单镜头 Swing 计时器延迟添加侦听器解决了这个问题。
  • 是基于微积分,它是一个使用脚本引擎的全功能(如果简单)计算器。
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.util.ArrayList;
import javax.script.*;
import javax.swing.border.Border;

class SwingCalculator implements ActionListener, KeyListener {

    JTextField io;
    ScriptEngine engine;
    ArrayList<JButton> controls;
    final BufferedImage textImage = new BufferedImage(
            100, 100,
            BufferedImage.TYPE_INT_ARGB);

    public int getMaxFontSizeForControls() {
        Graphics2D g = textImage.createGraphics();
        FontRenderContext frc = g.getFontRenderContext();
        int maxSize = 500;
        for (JButton b : controls) {
            // skip the = button..
            if (!b.getText().equals("=")) {
                int max = getMaxFontSizeForControl(b, frc);
                if (maxSize > max) {
                    maxSize = max;
                }
            }
        }
        g.dispose();
        return maxSize;
    }

    public int getMaxFontSizeForControl(JButton button, FontRenderContext frc) {
        Rectangle r = button.getBounds();
        Insets m = button.getMargin();
        Insets i = button.getBorder().getBorderInsets(button);
        Rectangle viewableArea = new Rectangle(
                r.width - 
                (m.right + m.left + i.left + i.right),
                r.height - 
                (m.top + m.bottom + i.top + i.bottom)
                );
        Font font = button.getFont();
        int size = 1;
        boolean tooBig = false;
        while (!tooBig) {
            Font f = font.deriveFont((float) size);
            GlyphVector gv = f.createGlyphVector(frc, button.getText());
            Rectangle2D box = gv.getVisualBounds();
            if (box.getHeight() > viewableArea.getHeight()
                    || box.getWidth() > viewableArea.getWidth()) {
                tooBig = true;
                size--;
            }
            size++;
        }
        return size;
    }

    SwingCalculator() {
        // obtain a reference to the JS engine
        engine = new ScriptEngineManager().getEngineByExtension("js");

        JPanel gui = new JPanel(new BorderLayout(2, 2));
        controls = new ArrayList<JButton>();

        JPanel text = new JPanel(new GridLayout(0, 1, 3, 3));
        gui.add(text, BorderLayout.NORTH);
        io = new JTextField(15);
        Font font = io.getFont();
        font = font.deriveFont(font.getSize() * 1.7f);
        io.setFont(font);
        io.setHorizontalAlignment(SwingConstants.TRAILING);
        io.setFocusable(false);
        text.add(io);

        JPanel buttons = new JPanel(new GridLayout(4, 4, 2, 2));
        gui.add(buttons, BorderLayout.CENTER);
        addButton(buttons, "7");
        addButton(buttons, "8");
        addButton(buttons, "9");
        addButton(buttons, "/");

        addButton(buttons, "4");
        addButton(buttons, "5");
        addButton(buttons, "6");
        addButton(buttons, "*");

        addButton(buttons, "1");
        addButton(buttons, "2");
        addButton(buttons, "3");
        addButton(buttons, "-");

        addButton(buttons, "0");
        addButton(buttons, ".");
        addButton(buttons, "C");
        addButton(buttons, "+");

        JButton equals = new JButton("=");
        equals.addKeyListener(this);
        controls.add(equals);
        equals.addActionListener(this);
        gui.add(equals, BorderLayout.EAST);

        gui.setBorder(new EmptyBorder(5, 5, 5, 5));

        final JFrame f = new JFrame("Calculet");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(gui);
        f.pack();
        f.setMinimumSize(f.getSize());
        f.setLocationByPlatform(true);
        f.setVisible(true);

        final ComponentListener cl = new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent e) {
                int ii = getMaxFontSizeForControls();
                for (JButton b : controls) {
                    if (!b.getText().equals("=")) {
                        b.setFont(b.getFont().deriveFont((float) ii));
                    }
                }
            }
        };
        ActionListener al = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                f.addComponentListener(cl);
            }
        };
        Timer t = new Timer(500, al);
        t.setRepeats(false);
        t.start();
    }

    public void addButton(Container c, String text) {
        JButton b = new JButton(text);
        b.addActionListener(this);
        b.addKeyListener(this);
        controls.add(b);
        c.add(b);
    }

    public void calculateResult() {
        try {
            Object result = engine.eval(io.getText());
            if (result == null) {
                io.setText("Output was 'null'");
            } else {
                io.setText(result.toString());
            }
        } catch (ScriptException se) {
            io.setText(se.getMessage());
        }
    }

    public void actionPerformed(ActionEvent ae) {
        String command = ae.getActionCommand();
        if (command.equals("C")) {
            io.setText("");
        } else if (command.equals("=")) {
            calculateResult();
        } else {
            io.setText(io.getText() + command);
        }
    }

    private JButton getButton(String text) {
        for (JButton button : controls) {
            String s = button.getText();
            if (text.endsWith(s)
                    || (s.equals("=")
                    && (text.equals("Equals") || text.equals("Enter")))) {

                return button;
            }
        }
        return null;
    }

    /*
     * START - Because I hate mice.
     */
    public void keyPressed(KeyEvent ke) {
    }

    public void keyReleased(KeyEvent ke) {
        String s = ke.getKeyText(ke.getKeyCode());
        JButton b = getButton(s);
        if (b != null) {
            b.requestFocusInWindow();
            b.doClick();
        }
    }

    public void keyTyped(KeyEvent ke) {
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                new SwingCalculator();
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}
 类似资料:
  • 我正在使用i18n-js和react-native-localize在我的React Native应用程序中支持多种语言。我为每种语言创建一个 JSON 文件,并根据用户的语言设置使用密钥显示该文件。下面是导入 JSON 文件并配置 i18n 的核心文件。 由于有些语言不使用字母表,我希望能够更改其字体大小。 有人知道我怎么做吗?

  • 除了这个问题:更改超文本标记语言电子邮件正文字体类型和大小在VBA,我想知道如何才能改变字体大小 当我从代码中删除字体大小时,它确实改变了字体系列。 谢谢你的协助,

  • 问题内容: 我有一个具有%宽度和高度的容器,因此它可以根据外部因素进行缩放。我希望容器内的字体相对于容器的大小是恒定的。有没有什么好方法可以使用CSS做到这一点?将根据原来的字体尺寸(这将是100%)将只缩放字体。 问题答案: 您也许可以使用CSS3通过计算来做到这一点,但是使用JavaScript可能更安全。 使用JS,您可以更改文本的高度,然后在调整大小的过程中将相同的计算简单地绑定到调整大小

  • 问题内容: 您可以更改JOptionPane的字体和文本大小吗?我尝试了它,只有当我在那个特定的Java类上“运行文件”时,它才起作用。如果启动整个项目,则不会更改字体。我只想更改一个特定的JOptionPane而不是全部。 这是代码: 问题答案: 真的很简单。JOption窗格不仅接受字符串,还接受组件。因此,您可以创建一个标签集并设置其字体并将其用作消息。 我不明白为什么以前没人回答这个问题

  • 问题内容: 它由9个框组成,中间带有文本。我已经制作了框,以便它们可以随着屏幕大小的变化而调整大小,以便始终保持在同一位置。 但是,即使我使用百分比,文本也不会调整大小。 如何调整文本的大小,使其在整个页面上始终具有相同的比例? 这是处理多种分辨率的合适解决方案吗?还是我应该在CSS中进行很多检查并为每种媒体类型设置许多布局? ``` html, body { } #launchmain { }

  • 问题内容: 如何更改matplotlib图上所有元素(刻度,标签,标题)的字体大小? 我知道如何更改刻度标签的大小,方法是: 但是如何改变其余的呢? 问题答案: 从matplotlib文档中, 这会将所有项目的字体设置为kwargs对象指定的字体。 另外,您也可以使用此答案中建议的方法: 要么 您可以在“定制matplotlib”页面上找到可用属性的完整列表。