所以我写了一个类,它绘制了一个具有一定透明度的透明盒子。只要将鼠标悬停在它上面,透明度就会改变(父组件使用setTransparency(浮动透明度)),但是当更改透明度时,CPU会从~2%上升到~40%CPU使用率。它在变化后再次下降,但这不应该发生,因为当你快速盘旋在几个组件上时它会变得更糟......
这是我写的TransparentBox类的代码:
public class TransparentBox extends JComponent{
private static final long serialVersionUID = 1L;
private Color color = Color.WHITE;
private int borderRadius = 0;
private float transparency = 0.85f;
public TransparentBox(Color color) {
this.color = color;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public void setTransparency(float transparency) {
this.transparency = transparency;
repaint();
}
public float getTransparency() {
return transparency;
}
public int getBorderRadius() {
return borderRadius;
}
public void setBoderRadius(int borderRadius) {
this.borderRadius = borderRadius;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING , RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int alphaType = AlphaComposite.SRC_OVER;
AlphaComposite composite = (AlphaComposite.getInstance(alphaType, transparency));
g2d.setComposite(composite);
g2d.setColor(color);
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), borderRadius, borderRadius);
}
}
我检查了循环或可能减慢它的东西,但我什么都没发现,我也查了一下,但找不到任何东西。经过大量的调试和寻找原因,我100%确定这些组件会导致高CPU使用率。
为了重新创建问题,我很快就创建了一个例子,你应该看到CPU上升,但可能不会达到40%,因为我的实际应用程序要大一些,但是重绘还是会扼杀性能。
public static void main(String[] args){
JFrame newFrame = new JFrame("Demo");
newFrame.setSize(new Dimension(900, 700));
newFrame.setVisible(true);
newFrame.getContentPane().setLayout(null);
newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
LeatherPanel content = new LeatherPanel();
content.setLayout(null);
content.setBounds(0, 0, newFrame.getWidth(), newFrame.getHeight());
newFrame.getContentPane().add(content);
LoginMenu lm = new LoginMenu();
lm.setBounds((newFrame.getWidth()-780)/2, (newFrame.getHeight()-430)/2, 780, 430);
content.add(lm);
lm.update();
}
这是LoginMenu类
public class LoginMenu extends JComponent{
private static final long serialVersionUID = 1L;
private TransparentBox content = null;
private TransparentBox backButton = null;
private TransparentBox loginButton = null;
private JLabel currentIcon = null;
private JLabel currentUserName = null;
private JPasswordField passField = null;
private JPanel user_panel = null;
private JScrollPane user_scroll = null;
private int currentIconID = 0;
private String currentName = "NA";
private boolean userSelected = false;
public LoginMenu() {
content = new TransparentBox(Color.BLUE);
content.setBoderRadius(15);
setLayout(null);
user_panel = new JPanel();
user_panel.setOpaque(false);
user_panel.setLayout(null);
user_panel.setBorder(BorderFactory.createEmptyBorder());
user_scroll = new JScrollPane(user_panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
user_scroll.getVerticalScrollBar().setPreferredSize(new Dimension(0,0));
user_scroll.setOpaque(false);
user_scroll.setBorder(BorderFactory.createEmptyBorder());
user_scroll.getViewport().setOpaque(false);
user_scroll.getVerticalScrollBar().setUnitIncrement(CoreData.INCREMENT_UNIT);
passField = new JPasswordField();
passField.setFont(new Font("Calibri", Font.PLAIN, 20));
passField.setForeground(Color.GRAY);
backButton = new TransparentBox(Color.BLUE);
loginButton = new TransparentBox(Color.BLUE);
}
public void update() {
content.setBounds(0, 0, getWidth(), getHeight());
add(content);
content.removeAll();
content.repaint();
content.revalidate();
if(!userSelected) {
user_panel.removeAll();
int x = 5;
int h = 5;
String[] users = {"Test","Test","Test","Test"};
for(String usr : users) {
UserComponent uc = new UserComponent(usr, null);
uc.setBounds(x, h, 380, 90);
uc.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
currentName = usr;
currentIconID = null;
userSelected = true;
update();
}
});
user_panel.add(uc);
uc.update();
x += 390;
if(x >= getWidth()-310) {
x = 5;
h += 100;
}
}
h += 100;
user_panel.setPreferredSize(new Dimension(getWidth()-10, h));
user_scroll.repaint();
user_scroll.revalidate();
user_scroll.setBounds(0, 0, getWidth(), getHeight());
content.add(user_scroll);
}else {
currentIcon.setBounds((getWidth()-90)/2, 40, 90, 90);
currentUserName = new JLabel(currentName);
currentUserName.setFont(new Font("Calibri", Font.PLAIN, 38));
currentUserName.setForeground(Color.WHITE);
currentUserName.setHorizontalAlignment(SwingConstants.CENTER);
currentUserName.setBounds(20, 130, getWidth()-40, 42);
content.add(currentUserName);
passField.setText("");
passField.setHorizontalAlignment(SwingConstants.CENTER);
passField.requestFocus();
passField.setBounds(20, getHeight()-202, getWidth()-40, 64);
content.add(passField);
backButton.setBounds(20, getHeight()-124, 64, 64);
backButton.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
userSelected = false;
update();
}
@Override
public void mouseEntered(MouseEvent e) {
backButton.setTransparency(0.6f);
}
@Override
public void mouseExited(MouseEvent e) {
backButton.setTransparency(0.85f);
}
});
content.add(backButton);
loginButton.setBounds(getWidth()-84, getHeight()-124, 64, 64);
loginButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
loginButton.setTransparency(0.6f);
}
@Override
public void mouseExited(MouseEvent e) {
loginButton.setTransparency(0.85f);
}
});
content.add(loginButton);
JLabel backArrow = new JLabel("<");
backArrow.setFont(new Font("Calibri", Font.PLAIN, 24));
backArrow.setForeground(Color.WHITE);
backArrow.setHorizontalAlignment(SwingConstants.CENTER);
backArrow.setBounds(0, 0, 64, 64);
backButton.add(backArrow);
JLabel loginArrow = new JLabel(">");
loginArrow.setFont(new Font("Calibri", Font.PLAIN, 24));
loginArrow.setForeground(Color.WHITE);
loginArrow.setHorizontalAlignment(SwingConstants.CENTER);
loginArrow.setBounds(0, 0, 64, 64);
loginButton.add(loginArrow);
}
}
}
LeatherPanel类
public class LeatherPanel extends JComponent{
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING , RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.WHITE);
g.fillRect(x,y,getWidth(),getHeight());
}
}
最后是UserComponent类
public class UserComponent extends JComponent implements MouseListener{
private static final long serialVersionUID = 1L;
private JLabel userLabel = null;
private JLabel userIcon = null;
private TransparentBox content = null;
public UserComponent(String user, int user_icon_id) {
userLabel = new JLabel(user);
userLabel.setFont(new Font("Calibri", Font.PLAIN, 30));
userLabel.setForeground(Color.WHITE);
userLabel.setHorizontalAlignment(SwingConstants.LEFT);
userIcon.setBounds(5, 13, 64, 64);
setLayout(null);
addMouseListener(this);
content = new TransparentBox(Color.WHITE);
content.setTransparency(0.0f);
add(content);
add(userIcon);
add(userLabel);
}
public void update() {
content.setBounds(0, 0, getWidth(), getHeight());
}
@Override
public void mouseEntered(MouseEvent e) {
content.setTransparency(0.2f);
}
@Override
public void mouseExited(MouseEvent e) {
content.setTransparency(0.0f);
}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
}
答案 0 :(得分:0)
如果我不得不猜测,我会说问题出在更新方法上:
public void update() {
content.setBounds(0, 0, getWidth(), getHeight());
add(content);
content.removeAll();
content.repaint();
content.revalidate();
if(!userSelected) {
user_panel.removeAll();
int x = 5;
int h = 5;
String[] users = {"Test","Test","Test","Test"};
for(String usr : users) {
// UserComponent uc = new UserComponent(usr, null);
UserComponent uc = new UserComponent(usr, 1);
uc.setBounds(x, h, 380, 90);
uc.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
currentName = usr;
// currentIconID = null;
currentIconID = 1;
userSelected = true;
update();
}
});
user_panel.add(uc);
uc.update();
x += 390;
if(x >= getWidth()-310) {
x = 5;
h += 100;
}
}
在mousePressed()方法中,您可以调用update()方法。所以在我看来,当你不断更换组件并创建新的监听器时,你可以继续使用某种循环逻辑。
然后,您可以从我看到的内容中调用用户面板上的update()。
所以我建议你需要添加一些调试代码来查看哪些方法继续执行。我想某种程度上你是在一个与透明度无关的循环中,而是你删除/添加组件的方式。