【发布时间】:2014-09-04 23:17:22
【问题描述】:
目前我正在使用自定义 JPanel 创建自定义 JFrame。渲染 JFrame 不会闪烁,但是当我渲染自定义 `JPanel 时,组件会闪烁。我的代码:
我绘制JFrame的代码:
public void paint(Graphics g) {
Dimension d = getSize();
Graphics og = g;
g = b.getGraphics();
//background
g.setColor(SConstants.ct.FRAME_BACKGROUND());
g.fillRect(SConstants.ct.FRAME_FRAME_WIDTH(), SConstants.ct.FRAME_FRAME_HEIGHT(), d.width - SConstants.ct.FRAME_FRAME_WIDTH(), d.height - SConstants.ct.FRAME_FRAME_WIDTH());
//frame
if(isFocused()){
g.setColor(SConstants.ct.FRAME_FOCUSED_FRAME());
}else{
g.setColor(SConstants.ct.FRAME_UNFOCUSED_FRAME());
}
//top
g.fillRect(0, 0, d.width, SConstants.ct.FRAME_FRAME_HEIGHT());
//left
g.fillRect(0, 0, SConstants.ct.FRAME_FRAME_WIDTH(), d.height);
//bottom
g.fillRect(0, d.height - SConstants.ct.FRAME_FRAME_WIDTH(), d.width, SConstants.ct.FRAME_FRAME_WIDTH());
//right
g.fillRect(d.width - SConstants.ct.FRAME_FRAME_WIDTH(), 0, SConstants.ct.FRAME_FRAME_WIDTH(), d.height);
//icon
if(getIconImage() != null)
g.drawImage(getIconImage(), 15, SConstants.ct.FRAME_FRAME_HEIGHT() / 2 - getIconImage().getHeight(null) / 2, null);
Graphics2D g2d = (Graphics2D) g;
g2d.setFont(SConstants.ct.FRAME_FONT());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.BLACK);
g2d.drawString(getTitle(), d.width / 2 - g2d.getFontMetrics().stringWidth(getTitle()) / 2, SConstants.ct.FRAME_FRAME_HEIGHT() / 2 - g2d.getFontMetrics().getHeight() / 2 + g2d.getFontMetrics().getAscent());
getContentPane().paint(og);
og.drawImage(b, 0, 0, null);
}
我正在像这样设置contentPane:
getRootPane().setLayout(null);
SPanel cp = new SPanel();
cp.setBounds(SConstants.ct.FRAME_FRAME_WIDTH(), SConstants.ct.FRAME_FRAME_HEIGHT(), getWidth() - SConstants.ct.FRAME_FRAME_WIDTH() * 2, getHeight() - SConstants.ct.FRAME_FRAME_HEIGHT() - SConstants.ct.FRAME_FRAME_WIDTH());
setContentPane(cp);
SPanel 是这样的:
public void paint(Graphics g) {
paintComponent(g);
}
protected void paintComponent(Graphics g) {
//paintComponents(g);
for(Component c : getComponents())
c.paint(g);
}
我正在像这样渲染SLabel:
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.drawString(text, getX() + SConstants.ct.LABEL_SPACING_HORIZONTAL(), getY());
}
public Dimension getPreferredSize() {
Rectangle2D d = getGraphics().getFontMetrics(SConstants.ct.LABEL_FONT()).getStringBounds(text, getGraphics());
int w = (int)(d.getWidth() + SConstants.ct.LABEL_SPACING_HORIZONTAL() * 2);
int h = (int)(d.getHeight() + SConstants.ct.LABEL_SPACING_VERTICAL() * 2);
return new Dimension(w, h);
}
可运行示例:https://drive.google.com/file/d/0B8czlxc22-xqOHlPdUZxV2dkMjQ/edit?usp=sharing
有人知道为什么SLabel 会闪烁吗?
【问题讨论】:
-
你为什么要手动绘制
Components?他们有自己的绘画过程。您正在执行双重绘画动作,因为组件可以由paintComponents绘画或由RepaintManager指示自己绘画 - 您无法控制绘画过程。你已经多次打破油漆链。您提供的所有内容都毫无意义,坦率地说,您不应该这样做 -
运行绘制组件甚至不显示标签。
-
这是什么意思?您是否实际上将
SLabel添加到其中一个容器中?SLabel是某种JComponent吗? -
您还替换了内容窗格,请考虑提供一个 runnable example 来证明您的问题。这将导致更少的混乱和更好的响应
-
另外,通常情况下,
paint会调用paintComponent,因为您认为正常流程对您来说不够好,您破坏了底层的默认双缓冲支持由基于 Swing 的组件提供
标签: java swing jframe rendering