2016-09-27 21 views
1

我正在尝试做一些基本的Java,并且我的框架中有一个形状。它使用JComponent类绘制形状,并在顶部单击按钮时触发动画。直到for循环已经逃脱,重绘才会发生,只有两个框架

组件代码只是此加入的JPanel

public void paintComponent(Graphics g){  
    Dimension dim = getSize();  
    g.setColor(Color.GREEN); 
    g.fillOval(margin, 150, 100, 100); 
    super.paintComponent(g); 
} 

动画只是内部的做了循环,这只是编辑左边距,以使圆形移动到右侧;

​​3210

但它似乎没有移动,直到循环结束,一次移动20个像素。我以前有一个睡眠功能,但它不动画时似乎毫无意义。

任何见解?干杯。

兴趣的人,乱,很大程度上只是为了让造型全码:

class Main extends JFrame{ 

public JPanel panel = new JPanel(); 
JButton button1 = new JButton("Move Right"); 

CreateComps cc = new CreateComps(); 

Main(){ 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    initUI(); 
} 

void initUI(){ 
    setSize(800,800); 
    setBackground(Color.GRAY); 
    setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS)); 

    JPanel topBar = new JPanel(); 
    topBar.setPreferredSize(new Dimension(800,30)); 
    topBar.setMaximumSize(new Dimension(800,30)); 
    topBar.setLayout(new BorderLayout()); 
    topBar.add(button1, BorderLayout.WEST); 
    topBar.setBackground(Color.GRAY); 

    JPanel container = new JPanel(); 
    container.setLayout(new GridBagLayout()); 
    container.setBackground(Color.DARK_GRAY); 

    panel.setPreferredSize(new Dimension(600,500)); 
    panel.setMinimumSize(new Dimension(600,500)); 
    panel.setBackground(Color.WHITE); 
    panel.setLayout(new BorderLayout()); 
    panel.add(cc, BorderLayout.CENTER); 

    add(topBar); 
    add(container); 
    container.add(panel); 

    Listener listen = new Listener(); 
    button1.addActionListener(listen); 

    setVisible(true); 
} 

public void reValidate(){ 
    panel.revalidate(); 
    panel.repaint(); 
} 

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

class Listener implements ActionListener{ 
    @Override 
    public void actionPerformed(ActionEvent e) { 

     System.out.println("Listening.."); 
     if(e.getSource().equals(button1)){ 
      int getMarg = cc.getMargin(); 
      for(int i = 1;i < 20;i++){ 
       getMarg = cc.getMargin(); 
       cc.setMargin(getMarg + 1);    
       reValidate(); 
       System.out.println(i); 
      } 
     }      
    } 
} 



} 

class CreateComps extends JComponent{ 

int margin = 10;   
public void setMargin(int marg){ 
    margin = marg; 
} 
public int getMargin(){ 
    return margin; 
} 
@Override 
public Dimension getPreferredSize(){ 
    return new Dimension(new Dimension(200,200)); 
} 
@Override 
public Dimension getMaximumSize(){ 
    return new Dimension(new Dimension(200,200)); 
} 
@Override 
public Dimension getMinimumSize(){ 
    return new Dimension(new Dimension(200,200)); 
} 
public void paintComponent(Graphics g){  
    Dimension dim = getSize();  
    g.setColor(Color.GREEN); 
    g.fillOval(margin, 150, 100, 100); 
    super.paintComponent(g); 
} 

}

回答

0

没有停顿,你堆叠调用revalidate和会看到没有别的比结果最后一次通话。

您之前拥有的睡眠功能,可能是在Event Dispatch Thread上调用的,因为您阻止了整个事件调度和GUI更新,所以这并不好。

考虑或者使用另一个Threadsleep电话:

@Override 
public void actionPerformed(final ActionEvent e) { 

    System.out.println("Listening.."); 
    if (e.getSource().equals(button1)) { 
     new Thread() { 
      @Override 
      public void run() { 
       int getMarg = cc.getMargin(); 
       for (int i = 1; i < 20; i++) { 
        getMarg = cc.getMargin(); 
        cc.setMargin(getMarg + 1); 
        reValidate(); 
        System.out.println(i); 

        try { 
         Thread.sleep(50); 
        } catch (Throwable e) { 
        } 

       } 
      } 
     }.start(); 

    } 

} 

或者你也可以简单地使用Timer,这是伟大的这份工作。

+1

非常感谢,标记为答案。欢呼声:) –

+0

尽管这确实说明了问题的核心(紧张/在美国东部时间睡觉),但我无法在这么小的一段代码中回答如此大量的不良做法。有一次,Swing中几乎每个类都有'Swing不是线程安全的'。不要从非EDT线程调用'getMargin()'和'setMargin()'等。当你有方便的Swing'Timer'类时,为什么要创建一个全新的线程,它将直接在EDT上运行你的'Runnable'而不需要睡眠? – Ordous