Java Swing繪製緩衝
好吧,本來要學Android的,結果Google好像要改底層的程式語言。 甲骨文,你腦子裝屎嗎?嘛,算了,聽說MySql的時候它們就屎一次了。 反正今天還是學習中,你總不能退費吧?
試過之後發現Swing提供的東西根本不能和Qt比,那簡陋的樣子實在是… 當然,簡單也有簡單的好處,因為自訂性更高。 要說我最討厭的還是它的觀察者模式,全部都塞在同一個函式處理,沒有Qt的Signals&Slots靈活。
抱怨完了,開始畫圖吧!
這部份最大的問題是:如果不使用內建的Component的話,會有圖片閃爍的問題,解決方法是使用double buffering。
參考文章
public class DoubleFrame extends JFrame
{
//這邊用Timer處理物件的製造和重繪工作
//話說,這也比不上Qt的Timer
public static Timer defaultTimer = new Timer();
public static int getRandom(int start, int length) {
return (int)(Math.random() * length) + start;
}
public DoubleFrame()
{
setLayout(null);
setBounds(100, 100, 500, 420);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
m_buffer = createImage(getSize().width, getSize().height);
//處理緩衝和物件移動
defaultTimer.schedule(new TimerTask() {
public void run()
{
Graphics gr = m_buffer.getGraphics();
for(MyImage img : m_imageList) {
//消掉前次位置
gr.clearRect(img.x(), img.y(), img.getIconWidth(), img.getIconHeight());
//貼上本次位置
gr.drawImage(img.getImage(), img.x(), img.moveY(20), null);
}
//正式重繪
repaint();
}
}, 180, 220);
//處理物件建立
defaultTimer.schedule(new TimerTask() {
public void run()
{
if(getRandom(0, 2) == 1 && m_imageList.size() < 10) {
int xHint = getRandom(0, 20);
m_imageList.addElement(new MyImage("img.png", xHint * 20, 20));
}
}
}, 500, 300);
}
@Override
public void paint(Graphics g)
{
g.drawImage(m_buffer, 0, 0, null);
}
Vector<MyImage> m_imageList = new Vector<>();
Image m_buffer;
}
class MyImage extends ImageIcon
{
public MyImage(String imagePath)
{
super(imagePath);
}
public Fruit(String imagePath, int x, int y)
{
super(imagePath);
setX(x);
setY(y);
}
public int x()
{
return m_x;
}
public void setX(int x)
{
m_x = x;
}
public int y()
{
return m_y;
}
public void setY(int y)
{
m_y = y;
}
public int moveX(int x)
{
return m_x += x;
}
public int moveY(int y)
{
return m_y += y;
}
int m_y = 0;
int m_x = 0;
}