在实现自己的渲染而不使用标准Java GUI组件时,使用AWT Frame和Swing JFrame有什么主要区别?
这是上一个问题的后续内容:
AWT custom rendering - capture smooth resizes and eliminate resize flicker
Swing与AWT的典型谈话点似乎并不适用,因为我们只使用帧。例如,重量级和轻量级超出窗口(并且JFrame扩展了Frame)。
那么哪个最好,JFrame或框架这种情况?它有什么有意义的区别吗?
注意:此场景是在EDT中渲染不可取的场景。有一个应用程序工作流程没有链接到EDT,渲染是在EDT之外的需要基础上完成的。要使渲染与EDT同步会增加渲染的延迟。除了Frame或JFrame之外,我们不渲染任何Swing或AWT组件(如果最好的话,我们不会渲染封闭的JPanel / Component /等)。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.image.BufferStrategy;
import java.awt.Frame;
public class SmoothResize extends Frame {
public static void main(String[] args) {
Toolkit.getDefaultToolkit().setDynamicLayout(true);
System.setProperty("sun.awt.noerasebackground", "true");
SmoothResize srtest = new SmoothResize();
//srtest.setIgnoreRepaint(true);
srtest.setSize(100, 100);
srtest.setVisible(true);
}
public SmoothResize() {
render();
}
private Dimension old_size = new Dimension(0, 0);
private Dimension new_size = new Dimension(0, 0);
public void validate() {
super.validate();
new_size.width = getWidth();
new_size.height = getHeight();
if (old_size.equals(new_size)) {
return;
} else {
render();
}
}
public void paint(Graphics g) {
validate();
}
public void update(Graphics g) {
paint(g);
}
public void addNotify() {
super.addNotify();
createBufferStrategy(2);
}
protected synchronized void render() {
BufferStrategy strategy = getBufferStrategy();
if (strategy == null) {
return;
}
// Render single frame
do {
// The following loop ensures that the contents of the drawing buffer
// are consistent in case the underlying surface was recreated
do {
Graphics draw = strategy.getDrawGraphics();
Insets i = getInsets();
int w = (int)(((double)(getWidth() - i.left - i.right))/2+0.5);
int h = (int)(((double)(getHeight() - i.top - i.bottom))/2+0.5);
draw.setColor(Color.YELLOW);
draw.fillRect(i.left, i.top + h, w,h);
draw.fillRect(i.left + w, i.top, w,h);
draw.setColor(Color.BLACK);
draw.fillRect(i.left, i.top, w, h);
draw.fillRect(i.left + w, i.top + h, w,h);
draw.dispose();
// Repeat the rendering if the drawing buffer contents
// were restored
} while (strategy.contentsRestored());
// Display the buffer
strategy.show();
// Repeat the rendering if the drawing buffer was lost
} while (strategy.contentsLost());
}
}
答案 0 :(得分:2)
默认情况下,Swing是双缓冲的,所以通常你只需要专注于你的绘画。
这是Swing版本:
import java.awt.*;
import javax.swing.*;
public class SwingResize extends JPanel
{
protected void paintComponent(Graphics g)
{
int w = (int)(((double)(getWidth()))/2+0.5);
int h = (int)(((double)(getHeight()))/2+0.5);
g.setColor(Color.YELLOW);
g.fillRect(0, h, w,h);
g.fillRect(w, 0, w,h);
g.setColor(Color.BLACK);
g.fillRect(0, 0, w, h);
g.fillRect(w, h, w,h);
}
public static void main(String[] args)
{
// Toolkit.getDefaultToolkit().setDynamicLayout(true);
// System.setProperty("sun.awt.noerasebackground", "true");
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new SwingResize() );
frame.setSize(100, 100);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
答案 1 :(得分:2)
扩展@ camickr的answer,"missing detail"为JRootPane
,管理contentPane
。请注意,对于JFrame
“add
及其变体,remove
和setLayout
已被覆盖,以便在必要时转发到contentPane
。” JRootPane#createContentPane()
“创建新的JComponent
a [n] d将BorderLayout
设置为LayoutManager
。”作为实施细节,JComponent
恰好是new JPanel()
。这会对contentPane
的{{1}}产生一些影响:
JFrame
是双缓冲的。contentPane
有一个contentPane
,但BorderLayout
通常默认为JPanel
。FlowLayout
具有L& F特定的UI委托,通常来自contentPane
,可能会影响外观和几何。