Java小程序仅部分绘制
我是Java小程序编程的新手,所以如果这是一个非常基本的问题,请原谅,但我在谷歌上搜索了很多,只找到了半相关的问题和解决方案 我正在编写一些几何算法的简单演示,当我重新绘制时,只有一些图形原语被渲染到屏幕上。每次我的小程序重新绘制时,都会绘制线条和椭圆的一个看似随机的子集。唯一的模式是渲染的基本体始终从图形的开头开始。也就是说,有时它会绘制原语0-2,有时0-5,有时整个批次 我想指出的是,据我所知,这不是经典的“闪烁”,可以用双缓冲解决。据我所知,闪烁是指在短时间内,您可以在小程序完成渲染之前看到部分渲染的小程序。然而,在我的例子中,如果它没有完成渲染,它永远不会完成,除非我再次Java小程序仅部分绘制,java,drawing,buffer,render,paint,Java,Drawing,Buffer,Render,Paint,我是Java小程序编程的新手,所以如果这是一个非常基本的问题,请原谅,但我在谷歌上搜索了很多,只找到了半相关的问题和解决方案 我正在编写一些几何算法的简单演示,当我重新绘制时,只有一些图形原语被渲染到屏幕上。每次我的小程序重新绘制时,都会绘制线条和椭圆的一个看似随机的子集。唯一的模式是渲染的基本体始终从图形的开头开始。也就是说,有时它会绘制原语0-2,有时0-5,有时整个批次 我想指出的是,据我所知,这不是经典的“闪烁”,可以用双缓冲解决。据我所知,闪烁是指在短时间内,您可以在小程序完成渲染之前
redraw()
,并获得幸运。我尝试过双缓冲:
public void update(Graphics g) {
Graphics offgc;
Image offscreen = null;
Dimension d = size();
// create the offscreen buffer and associated Graphics
offscreen = createImage(d.width, d.height);
offgc = offscreen.getGraphics();
// clear the exposed area
offgc.setColor(getBackground());
offgc.fillRect(0, 0, d.width, d.height);
offgc.setColor(getForeground());
// do normal redraw
paint(offgc);
// transfer offscreen to window
g.drawImage(offscreen, 0, 0, this);
}
但这似乎毫无帮助。如果有用的话,这里有一些正在发生的事情的图片。这就是它应该看起来的样子:
但大多数时候它看起来像这样:
或者这个:
提前谢谢 这并不是双缓冲的工作原理,也不是绘制过程的工作原理
- 不要覆盖
更新
- 尽可能不要覆盖顶层容器(如Applet/JApplet/Frame/JFrame)的
paint
- 使用可以渲染的“绘制”面板,最好是类似于
。回转组件提供双缓冲支撑JPanel
- 双缓冲区应该在绘制周期的外侧绘制,并且仅在需要时更新,这样可以加快整个绘制过程,因为您不必重新渲染不必要的内容李>
- 当需要更新缓冲区时,请先渲染到临时缓冲区,这样可以确保在更新时可能发生的任何重新绘制不会过早地反射回屏幕
公共类TestPaintGeometry{
公共静态void main(字符串[]args){
新的TestPaintGeometry();
}
公共TestPaintGeometry(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}捕获(ClassNotFoundException ex){
}catch(实例化异常){
}捕获(非法访问例外){
}捕获(无支持的LookandFeelexception ex){
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(新的ShowPane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类ShowPane扩展了JPanel{
私人土工四环素;
公共展示窗格(){
setLayout(新的BorderLayout());
geoPane=新的Geopetrypane();
JButton redrew=新JButton(“Redraw”);
添加(地质烷);
添加(红色,边界布局。南部);
addActionListener(新ActionListener()){
@凌驾
已执行的公共无效操作(操作事件e){
geoPane.redrew();
}
});
}
}
公共级土工四环素扩展JPanel{
专用缓冲区图像缓冲区;
公共无效重绘(){
Path2D.Float path=新的Path2D.Float();
int width=getWidth();
int height=getHeight();
int points=Math.max(10,(int)Math.round(Math.random()*100));
对于(int index=0;index0){
线路图(x,y);
}否则{
路径移动到(x,y);
}
}
BuffereImage tmp=createCompatibleImage(宽度、高度);
Graphics2D g2d=tmp.createGraphics();
g2d.setColor(Color.BLACK);
g2d.绘制(路径);
g2d.dispose();
缓冲区=tmp;
重新油漆();
}
@凌驾
公共维度getPreferredSize(){
返回新维度(200200);
}
@凌驾
受保护组件(图形g){
超级组件(g);
if(缓冲区!=null){
intx=(getWidth()-buffer.getWidth())/2;
int y=(getHeight()-buffer.getHeight())/2;
g、 drawImage(缓冲区,x,y,this);
}
}
}
公共静态图形配置getGraphicsConfiguration(){
返回GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
公共静态缓冲区映像createCompatibleImage(整数宽度、整数高度){
返回createCompatibleImage(宽度、高度、透明度、半透明);
}
公共静态缓冲区图像createCompatibleImage(整数宽度、整数高度、整数透明度){
BuffereImage image=getGraphicsConfiguration().createCompatibleImage(宽度、高度、透明度);
image.impressedata(true);
返回图像;
}
}
这允许您将GeometryPane
部署到JFrame
或JAppelt
,因为它不受继承遗产的约束…它的非小程序问题
public class TestPaintGeometry {
public static void main(String[] args) {
new TestPaintGeometry();
}
public TestPaintGeometry() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ShowPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ShowPane extends JPanel {
private GeometryPane geoPane;
public ShowPane() {
setLayout(new BorderLayout());
geoPane = new GeometryPane();
JButton redrew = new JButton("Redraw");
add(geoPane);
add(redrew, BorderLayout.SOUTH);
redrew.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
geoPane.redrew();
}
});
}
}
public class GeometryPane extends JPanel {
private BufferedImage buffer;
public void redrew() {
Path2D.Float path = new Path2D.Float();
int width = getWidth();
int height = getHeight();
int points = Math.max(10, (int) Math.round(Math.random() * 100));
for (int index = 0; index < points; index++) {
int x = (int) Math.round(Math.random() * width);
int y = (int) Math.round(Math.random() * height);
if (index > 0) {
path.lineTo(x, y);
} else {
path.moveTo(x, y);
}
}
BufferedImage tmp = createCompatibleImage(width, height);
Graphics2D g2d = tmp.createGraphics();
g2d.setColor(Color.BLACK);
g2d.draw(path);
g2d.dispose();
buffer = tmp;
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (buffer != null) {
int x = (getWidth() - buffer.getWidth()) / 2;
int y = (getHeight() - buffer.getHeight()) / 2;
g.drawImage(buffer, x, y, this);
}
}
}
public static GraphicsConfiguration getGraphicsConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
public static BufferedImage createCompatibleImage(int width, int height) {
return createCompatibleImage(width, height, Transparency.TRANSLUCENT);
}
public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency);
image.coerceData(true);
return image;
}
}