Spec-Zone .ru
спецификации, руководства, описания, API
|
В демонстрационных целях имеет смысл сохранять логику рисования полностью содержавшей в пределах MyPanel
class. Но если Ваше приложение должно будет отследить многократные экземпляры, один образец, который Вы могли использовать, должен факторизовать тот код в отдельный class так, чтобы каждый квадрат мог быть обработан как отдельный объект. Этот метод распространен в 2-D игровом программировании и иногда упоминается как "анимация спрайта."
Нажмите кнопку Launch, чтобы работать, SwingPaintDemo4, используя Сеть Java™ Запускаются (
package painting; import javax.swing.SwingUtilities; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.BorderFactory; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseMotionListener; import java.awt.event.MouseMotionAdapter; public class SwingPaintDemo4 { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } private static void createAndShowGUI() { System.out.println("Created GUI on EDT? "+ SwingUtilities.isEventDispatchThread()); JFrame f = new JFrame("Swing Paint Demo"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new MyPanel()); f.setSize(250,250); f.setVisible(true); } } class MyPanel extends JPanel { RedSquare redSquare = new RedSquare(); public MyPanel() { setBorder(BorderFactory.createLineBorder(Color.black)); addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent e){ moveSquare(e.getX(),e.getY()); } }); addMouseMotionListener(new MouseAdapter(){ public void mouseDragged(MouseEvent e){ moveSquare(e.getX(),e.getY()); } }); } private void moveSquare(int x, int y){ // Current square state, stored as final variables // to avoid repeat invocations of the same methods. final int CURR_X = redSquare.getX(); final int CURR_Y = redSquare.getY(); final int CURR_W = redSquare.getWidth(); final int CURR_H = redSquare.getHeight(); final int OFFSET = 1; if ((CURR_X!=x) || (CURR_Y!=y)) { // The square is moving, repaint background // over the old square location. repaint(CURR_X,CURR_Y,CURR_W+OFFSET,CURR_H+OFFSET); // Update coordinates. redSquare.setX(x); redSquare.setY(y); // Repaint the square at the new location. repaint(redSquare.getX(), redSquare.getY(), redSquare.getWidth()+OFFSET, redSquare.getHeight()+OFFSET); } } public Dimension getPreferredSize() { return new Dimension(250,200); } public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("This is my custom Panel!",10,20); redSquare.paintSquare(g); } } class RedSquare{ private int xPos = 50; private int yPos = 50; private int width = 20; private int height = 20; public void setX(int xPos){ this.xPos = xPos; } public int getX(){ return xPos; } public void setY(int yPos){ this.yPos = yPos; } public int getY(){ return yPos; } public int getWidth(){ return width; } public int getHeight(){ return height; } public void paintSquare(Graphics g){ g.setColor(Color.RED); g.fillRect(xPos,yPos,width,height); g.setColor(Color.BLACK); g.drawRect(xPos,yPos,width,height); } }
В этой определенной реализации мы создали a RedSquare
class полностью с нуля. Другой подход должен был бы снова использовать functionlity java.awt.Rectangle
делая RedSquare
подкласс этого. Независимо от как RedSquare
реализуется, важный момент - то, что мы дали class метод, который принимает a Graphics
объект, и тот метод вызываются от панели paintComponent
метод. Это разделение содержит Ваш код в чистоте, потому что это по существу говорит каждому красному квадрату красить себя.