Spec-Zone .ru
спецификации, руководства, описания, API
След: Создание GUI С JFC/Swing
Урок: Выполнение Пользовательского Рисования
Создание Демонстрационного Приложения (Шаг 3)
Домашняя страница > Создание GUI С JFC/Swing > Выполнение Пользовательского Рисования

Создание Демонстрационного Приложения (Шаг 3)

Наконец, мы добавим, что код обработки событий к programatically перекрашивает компонент всякий раз, когда пользователь щелкает или перетаскивает мышь. Чтобы сохранить наше пользовательское рисование настолько эффективным насколько возможно, мы отследим координаты мыши и перекрасим только области экрана, которые изменились. Это - рекомендуемая передовая практика, которая сохранит Ваше приложение, работающее настолько эффективно насколько возможно.

Завершенное приложение, показывая красный квадрат с черной границей

Завершенное Приложение

Рисунок 3: Завершенное Приложение

Нажмите кнопку Launch, чтобы работать, SwingPaintDemo3, используя Сеть Java™ Запускаются (загрузите JDK 6 или позже). Альтернативно, чтобы скомпилировать и выполнить пример самостоятельно, консультируйтесь, пример индексируют.

Запускает пример SwingPaintDemo3
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 не будет перекрашивать компонент дважды подряд, даже если, именно это код, кажется, делает.

Упражнения:

  1. Прокомментируйте первый вызов перекрашивания и отметьте то, что происходит, когда Вы щелкаете или перетаскиваете мышь. Поскольку та строка ответственна за заполнение в фоновом режиме, следует заметить, что все квадраты остаются на экране после того, как они красятся.
  2. С многократными квадратами на экране минимизируйте и восстановите фрейм приложения. Что происходит? Следует заметить, что действие максимизации экрана заставляет систему полностью перекрашивать компонентную поверхность, которая сотрет все квадраты кроме текущего.
  3. Прокомментируйте оба вызова перекрашивания, и добавьте строку в конце paintComponent метода, чтобы вызвать версию нулевого аргумента перекрашивания вместо этого. Приложение, будет казаться, будет восстановлено его исходному поведению, но рисование теперь будет менее эффективным, так как вся площадь поверхности компонента теперь красится. Можно заметить медленнее performace, особенно если приложение максимизируется.

Проблемы с примерами? Попытайтесь Компилировать и Выполнить Примеры: FAQ.
Жалобы? Поздравление? Предложения? Дайте нам свою обратную связь.

Предыдущая страница: Создание Демонстрационного Приложения (Шаг 2)
Следующая страница: Совершенствование Проекта