Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用createBufferStrategy()的正确方法是什么?_Java_Swing_Bufferstrategy - Fatal编程技术网

Java 使用createBufferStrategy()的正确方法是什么?

Java 使用createBufferStrategy()的正确方法是什么?,java,swing,bufferstrategy,Java,Swing,Bufferstrategy,即使在使用JavaSwing一年多之后,它对我来说仍然是一种魔力。如何正确使用缓冲策略,特别是方法createBufferSrategy() 我想有一个JFrame和一个画布,可以添加到其中,然后进行绘制。我还希望能够调整画布的大小(setSize())。每次我调整画布的大小时,我的BufferStrategy似乎都被破坏了,或者说变得无用,因为在BufferStrategy上使用show()。另外,createBufferStrategy()有一种奇怪的非确定性行为,我不知道如何正确地同步它

即使在使用JavaSwing一年多之后,它对我来说仍然是一种魔力。如何正确使用缓冲策略,特别是方法
createBufferSrategy()

我想有一个JFrame和一个画布,可以添加到其中,然后进行绘制。我还希望能够调整画布的大小(
setSize()
)。每次我调整画布的大小时,我的
BufferStrategy
似乎都被破坏了,或者说变得无用,因为在
BufferStrategy
上使用
show()。另外,
createBufferStrategy()
有一种奇怪的非确定性行为,我不知道如何正确地同步它

我的意思是:

public class MyFrame extends JFrame {
MyCanvas canvas;
int i = 0;

public MyFrame() {
    setUndecorated(false);
    setVisible(true);
    setSize(1100, 800);
    setLocation(100, 100);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    canvas = new MyCanvas();
    add(canvas);
    canvas.makeBufferStrat();
}

@Override
public void repaint() {
    super.repaint();
    canvas.repaint();
    //the bigger threshold's value, the more likely it is that the BufferStrategy works correctly
    int threshold = 2;
    if (i < threshold) {
        i++;
        canvas.makeBufferStrat();
    }
}
}
我只是从main方法中的while(true)循环调用
MyFrame
repaint()
方法。 当
threshold
很小时(即2),
bufferStrat.show()
在大约70%的情况下没有任何作用-启动程序时JFrame只是保持灰色。剩下的30%是它应该如何绘制矩形的。如果我做
threshold=200,在我执行程序的时间里,绘画成功率接近100%。Javadoc说,
createBufferStrategy()
可能需要一段时间,所以我认为这就是问题所在。但是,如何正确地同步和使用它?很明显,我做错了什么。我无法想象它是怎么被使用的


有人有一个最简单的工作示例吗?

创建
缓冲策略的方法是“好的”,您可以看看有一个简洁的小示例的

你使用它的方式值得怀疑。使用
BufferStrategy
的主要原因是,您希望从Swing的绘制算法(被动)中控制绘制过程(主动绘制)

但是,你似乎试图两者兼而有之,这就是为什么它会引起你的问题。相反,您应该有一个“main”循环,负责决定缓冲区应该绘制什么以及何时绘制,例如

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferStrategy;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TestPane testPane = new TestPane();
                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(testPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                // The component needs to be attached to displayed window before
                // the buffer can be created
                testPane.startPainting();
            }
        });
    }

    public class TestPane extends Canvas {

        private AtomicBoolean painting = new AtomicBoolean(true);
        private PaintCycle paintCycle;

        private Rectangle clickBounds;

        public TestPane() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (clickBounds != null && clickBounds.contains(e.getPoint())) {
                        painting.set(false);
                    }
                }
            });
        }

        public void startPainting() {
            if (paintCycle == null) {
                createBufferStrategy(2);
                painting.set(true);
                paintCycle = new PaintCycle();
                Thread t = new Thread(paintCycle);
                t.setDaemon(true);
                t.start();
            }
        }

        public void stopPainting() {
            if (paintCycle != null) {
                painting.set(false);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        public class PaintCycle implements Runnable {

            private BufferStrategy strategy;
            private int xDelta = 2;
            private int yDelta = 2;

            @Override
            public void run() {
                System.out.println("Painting has started");

                int x = (int) (Math.random() * (getWidth() - 40));
                int y = (int) (Math.random() * (getHeight() - 40));

                do {
                    xDelta = (int) (Math.random() * 8) - 4;
                } while (xDelta == 0);
                do {
                    yDelta = (int) (Math.random() * 8) - 4;
                } while (yDelta == 0);

                clickBounds = new Rectangle(x, y, 40, 40);
                strategy = getBufferStrategy();
                while (painting.get()) {
                    // Update the state of the model...
                    update();
                    // Paint the state of the model...
                    paint();
                    try {
                        // What ever calculations you want to use to maintain the framerate...
                        Thread.sleep(40);
                    } catch (InterruptedException ex) {
                    }
                }
                System.out.println("Painting has stopped");
            }

            protected void update() {
                int x = clickBounds.x + xDelta;
                int y = clickBounds.y + yDelta;

                if (x + 40 > getWidth()) {
                    x = getWidth() - 40;
                    xDelta *= -1;
                } else if (x < 0) {
                    x = 0;
                    xDelta *= -1;
                }
                if (y + 40 > getHeight()) {
                    y = getHeight() - 40;
                    yDelta *= -1;
                } else if (y < 0) {
                    y = 0;
                    yDelta *= -1;
                }

                clickBounds.setLocation(x, y);
            }

            protected void paint() {
                // 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 {
                        // Get a new graphics context every time through the loop
                        // to make sure the strategy is validated
                        Graphics2D graphics = (Graphics2D) strategy.getDrawGraphics();

                        // Render to graphics
                        // ...
                        graphics.setColor(Color.BLUE);
                        graphics.fillRect(0, 0, getWidth(), getHeight());

                        graphics.setColor(Color.RED);
                        graphics.fill(clickBounds);

                        // Dispose the graphics
                        graphics.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());
            }

        }

    }

}
导入java.awt.Canvas;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics2D;
导入java.awt.Rectangle;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.image.BufferStrategy;
导入java.util.concurrent.AtomicBoolean;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.swing.JFrame;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公开课考试{
公共静态void main(字符串[]args){
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
TestPane TestPane=新建TestPane();
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(testPane);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
//组件需要先附着到显示的窗口,然后才能显示
//可以创建缓冲区
testPane.startPainting();
}
});
}
公共类TestPane扩展了画布{
私有原子布尔绘制=新原子布尔(true);
私人画册画册;
私有矩形单击边界;
公共测试窗格(){
addMouseListener(新的MouseAdapter(){
@凌驾
公共无效mouseClicked(MouseEvent e){
if(clickBounds!=null&&clickBounds.contains(e.getPoint())){
绘画。设置(假);
}
}
});
}
公共无效开始打印(){
if(paintCycle==null){
创新战略(2);
绘画。设置(真实);
paintCycle=新的paintCycle();
螺纹t=新螺纹(喷漆周期);
t、 setDaemon(true);
t、 start();
}
}
公众休憩用漆(){
if(paintCycle!=null){
绘画。设置(假);
}
}
@凌驾
公共维度getPreferredSize(){
返回新维度(200200);
}
公共类PaintCycle实现了Runnable{
私人缓冲战略;
私有int xDelta=2;
私人int yDelta=2;
@凌驾
公开募捐{
System.out.println(“绘制已开始”);
intx=(int)(Math.random()*(getWidth()-40));
int y=(int)(Math.random()*(getHeight()-40));
做{
xDelta=(int)(Math.random()*8)-4;
}而(xDelta==0);
做{
yDelta=(int)(Math.random()*8)-4;
}而(yDelta==0);
单击边界=新矩形(x、y、40、40);
strategy=getBufferStrategy();
while(绘制.get()){
//更新模型的状态。。。
更新();
//绘制模型的状态。。。
油漆();
试一试{
//您希望使用什么计算来保持帧速率。。。
睡眠(40);
}赶上
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferStrategy;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TestPane testPane = new TestPane();
                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(testPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                // The component needs to be attached to displayed window before
                // the buffer can be created
                testPane.startPainting();
            }
        });
    }

    public class TestPane extends Canvas {

        private AtomicBoolean painting = new AtomicBoolean(true);
        private PaintCycle paintCycle;

        private Rectangle clickBounds;

        public TestPane() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (clickBounds != null && clickBounds.contains(e.getPoint())) {
                        painting.set(false);
                    }
                }
            });
        }

        public void startPainting() {
            if (paintCycle == null) {
                createBufferStrategy(2);
                painting.set(true);
                paintCycle = new PaintCycle();
                Thread t = new Thread(paintCycle);
                t.setDaemon(true);
                t.start();
            }
        }

        public void stopPainting() {
            if (paintCycle != null) {
                painting.set(false);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        public class PaintCycle implements Runnable {

            private BufferStrategy strategy;
            private int xDelta = 2;
            private int yDelta = 2;

            @Override
            public void run() {
                System.out.println("Painting has started");

                int x = (int) (Math.random() * (getWidth() - 40));
                int y = (int) (Math.random() * (getHeight() - 40));

                do {
                    xDelta = (int) (Math.random() * 8) - 4;
                } while (xDelta == 0);
                do {
                    yDelta = (int) (Math.random() * 8) - 4;
                } while (yDelta == 0);

                clickBounds = new Rectangle(x, y, 40, 40);
                strategy = getBufferStrategy();
                while (painting.get()) {
                    // Update the state of the model...
                    update();
                    // Paint the state of the model...
                    paint();
                    try {
                        // What ever calculations you want to use to maintain the framerate...
                        Thread.sleep(40);
                    } catch (InterruptedException ex) {
                    }
                }
                System.out.println("Painting has stopped");
            }

            protected void update() {
                int x = clickBounds.x + xDelta;
                int y = clickBounds.y + yDelta;

                if (x + 40 > getWidth()) {
                    x = getWidth() - 40;
                    xDelta *= -1;
                } else if (x < 0) {
                    x = 0;
                    xDelta *= -1;
                }
                if (y + 40 > getHeight()) {
                    y = getHeight() - 40;
                    yDelta *= -1;
                } else if (y < 0) {
                    y = 0;
                    yDelta *= -1;
                }

                clickBounds.setLocation(x, y);
            }

            protected void paint() {
                // 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 {
                        // Get a new graphics context every time through the loop
                        // to make sure the strategy is validated
                        Graphics2D graphics = (Graphics2D) strategy.getDrawGraphics();

                        // Render to graphics
                        // ...
                        graphics.setColor(Color.BLUE);
                        graphics.fillRect(0, 0, getWidth(), getHeight());

                        graphics.setColor(Color.RED);
                        graphics.fill(clickBounds);

                        // Dispose the graphics
                        graphics.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());
            }

        }

    }

}