2011-07-13 154 views
3

考虑到扩展Canvas的Display类,我遇到了一个问题。 单个线程在同一个类中运行。 在这个线程中,调用repaint方法。 但是,虽然线程正常工作,但永远不会调用paint方法!为什么我的重绘不工作?

这里是我的代码(我离开了一切无关):

package display; 

public final class Display extends Canvas implements Runnable { 
private static final long serialVersionUID = 1L; 

private Frame frame; 

private GraphicsEnvironment ge; 
private GraphicsDevice gd; 

public BDisplay() {  
    ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    gd = ge.getDefaultScreenDevice(); 

    frame = new Frame(); 

    //frame.setUndecorated(true); 
    frame.setLocationRelativeTo(null); 
    frame.setResizable(false); 
    frame.setVisible(true); 

    frame.add(this); 

    frame.setLayout(null); 

    //gd.setFullScreenWindow(frame); 
} 

@Override 
public final void paint(Graphics g) { 
    //THIS METHOD IS NEVER CALLED 

    System.out.println("Paint method was called!"); 
    super.paint(g); 

    //... 
} 

@Override 
public synchronized void run() { 
    while (isRunning()) { 
     //THIS LOOP WORKS FINE. 
     this.repaint(); 
    } 
} 
} 

它无关,与缺少一些功能,如isRunning()。 他们存在,我只是把这些留下。

我从来没有偶然发现过这样的问题, ,虽然我一段时间以来都没有对SWING或AWT做过任何事情。

任何人都可以帮忙吗?

螺纹环工作正常,但 重绘只是似乎没有获得计划...

+0

你试图在这里实现的东西很奇怪。 – dhblah

+0

不知道isRunning()是否正在循环运行(;-))。这是不让任何其他线程得到安排 – jogabonito

+0

问题:为什么使用'画布'如果有'JPanel' – mKorbel

回答

3

实现JFrame添加该组件之前(即Canvas,以前JPanel)。

试试这个

public BDisplay() {  
    ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    gd = ge.getDefaultScreenDevice(); 

    frame = new Frame(); 
    frame.setResizable(false); 
    frame.add(this); 
    //frame.setLayout(null); // Why are you using a null layout? 
    frame.pack(); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
} 

编辑

顺便说一句,我推荐使用的JPanel而不是Canvas因为它不建议你混合重和轻组分。有关更多详细信息,请参见Mixing heavy and light components

+0

谢谢,工作得很好! –

+0

@Tom S.,非常欢迎!:) – mre

+0

好suggstion +1 – mKorbel

1

现在???通过使用javax.swing.Timer

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class AnimationJPanel extends JPanel { 

    private static final long serialVersionUID = 1L; 
    private int cx = 0; 
    private int cy = 150; 
    private int cw = 20; 
    private int ch = 20; 
    private int xinc = 1; 
    private int yinc = 1; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       AnimationJPanel panel = new AnimationJPanel(); 
       panel.setPreferredSize(new Dimension(400, 300)); 
       panel.animate(); 
       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       frame.getContentPane().add(panel); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public AnimationJPanel() { 
     setLayout(new BorderLayout()); 
     JLabel label = new JLabel("This is an AnimationJPanel"); 
     label.setForeground(Color.RED); 
     label.setHorizontalAlignment(SwingConstants.CENTER); 
     add(label); 
     setBackground(Color.BLACK); 
     setForeground(Color.RED); 
     setOpaque(true); 
    } 

    public void animate() { 
     new Timer(15, new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       Rectangle oldCircle = new Rectangle(cx - 1, cy - 1, cw + 2, ch + 2); 
       cx += xinc; 
       cy += yinc; 
       if (cx >= getWidth() - cw || cx <= 0) { 
        xinc *= -1; 
       } 
       if (cy >= getHeight() - ch || cy <= 0) { 
        yinc *= -1; 
       } 
       repaint(oldCircle); 
       repaint(cx - 1, cy - 1, cw + 2, ch + 2); 
      } 
     }).start(); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawOval(cx, cy, cw, ch); 
    } 
} 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.Point; 
import java.awt.Polygon; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.Random; 
import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class AnimationBackground { 

    public AnimationBackground() { 
     Random random = new Random(); 
     JFrame frame = new JFrame("Animation Background"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 
     final MyJPanel panel = new MyJPanel(); 
     panel.setBackground(Color.BLACK); 
     for (int i = 0; i < 50; i++) { 
      Star star = new Star(new Point(random.nextInt(490), random.nextInt(490))); 
      star.setColor(new Color(100 + random.nextInt(155), 100 + random.nextInt(155), 100 + random.nextInt(155))); 
      star.setxIncr(-3 + random.nextInt(7)); 
      star.setyIncr(-3 + random.nextInt(7)); 
      panel.add(star); 
     } 
     panel.setLayout(new GridLayout(10, 1)); 
     JLabel label = new JLabel("This is a Starry background.", JLabel.CENTER); 
     label.setForeground(Color.WHITE); 
     panel.add(label); 
     JPanel stopPanel = new JPanel(); 
     stopPanel.setOpaque(false); 
     stopPanel.add(new JButton(new AbstractAction("Stop this madness!!") { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       panel.stopAnimation(); 
      } 
     })); 
     panel.add(stopPanel); 
     JPanel startPanel = new JPanel(); 
     startPanel.setOpaque(false); 
     startPanel.add(new JButton(new AbstractAction("Start moving...") { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       panel.startAnimation(); 
      } 
     })); 
     panel.add(startPanel); 
     frame.add(panel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       AnimationBackground animationBackground = new AnimationBackground(); 
      } 
     }); 
    } 

    class Star extends Polygon { 

     private static final long serialVersionUID = 1L; 
     private Point location = null; 
     private Color color = Color.YELLOW; 
     private int xIncr, yIncr; 
     static final int WIDTH = 500, HEIGHT = 500; 

     Star(Point location) { 
      int x = location.x; 
      int y = location.y; 
      this.location = location; 
      this.addPoint(x, y + 8); 
      this.addPoint(x + 8, y + 8); 
      this.addPoint(x + 11, y); 
      this.addPoint(x + 14, y + 8); 
      this.addPoint(x + 22, y + 8); 
      this.addPoint(x + 17, y + 12); 
      this.addPoint(x + 21, y + 20); 
      this.addPoint(x + 11, y + 14); 
      this.addPoint(x + 3, y + 20); 
      this.addPoint(x + 6, y + 12); 
     } 

     public void setColor(Color color) { 
      this.color = color; 
     } 

     public void move() { 
      if (location.x < 0 || location.x > WIDTH) { 
       xIncr = -xIncr; 
      } 
      if (location.y < 0 || location.y > WIDTH) { 
       yIncr = -yIncr; 
      } 
      translate(xIncr, yIncr); 
      location.setLocation(location.x + xIncr, location.y + yIncr); 
     } 

     public void setxIncr(int xIncr) { 
      this.xIncr = xIncr; 
     } 

     public void setyIncr(int yIncr) { 
      this.yIncr = yIncr; 
     } 

     public Color getColor() { 
      return color; 
     } 
    } 

    class MyJPanel extends JPanel { 

     private static final long serialVersionUID = 1L; 
     private ArrayList<Star> stars = new ArrayList<Star>(); 
     private Timer timer = new Timer(20, new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Star star : stars) { 
        star.move(); 
       } 
       repaint(); 
      } 
     }); 

     public void stopAnimation() { 
      if (timer.isRunning()) { 
       timer.stop(); 
      } 
     } 

     public void startAnimation() { 
      if (!timer.isRunning()) { 
       timer.start(); 
      } 
     } 

     @Override 
     public void addNotify() { 
      super.addNotify(); 
      timer.start(); 
     } 

     @Override 
     public void removeNotify() { 
      super.removeNotify(); 
      timer.stop(); 
     } 

     MyJPanel() { 
      this.setPreferredSize(new Dimension(512, 512)); 
     } 

     public void add(Star star) { 
      stars.add(star); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      for (Star star : stars) { 
       g.setColor(star.getColor()); 
       g.fillPolygon(star); 
      } 
     } 
    } 
}