Java 杀死CPU的Jpanel实现

Java 杀死CPU的Jpanel实现,java,swing,jpanel,cpu-usage,Java,Swing,Jpanel,Cpu Usage,我遇到了一个实现JPanel的类的问题,它似乎会杀死我的CPU,即使应用程序处于空闲状态,并且没有后台线程或类似的东西 该类如下所示: public class GradientPanel extends JPanel { /** * Serial ID */ private static final long serialVersionUID = 1L; /** * Starting color for the gradient */ private Color startColo

我遇到了一个实现JPanel的类的问题,它似乎会杀死我的CPU,即使应用程序处于空闲状态,并且没有后台线程或类似的东西

该类如下所示:

public class GradientPanel extends JPanel {

/**
 * Serial ID
 */
private static final long serialVersionUID = 1L;

/**
 * Starting color for the gradient
 */
private Color startColor;

/**
 * Ending color for the gradient
 */
private Color endColor;

/**
 * Border Color
 */
private Color borderColor;


@Override
/**
 * This is the method that actually paints the Panel 
 * 
 * @param   g   The graphics object used to do the rendering
 * 
 */
protected void paintComponent( Graphics g ) {

    //check that the opacitiy is not set to true first
    if ( !isOpaque( ) ) {

        super.paintComponent( g );  
        return;
    }

    Graphics2D g2d = (Graphics2D) g;

    //to get height and width of the component  
    int w = getWidth();     
    int h = getHeight();

    /*generating gradient pattern from two colors*/
    GradientPaint gp = new GradientPaint( 0, 0, startColor, 0, h, endColor );
    g2d.setPaint( gp ); //set gradient color to graphics2D object
    g2d.fillRect( 0, 0, w, h ); //filling color
    setOpaque( false );
    //Generating Titleborder
    TitledBorder title;
    title= BorderFactory.createTitledBorder(new LineBorder(borderColor, 1, true), null, javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 0, 16), Color.BLACK);
    super.setBorder(title);  //appling border to JPanel
    super.paintComponent( g );
    setOpaque( true );
}

/**
 * Getters and setters 
 */
public Color getStartColor() {
    return startColor;
}


public void setStartColor(Color startColor) {
    this.startColor = startColor;
}


public Color getEndColor() {
    return endColor;
}


public void setEndColor(Color endColor) {
    this.endColor = endColor;
}

public Color getBorderColor() {
    return borderColor;
}


public void setBorderColor(Color borderColor) {
    this.borderColor = borderColor;
}
public class CommencingWindow extends JFrame {

/**
 * The serial ID
 */
private static final long serialVersionUID = 1L;


/**
 * Content Panel
 */
private GradientPanel contentPane;


/**
 * Window specific attributes
 */
private GraphicsConfiguration translucencyCapableGC;

/**
 * Flag to indicate if frame supports shaping
 */
private boolean isShapingSupported;

/**
 * Flag used to indicate if frame supports opacity
 */
private boolean isOpacityControlSupported;

/**
 * Used to display an infinite progress bar
 */
private JLabel progress;


/**
 * Constructor
 * @throws MalformedURLException 
 * 
 */
public CommencingWindow(){

    //change default Java icon for a nicer one
    java.net.URL url = ClassLoader.getSystemResource("res/images/smarcos.png");
    Toolkit kit = Toolkit.getDefaultToolkit();
    Image img = kit.createImage(url);
    this.setIconImage(img);
    this.setUndecorated(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setTitle("SMarcos Coach");
    kit = this.getToolkit();
    isShapingSupported = AWTUtilitiesWrapper.isTranslucencySupported(AWTUtilitiesWrapper.PERPIXEL_TRANSPARENT);
    isOpacityControlSupported = AWTUtilitiesWrapper.isTranslucencySupported(AWTUtilitiesWrapper.TRANSLUCENT);
    AWTUtilitiesWrapper.isTranslucencySupported(AWTUtilitiesWrapper.PERPIXEL_TRANSLUCENT);
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    //get translucency properties of the current screen device
    translucencyCapableGC = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    if (!AWTUtilitiesWrapper.isTranslucencyCapable(translucencyCapableGC)) {
        translucencyCapableGC = null;

        GraphicsEnvironment env =
                GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] devices = env.getScreenDevices();

        for (int i = 0; i < devices.length && translucencyCapableGC == null; i++) {
            GraphicsConfiguration[] configs = devices[i].getConfigurations();
            for (int j = 0; j < configs.length && translucencyCapableGC == null; j++) {
                if (AWTUtilitiesWrapper.isTranslucencyCapable(configs[j])) {
                    translucencyCapableGC = configs[j];
                }
            }
        }
        if (translucencyCapableGC == null) {
        }
    }

    // Determine what the default GraphicsDevice can support.
    GraphicsDevice[] gs = ge.getScreenDevices();
    Insets in = kit.getScreenInsets(gs[0].getDefaultConfiguration());
    Dimension d = kit.getScreenSize();
    //Get max screen width and height
    int max_width = (d.width - in.left - in.right);
    int max_height = (d.height - in.top - in.bottom);
    //calculate frame width and height
    int frameWidth = Math.min(max_width, 300);
    int frameHeight = Math.min(max_height, 100);
    //center frame relative to the screen
    int frameX = (int) (max_width - frameWidth) / 2;
    int frameY = (int) (max_height - frameHeight ) / 2;
    this.setSize(frameWidth, frameHeight);//whatever size you want but smaller the insets
    this.setLocation(frameX, frameY);

    //apply rounded corners to frame, if possible
    if (isShapingSupported) {
        Shape  shape = new RoundRectangle2D.Float(0, 0, frameWidth, frameHeight, 30, 30);
        AWTUtilitiesWrapper.setWindowShape(this, shape);
    }
    //apply some transparency, if possible
    if (isOpacityControlSupported) {
        AWTUtilitiesWrapper.setWindowOpacity(this, 1.0f);
    }

    //add the content panel to the frame
    contentPane = new GradientPanel();
    contentPane.setStartColor(new Color(170, 191, 236));
    contentPane.setEndColor(new Color(52, 101, 206));
    contentPane.setBorderColor(new Color(170, 191, 236));
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    //Smarcos Label
    JLabel lblSmarcos = new JLabel();
    String lblSmarcosText = "<html><font align=\"center\" size=\"5\" color=\"D1D1D1\">SMARCOS COACH</font></html>";
    lblSmarcos.setText(lblSmarcosText);
    lblSmarcos.setBounds(67, 14, 257, 30);
    contentPane.add(lblSmarcos);

    //Add a label to ask for the verifier
    JLabel lblVerifier = new JLabel();
    String lblVerifierText = "<html><font align=\"center\" size=\"3\" color=\"D1D1D1\">Trying to connect to DirectLife Oauth service...</font></html>";
    lblVerifier.setText(lblVerifierText);
    lblVerifier.setBounds(60, 45, 240, 30);
    contentPane.add(lblVerifier);


}
}

我在另一个类中使用它,它有一个JFrame,看起来像这样:

public class GradientPanel extends JPanel {

/**
 * Serial ID
 */
private static final long serialVersionUID = 1L;

/**
 * Starting color for the gradient
 */
private Color startColor;

/**
 * Ending color for the gradient
 */
private Color endColor;

/**
 * Border Color
 */
private Color borderColor;


@Override
/**
 * This is the method that actually paints the Panel 
 * 
 * @param   g   The graphics object used to do the rendering
 * 
 */
protected void paintComponent( Graphics g ) {

    //check that the opacitiy is not set to true first
    if ( !isOpaque( ) ) {

        super.paintComponent( g );  
        return;
    }

    Graphics2D g2d = (Graphics2D) g;

    //to get height and width of the component  
    int w = getWidth();     
    int h = getHeight();

    /*generating gradient pattern from two colors*/
    GradientPaint gp = new GradientPaint( 0, 0, startColor, 0, h, endColor );
    g2d.setPaint( gp ); //set gradient color to graphics2D object
    g2d.fillRect( 0, 0, w, h ); //filling color
    setOpaque( false );
    //Generating Titleborder
    TitledBorder title;
    title= BorderFactory.createTitledBorder(new LineBorder(borderColor, 1, true), null, javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 0, 16), Color.BLACK);
    super.setBorder(title);  //appling border to JPanel
    super.paintComponent( g );
    setOpaque( true );
}

/**
 * Getters and setters 
 */
public Color getStartColor() {
    return startColor;
}


public void setStartColor(Color startColor) {
    this.startColor = startColor;
}


public Color getEndColor() {
    return endColor;
}


public void setEndColor(Color endColor) {
    this.endColor = endColor;
}

public Color getBorderColor() {
    return borderColor;
}


public void setBorderColor(Color borderColor) {
    this.borderColor = borderColor;
}
public class CommencingWindow extends JFrame {

/**
 * The serial ID
 */
private static final long serialVersionUID = 1L;


/**
 * Content Panel
 */
private GradientPanel contentPane;


/**
 * Window specific attributes
 */
private GraphicsConfiguration translucencyCapableGC;

/**
 * Flag to indicate if frame supports shaping
 */
private boolean isShapingSupported;

/**
 * Flag used to indicate if frame supports opacity
 */
private boolean isOpacityControlSupported;

/**
 * Used to display an infinite progress bar
 */
private JLabel progress;


/**
 * Constructor
 * @throws MalformedURLException 
 * 
 */
public CommencingWindow(){

    //change default Java icon for a nicer one
    java.net.URL url = ClassLoader.getSystemResource("res/images/smarcos.png");
    Toolkit kit = Toolkit.getDefaultToolkit();
    Image img = kit.createImage(url);
    this.setIconImage(img);
    this.setUndecorated(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setTitle("SMarcos Coach");
    kit = this.getToolkit();
    isShapingSupported = AWTUtilitiesWrapper.isTranslucencySupported(AWTUtilitiesWrapper.PERPIXEL_TRANSPARENT);
    isOpacityControlSupported = AWTUtilitiesWrapper.isTranslucencySupported(AWTUtilitiesWrapper.TRANSLUCENT);
    AWTUtilitiesWrapper.isTranslucencySupported(AWTUtilitiesWrapper.PERPIXEL_TRANSLUCENT);
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    //get translucency properties of the current screen device
    translucencyCapableGC = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    if (!AWTUtilitiesWrapper.isTranslucencyCapable(translucencyCapableGC)) {
        translucencyCapableGC = null;

        GraphicsEnvironment env =
                GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] devices = env.getScreenDevices();

        for (int i = 0; i < devices.length && translucencyCapableGC == null; i++) {
            GraphicsConfiguration[] configs = devices[i].getConfigurations();
            for (int j = 0; j < configs.length && translucencyCapableGC == null; j++) {
                if (AWTUtilitiesWrapper.isTranslucencyCapable(configs[j])) {
                    translucencyCapableGC = configs[j];
                }
            }
        }
        if (translucencyCapableGC == null) {
        }
    }

    // Determine what the default GraphicsDevice can support.
    GraphicsDevice[] gs = ge.getScreenDevices();
    Insets in = kit.getScreenInsets(gs[0].getDefaultConfiguration());
    Dimension d = kit.getScreenSize();
    //Get max screen width and height
    int max_width = (d.width - in.left - in.right);
    int max_height = (d.height - in.top - in.bottom);
    //calculate frame width and height
    int frameWidth = Math.min(max_width, 300);
    int frameHeight = Math.min(max_height, 100);
    //center frame relative to the screen
    int frameX = (int) (max_width - frameWidth) / 2;
    int frameY = (int) (max_height - frameHeight ) / 2;
    this.setSize(frameWidth, frameHeight);//whatever size you want but smaller the insets
    this.setLocation(frameX, frameY);

    //apply rounded corners to frame, if possible
    if (isShapingSupported) {
        Shape  shape = new RoundRectangle2D.Float(0, 0, frameWidth, frameHeight, 30, 30);
        AWTUtilitiesWrapper.setWindowShape(this, shape);
    }
    //apply some transparency, if possible
    if (isOpacityControlSupported) {
        AWTUtilitiesWrapper.setWindowOpacity(this, 1.0f);
    }

    //add the content panel to the frame
    contentPane = new GradientPanel();
    contentPane.setStartColor(new Color(170, 191, 236));
    contentPane.setEndColor(new Color(52, 101, 206));
    contentPane.setBorderColor(new Color(170, 191, 236));
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    //Smarcos Label
    JLabel lblSmarcos = new JLabel();
    String lblSmarcosText = "<html><font align=\"center\" size=\"5\" color=\"D1D1D1\">SMARCOS COACH</font></html>";
    lblSmarcos.setText(lblSmarcosText);
    lblSmarcos.setBounds(67, 14, 257, 30);
    contentPane.add(lblSmarcos);

    //Add a label to ask for the verifier
    JLabel lblVerifier = new JLabel();
    String lblVerifierText = "<html><font align=\"center\" size=\"3\" color=\"D1D1D1\">Trying to connect to DirectLife Oauth service...</font></html>";
    lblVerifier.setText(lblVerifierText);
    lblVerifier.setBounds(60, 45, 240, 30);
    contentPane.add(lblVerifier);


}
到目前为止没有什么奇怪或复杂的,现在如果我转到shell并运行“top”,这是setVisible调用之后的输出:

正如您所见,对于这样一个简单的应用程序来说,CPU使用率是荒谬的,它永远在90-80之间运行……恐怕GradientPanel.paintComponent一直在被调用,这导致了这种行为。有人知道怎么解决这个问题吗?一种指定何时调用或刷新率的方法很好

问候,,
Alex

问题来自这一行:

 super.setBorder(title);  //appling border to JPanel
这最终会触发重新绘制,导致组件不断地重新绘制并耗尽CPU

要解决这个问题,请删除该行并尝试从其他地方调用它,例如面板的构造函数


通常,在绘制组件时不应修改组件以避免此类问题。您应该只执行喷漆操作。

问题来自这一行:

 super.setBorder(title);  //appling border to JPanel
这最终会触发重新绘制,导致组件不断地重新绘制并耗尽CPU

要解决这个问题,请删除该行并尝试从其他地方调用它,例如面板的构造函数


通常,在绘制组件时不应修改组件以避免此类问题。您应该只执行绘制操作。

若要更快获得更好的帮助,请发布。若要更快获得更好的帮助,请发布。