Spec-Zone .ru
спецификации, руководства, описания, API
|
Наконец, мы добавим, что код обработки событий к programatically перекрашивает компонент всякий раз, когда пользователь щелкает или перетаскивает мышь. Чтобы сохранить наше пользовательское рисование настолько эффективным насколько возможно, мы отследим координаты мыши и перекрасим только области экрана, которые изменились. Это - рекомендуемая передовая практика, которая сохранит Ваше приложение, работающее настолько эффективно насколько возможно.
Завершенное Приложение
Нажмите кнопку Launch, чтобы работать, SwingPaintDemo3, используя Сеть 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 SwingPaintDemo3 { 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.pack(); f.setVisible(true); } } class MyPanel extends JPanel { private int squareX = 50; private int squareY = 50; private int squareW = 20; private int squareH = 20; 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) { int OFFSET = 1; if ((squareX!=x) || (squareY!=y)) { repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET); squareX=x; squareY=y; repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET); } } public Dimension getPreferredSize() { return new Dimension(250,200); } protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("This is my custom Panel!",10,20); g.setColor(Color.RED); g.fillRect(squareX,squareY,squareW,squareH); g.setColor(Color.BLACK); g.drawRect(squareX,squareY,squareW,squareH); } }
Это изменение первый импорт различные классы мыши от java.awt.event
пакет, подавая заявку, способную к отвечанию на действие мыши пользователя. Конструктор был обновлен, чтобы зарегистрировать слушателей события для щелчков мышью и перетаскивает. Всякий раз, когда a MouseEvent
полученный, это передается moveSquare
метод, который обновляет координаты квадрата и перекрашивает компонент интеллектуальным способом. Отметьте, что по умолчанию, любой код, который помещается в пределах этих обработчиков событий, будет выполняться на Событии, Диспетчеризируют Поток.
Но самое важное изменение является вызовом repaint
метод. Этот метод определяется java.awt.Component
и механизм, который позволяет, Вы к programatically перекрашиваете поверхность любого данного компонента. У этого есть версия без аргументов (который перекрашивает весь компонент), и версия мультиаргумента (который перекрашивает только указанную область.) Эта область также известна как клип. Вызов версии мультиаргумента repaint
берет небольшое дополнительное усилие, но гарантирует, что Ваш код рисования не будет тратить впустую циклы, перекрашивающие области экрана, которые не изменились.
Поскольку мы вручную устанавливаем клип, наш moveSquare
метод вызывает метод перекрашивания не однажды, но дважды. Первый вызов говорит Swing перекрашивать область компонента, где квадрат ранее был (наследованное поведение использует Делегата UI, чтобы заполнить ту область текущим цветом фона.) Второй вызов красит область компонента, где квадрат в настоящий момент. Замечание ценности важного момента состоит в том, что, хотя мы вызвали перекрашивание дважды подряд в том же самом обработчике событий, Swing достаточно умен, чтобы взять ту информацию и перекрасить те разделы экрана все в одной единственной работе краски. Другими словами Swing не будет перекрашивать компонент дважды подряд, даже если, именно это код, кажется, делает.
Упражнения: