我已经看到了一些与此相关的问题,但它们要么涉及重复创建Fonts
,要么涉及paintComponent()
。我的项目都没有。我创建了一个可运行的测试用例,显示了延迟(随着setFont()
之后对JComponents
的后续调用,这种延迟似乎会增加。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import extensions.JActionButton;
public class TestFrame {
private JFrame mainframe;
private JPanel content;
private JButton exitButton;
public static void main(String[] args) {
new TestFrame();
}
public TestFrame() {
Color foreground = new Color(240, 240, 240);
Color background = new Color(254, 70, 70);
Color border = new Color(127, 127, 127);
Theme activeTheme = new Theme(foreground, background, border);
mainframe = new JFrame("Test");
mainframe.getContentPane().setLayout(new BorderLayout());
content = new JPanel();
content.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 10));
content.setPreferredSize(new Dimension(480, 320));
Font bold = new Font("Sans", Font.BOLD, 14);
exitButton = new JActionButton("Exit", activeTheme,
BorderFactory.createMatteBorder(1, 3, 1, 1, activeTheme.getBorder()));
// exitButton = new JButton("Exit");
exitButton.setForeground(activeTheme.getForeground());
exitButton.setBackground(activeTheme.getBackground());
exitButton.setPreferredSize(new Dimension(140, 40));
exitButton.setFont(bold);
exitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
content.add(exitButton);
mainframe.add(content, BorderLayout.CENTER);
mainframe.pack();
mainframe.setLocationByPlatform(true);
mainframe.setVisible(true);
}
}
您可以将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;
}
}
Theme
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;
}
}
答案 0 :(得分:1)
一旦我导出到JAR并将其作为程序运行,这似乎不是问题。据推测,这是由于启动时间延长并包含SplashScreen
提供。
仍然是一般性能的瓶颈,但除非我发现任何相反的建议,否则在构建JFrame
作为Java程序的初始部分时仅是个问题。
作为JAR运行解决了TestFrame实例和我的实际项目的问题。