好吧,本來要學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;
}