2013-01-07 1 views
1

JPanel에서 별도의 스레드로 도형을 그립니다. 이 모양을 호출하는 방법을 통해 move() 이동하려는 있지만 그림의 위치를 ​​변경하지 마십시오.Java에서 도형을 이동하는 방법은 무엇입니까?

이 내 CustomShape 콘솔에

public class CustomShape { 
    private static final int Y_STEP = 5; 
    private static final int X_STEP = 5; 
    public String name; 
    public Shape shape; 
    public Color color; 
    private Point newLocation; 

    public void move() { 
     newLocation.x += X_STEP; 
     newLocation.y += Y_STEP; 
     //How set new location ? 
     //It doesn't work 
     this.shape.getBounds().setLocation(newLocation);   
     System.out.println(String.format("New location is [%d,%d]",newLocation.x, newLocation.y)); 
     System.out.println(String.format("Move to [%d,%d]", this.shape.getBounds().getLocation().x, this.shape.getBounds().getLocation().y));  
    } 

    public CustomShape(Shape shape, Color color, String name) { 
     this.shape = shape; 
     this.color = color; 
     this.name = name; 
     newLocation = this.shape.getBounds().getLocation(); 
    } 

샘플 출력

New location is [15,15] 
Move to [10,10] 
New location is [20,20] 
Move to [10,10] 
New location is [25,25] 
Move to [10,10] 

내 JPanel의

public class ViewPanel extends JPanel { 
    private static final long serialVersionUID = 5252479726227082794L; 
    private List<CustomShape> shapeList = new ArrayList<CustomShape>(); 
    private Map<String, Thread> threads = new HashMap<String, Thread>(); 
    private Timer timer; 
    private static final int TIMER_SPEED = 1000; 

    public ViewPanel() { 
     super(); 
     this.setDoubleBuffered(true); 
     timer = new Timer(TIMER_SPEED, null); 

     timer.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       testMove(); 
      } 
     }); 
    } 
    private void testMove() { 
     for (CustomShape shape : shapeList) { 
      shape.move(); 
     } 
    } 

    public void startMove() { 
     timer.start(); 
    } 

    public void stopMove() { 
     timer.stop(); 
    } 

    public void addShape(CustomShape shape) { 
     shapeList.add(shape); 
     if (!threads.containsKey(shape.getName())) { 
      Thread t = new Thread(new DrawThread(shape, this.getGraphics()), 
        shape.getName()); 
      threads.put(shape.getName(), t); 
      t.start(); 
     } 
     this.repaint(); 
    } 

    public void removeShape(CustomShape shape) { 
     if (threads.containsKey(shape.getName())) { 
      Thread t = threads.remove(shape.getName()); 
      t.interrupt(); 
      shapeList.remove(shape); 
     } 
     this.repaint(); 
    } 
} 

스레드 무승부 모양에 대한

public class DrawThread implements Runnable { 
    private static final int THREAD_SLEEP = 100; 
    private CustomShape shape; 
    private Graphics2D g2d; 
    private boolean interrupted = false; 

    public DrawThread(CustomShape shape, Graphics g) { 
     this.shape = shape; 
     this.g2d = (Graphics2D)g; 
    } 

    @Override 
    public void run() { 
     while (true) { 
      try { 
       Thread.sleep(THREAD_SLEEP); 
       g2d.setColor(this.shape.getColor()); 
       g2d.draw(this.shape.getShape()); 
      } catch (InterruptedException e) { 
       System.out.println(String.format("interrupt %s", Thread 
         .currentThread().getName())); 
       interrupted = true; 
      } finally { 
       if (interrupted) 
        break; 
       } 
     } 
    } 
} 
+0

당신은 운동 기능의 다시 그리기 통화를 놓쳤다 : 여기

enter image description here

move rect는 코드입니다. – zeller

+0

스레드의 구성 요소를 다시 그립니다. 왜'this.shape.getBounds(). setLocation (newLocation);'가 위치를 변경하지 않는가? – BILL

+0

addShape 및 removeShape에있는 것들을 제외하고는 다시 그리기 호출을 볼 수 없지만 당신 말이 옳았는데 눈치 채지 못했습니다. 이 질문을보십시오 : http://stackoverflow.com/questions/3695673/why-doesnt-setlocation-move-my-label 아마도 도움이 될 것입니다. – zeller

답변

1

이 코드는 SSCCE를 게시하는 것이 더 어렵 기 때문에 버그를 찾기가 어렵습니다. 그러나 여기 화살표 키를 사용하여 모양을 이동할 수있는 방법을 보여주는 샷이 있습니다. JApplet은 마우스 클릭. 화살표 키를 사용하지 않으려면 마우스 동작을 구현할 수 있습니다. 더 나은 이해를 위해 프로그램에서 comments을 참조하십시오.

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


public class EgToMove extends JApplet 
       implements KeyListener, FocusListener, MouseListener { 

static final int SQUARE_SIZE = 40; 
int squareTop, squareLeft; 

boolean focussed = false; 
DisplayPanel canvas; 

public void init() { 


    squareTop = getSize().height/2 - SQUARE_SIZE/2; 
    squareLeft = getSize().width/2 - SQUARE_SIZE/2; 


    canvas = new DisplayPanel(); 
    setContentPane(canvas);  

    canvas.setBackground(Color.BLACK); 
    canvas.addFocusListener(this); // Set up the applet to listen for events 
    canvas.addKeyListener(this); 
    canvas.addMouseListener(this); 

    } 

public void keyTyped(KeyEvent e) { 
    //do nothing, if u want something 
} 

class DisplayPanel extends JPanel { 

    public void paintComponent(Graphics g) { 

    super.paintComponent(g); 

    if (focussed) 
     g.setColor(Color.cyan); 
    else 
     g.setColor(Color.lightGray); 

    int width = getSize().width; 
    int height = getSize().height; 
    g.drawRect(0,0,width-1,height-1); 
    g.drawRect(1,1,width-3,height-3); 
    g.drawRect(2,2,width-5,height-5); 
    g.fillRect(squareLeft, squareTop, SQUARE_SIZE, SQUARE_SIZE); 



    if (!focussed) { 
     g.setColor(Color.magenta); 
     g.drawString("Click to activate",7,20); 
    } 
    } 
    } 

    // --------- Event handling methods 

    public void focusGained(FocusEvent evt) { 

    focussed = true; 
    canvas.repaint(); // redraw with cyan border ///may b u had problem here 
    } 

    public void focusLost(FocusEvent evt) { 

    focussed = false; 
    canvas.repaint(); // redraw without cyan border///may b u had problem here 
    } 



    public void keyPressed(KeyEvent evt) { 


    int key = evt.getKeyCode(); // keyboard code for the key that was pressed 

    if (key == KeyEvent.VK_LEFT) { 
    squareLeft -= 8; 
    if (squareLeft < 3) 
     squareLeft = 3; 
    canvas.repaint(); 
    } 
    else if (key == KeyEvent.VK_RIGHT) { 
    squareLeft += 8; 
    if (squareLeft > getSize().width - 3 - SQUARE_SIZE) 
     squareLeft = getSize().width - 3 - SQUARE_SIZE; 
    canvas.repaint(); 
    } 
    else if (key == KeyEvent.VK_UP) { 
    squareTop -= 8; 
    if (squareTop < 3) 
     squareTop = 3; 
    canvas.repaint(); 
    } 
    else if (key == KeyEvent.VK_DOWN) { 
    squareTop += 8; 
    if (squareTop > getSize().height - 3 - SQUARE_SIZE) 
     squareTop = getSize().height - 3 - SQUARE_SIZE; 
    canvas.repaint(); 
    } 

    } 


public void keyReleased(KeyEvent evt) { 
    // empty method, required by the KeyListener Interface 
} 


public void mousePressed(MouseEvent evt) { 
    // Request that the input focus be given to the 
    // canvas 
    canvas.requestFocus(); 
} 


public void mouseEntered(MouseEvent evt) { } 
public void mouseExited(MouseEvent evt) { } 
public void mouseReleased(MouseEvent evt) { } 
public void mouseClicked(MouseEvent evt) { } 


} 
+0

고맙습니다. 나는 원리를 잘못 그리는 나의 방법을 이해했다. 윌 재작 성. – BILL