Java setFont()导致JFrame加载延迟

Java setFont()导致JFrame加载延迟,java,swing,fonts,Java,Swing,Fonts,我已经看到了一些与此相关的问题,但它们要么涉及重复创建字体,要么是乱搞paintComponent()。我的项目两者都没有。我创建了一个可运行的测试用例来显示延迟(在不同的JComponents上调用setFont(),延迟似乎会增加) 您可以将JActionButton换成JButton,以获得相同的结果。以防万一,以下是所有相关代码 JActionButton import java.awt.Dimension; import java.awt.Graphics; import java.a

我已经看到了一些与此相关的问题,但它们要么涉及重复创建
字体
,要么是乱搞
paintComponent()
。我的项目两者都没有。我创建了一个可运行的测试用例来显示延迟(在不同的
JComponents
上调用
setFont()
,延迟似乎会增加)

您可以将
JActionButton
换成
JButton
,以获得相同的结果。以防万一,以下是所有相关代码

JActionButton

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;

import javax.swing.JButton;
import javax.swing.border.Border;

import widgets.Theme;

public class JActionButton extends JButton {

    private static final long serialVersionUID = 1L;
    private BufferedImage backgroundImage = null;
    private MouseListener mL = null;

    private Theme theme;

    // you can always pass in null for the Border
    public JActionButton(Theme theme, Border border) {
        super();
        refreshContent();
        setExtendedVariables(theme, border);
    }

    public JActionButton(String text, Theme theme, Border border) {
        super(text);
        refreshContent();
        setExtendedVariables(theme, border);
    }   

    // and you can always pass in a blank string. Bad form, but seriously bored of writing constructors
    public JActionButton(BufferedImage image, String text, Theme theme, Border border) {
        super(text);
        this.backgroundImage = image;
        refreshContent();
        setExtendedVariables(theme, border);
    }

    public void setExtendedVariables(Theme theme, Border border) {
        this.theme = theme;
        setBorder(border);
    }

    public void refreshContent() {
        setFocusPainted(false);
        setContentAreaFilled(false);
        setOpaque(true);

        removeMouseListener(mL);
        mL = new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                setForeground(theme.getForegroundHighlight());
                setBackground(theme.getBackgroundHighlight());
            }

            @Override
            public void mouseExited(MouseEvent e) {
                setForeground(theme.getForeground());
                setBackground(theme.getBackground());
            }

            @Override
            public void mousePressed(MouseEvent e) {
                setForeground(theme.getForegroundLowlight());
                setBackground(theme.getBackgroundLowlight());
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                setForeground(theme.getForegroundHighlight());
                setBackground(theme.getBackgroundHighlight());
            }
        };

        addMouseListener(mL);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        if(null != backgroundImage) {
            g2d.drawImage(backgroundImage, 0, 0, null);
        }
    }

    // for use with BoxLayout as it requires explicit bounds to be set
    public void setAllSimilarConstraints(Dimension dim) {
        setPreferredSize(dim);
        setMinimumSize(dim);
        setMaximumSize(dim);
    }

    public void setAllUniqueConstraints(Dimension min, Dimension max, Dimension pref) {
        setPreferredSize(pref);
        setMinimumSize(min);
        setMaximumSize(max);
    }

    public BufferedImage getBackgroundImage() {
        return backgroundImage;
    }

    public void setBackgroundImage(BufferedImage backgroundImage) {
        this.backgroundImage = backgroundImage;
    }

}
主题

import java.awt.Color;

/**
 * 
 * @author Sean H
 * 
 * Welcome to the multicoloured parade!
 */

public class Theme {

    private Color foreground;
    private Color foregroundHighlight;
    private Color foregroundLowlight;
    private Color background;
    private Color backgroundHighlight;
    private Color backgroundLowlight;
    private Color border;
    private Color borderHighlight;
    private Color borderLowlight;

    public Theme(Color fore, Color back, Color border) {
        foreground = fore;
        int foreR = fore.getRed();
        int foreG = fore.getGreen();
        int foreB = fore.getBlue();
        // courtesy of http://stackoverflow.com/a/6615053/1306811
        Double foreRconv = foreR * 0.75;
        Double foreGconv = foreG * 0.75;
        Double foreBconv = foreB * 0.75;
        foregroundLowlight = new Color(foreRconv.intValue(), foreGconv.intValue(), foreBconv.intValue());
        foreRconv = foreR + ((255 - foreR) * 0.25);
        foreGconv = foreG + ((255 - foreG) * 0.25);
        foreBconv = foreB + ((255 - foreB) * 0.25);
        foregroundHighlight = new Color(foreRconv.intValue(), foreGconv.intValue(), foreBconv.intValue());

        background = back;
        int backR = back.getRed();
        int backG = back.getGreen();
        int backB = back.getBlue();
        Double backRconv = backR * 0.75;
        Double backGconv = backG * 0.75;
        Double backBconv = backB * 0.75;
        backgroundLowlight = new Color(backRconv.intValue(), backGconv.intValue(), backBconv.intValue());
        backRconv = backR + ((255 - backR) * 0.25);
        backGconv = backG + ((255 - backG) * 0.25);
        backBconv = backB + ((255 - backB) * 0.25);
        backgroundHighlight = new Color(backRconv.intValue(), backGconv.intValue(), backBconv.intValue());

        this.border = border;
        int borR = border.getRed();
        int borG = border.getGreen();
        int borB = border.getBlue();
        Double borRconv = borR * 0.75;
        Double borGconv = borG * 0.75;
        Double borBconv = borB * 0.75;
        borderLowlight = new Color(borRconv.intValue(), borGconv.intValue(), borBconv.intValue());
        borRconv = borR + ((255 - borR) * 0.25);
        borGconv = borG + ((255 - borG) * 0.25);
        borBconv = borB + ((255 - borB) * 0.25);
        borderHighlight = new Color(borRconv.intValue(), borGconv.intValue(), borBconv.intValue());
    }

    public Color getForeground() {
        return foreground;
    }

    public void setForeground(Color foreground) {
        this.foreground = foreground;
    }

    public Color getForegroundHighlight() {
        return foregroundHighlight;
    }

    public void setForegroundHighlight(Color foregroundHighlight) {
        this.foregroundHighlight = foregroundHighlight;
    }

    public Color getForegroundLowlight() {
        return foregroundLowlight;
    }

    public void setForegroundLowlight(Color foregroundLowlight) {
        this.foregroundLowlight = foregroundLowlight;
    }

    public Color getBackground() {
        return background;
    }

    public void setBackground(Color background) {
        this.background = background;
    }

    public Color getBackgroundHighlight() {
        return backgroundHighlight;
    }

    public void setBackgroundHighlight(Color backgroundHighlight) {
        this.backgroundHighlight = backgroundHighlight;
    }

    public Color getBackgroundLowlight() {
        return backgroundLowlight;
    }

    public void setBackgroundLowlight(Color backgroundLowlight) {
        this.backgroundLowlight = backgroundLowlight;
    }

    public Color getBorder() {
        return border;
    }

    public void setBorder(Color border) {
        this.border = border;
    }

    public Color getBorderHighlight() {
        return borderHighlight;
    }

    public void setBorderHighlight(Color borderHighlight) {
        this.borderHighlight = borderHighlight;
    }

    public Color getBorderLowlight() {
        return borderLowlight;
    }

    public void setBorderLowlight(Color borderLowlight) {
        this.borderLowlight = borderLowlight;
    }

}

一旦我导出到JAR并将其作为程序运行,这似乎就不是问题了。这可能是由于启动时间延长,包括
SplashScreen
提供的

仍然是总体性能的瓶颈,但除非我找到任何相反的建议,否则这只是在构建
JFrame
作为Java程序的初始部分时的问题


作为JAR运行解决了TestFrame实例和实际项目的问题。

为什么不试试
deriveFont()
?仍然会造成延迟;我猜你的意思是
setFont(bold.deriveFont(14))
setFont()
调用就是它所做的,而不是字体实例化——我不这么认为。
import java.awt.Color;

/**
 * 
 * @author Sean H
 * 
 * Welcome to the multicoloured parade!
 */

public class Theme {

    private Color foreground;
    private Color foregroundHighlight;
    private Color foregroundLowlight;
    private Color background;
    private Color backgroundHighlight;
    private Color backgroundLowlight;
    private Color border;
    private Color borderHighlight;
    private Color borderLowlight;

    public Theme(Color fore, Color back, Color border) {
        foreground = fore;
        int foreR = fore.getRed();
        int foreG = fore.getGreen();
        int foreB = fore.getBlue();
        // courtesy of http://stackoverflow.com/a/6615053/1306811
        Double foreRconv = foreR * 0.75;
        Double foreGconv = foreG * 0.75;
        Double foreBconv = foreB * 0.75;
        foregroundLowlight = new Color(foreRconv.intValue(), foreGconv.intValue(), foreBconv.intValue());
        foreRconv = foreR + ((255 - foreR) * 0.25);
        foreGconv = foreG + ((255 - foreG) * 0.25);
        foreBconv = foreB + ((255 - foreB) * 0.25);
        foregroundHighlight = new Color(foreRconv.intValue(), foreGconv.intValue(), foreBconv.intValue());

        background = back;
        int backR = back.getRed();
        int backG = back.getGreen();
        int backB = back.getBlue();
        Double backRconv = backR * 0.75;
        Double backGconv = backG * 0.75;
        Double backBconv = backB * 0.75;
        backgroundLowlight = new Color(backRconv.intValue(), backGconv.intValue(), backBconv.intValue());
        backRconv = backR + ((255 - backR) * 0.25);
        backGconv = backG + ((255 - backG) * 0.25);
        backBconv = backB + ((255 - backB) * 0.25);
        backgroundHighlight = new Color(backRconv.intValue(), backGconv.intValue(), backBconv.intValue());

        this.border = border;
        int borR = border.getRed();
        int borG = border.getGreen();
        int borB = border.getBlue();
        Double borRconv = borR * 0.75;
        Double borGconv = borG * 0.75;
        Double borBconv = borB * 0.75;
        borderLowlight = new Color(borRconv.intValue(), borGconv.intValue(), borBconv.intValue());
        borRconv = borR + ((255 - borR) * 0.25);
        borGconv = borG + ((255 - borG) * 0.25);
        borBconv = borB + ((255 - borB) * 0.25);
        borderHighlight = new Color(borRconv.intValue(), borGconv.intValue(), borBconv.intValue());
    }

    public Color getForeground() {
        return foreground;
    }

    public void setForeground(Color foreground) {
        this.foreground = foreground;
    }

    public Color getForegroundHighlight() {
        return foregroundHighlight;
    }

    public void setForegroundHighlight(Color foregroundHighlight) {
        this.foregroundHighlight = foregroundHighlight;
    }

    public Color getForegroundLowlight() {
        return foregroundLowlight;
    }

    public void setForegroundLowlight(Color foregroundLowlight) {
        this.foregroundLowlight = foregroundLowlight;
    }

    public Color getBackground() {
        return background;
    }

    public void setBackground(Color background) {
        this.background = background;
    }

    public Color getBackgroundHighlight() {
        return backgroundHighlight;
    }

    public void setBackgroundHighlight(Color backgroundHighlight) {
        this.backgroundHighlight = backgroundHighlight;
    }

    public Color getBackgroundLowlight() {
        return backgroundLowlight;
    }

    public void setBackgroundLowlight(Color backgroundLowlight) {
        this.backgroundLowlight = backgroundLowlight;
    }

    public Color getBorder() {
        return border;
    }

    public void setBorder(Color border) {
        this.border = border;
    }

    public Color getBorderHighlight() {
        return borderHighlight;
    }

    public void setBorderHighlight(Color borderHighlight) {
        this.borderHighlight = borderHighlight;
    }

    public Color getBorderLowlight() {
        return borderLowlight;
    }

    public void setBorderLowlight(Color borderLowlight) {
        this.borderLowlight = borderLowlight;
    }

}