2010-09-15 20 views
2

Я хотел бы иметь возможность рисовать Image сек на JFrame, но всякий раз, когда я хочу (не в методе JFrame.paint.Как рисовать графики за пределами функции краски() в JFrame

Для проекта I Я работаю, у меня есть class Bullseye extends BufferedImage, и я пытаюсь поставить его на JFrame:.

class DrawingFrame extends JFrame { 
    public void drawImage(Image img, int x, int y) { 
     getGraphics().drawImage(img,x,y,null); 
     repaint(); 
    } 
} 

class Main { 
    public static void main(String[] args) { 
     DrawingFrame frame = new DrawingFrame(); 
     Bullseye bullseye = new Bullseye(20,20); //width,height 

     // later 
     frame.setVisible(true); 
     frame.drawImage(bullseye,10,20); 
     frame.drawImage(bullseye,20,20); 
     frame.drawImage(bullseye,30,20); 
    } 
} 

Однако ничто не обнаруживается После некоторых исследований, по-видимому, это не работает, потому что изменения в graphics объекта получить очищается, когда я repaint().

Как это сделать? Это даже правильный подход?

+0

Могу ли я спросить вас, почему не в краске? – mhshams

+0

Потому что я хочу произвольно добавить 'Images' извне. Когда я переопределяю 'paint', я плотно соединяю' JFrame' с 'Images', которые хочу добавить. –

ответ

1

Рисование на экран в Java (почти) всегда выполняется в paint(). Что вам нужно для вашего класса:

class DrawingFrame extends JFrame { 

    private Image bullseye = new Bullseye(20,20); //width,height 


    public void paint(Graphics g) { 
     g.drawImage(bullseye,10,20); 
     g.drawImage(bullseye,20,20); 
     g.drawImage(bullseye,30,20); 
    } 

} 

class Main { 
    public static void main(String[] args) { 
     DrawingFrame frame = new DrawingFrame(); 

     // later 
     frame.setVisible(true); 
    } 
} 

Если вам нужно повернуть на чертеже bullseyes в определенное время, создать флаг на объекте DrawingFrame, и установить его, когда вы нуждаетесь в них. Вам нужно будет вызвать repaint(), когда флаг установлен.

4

Я думаю, что вы берете проблему в обратном направлении. В Swing все операции рисования должны выполняться в методе paint().

Что вы можете сделать, это сохранить изображение, которое вы хотите нарисовать в качестве атрибута в своем классе, а затем в своем методе боли нарисуйте изображение, где хотите. Например:

class MyFrame extends JFrame { 

    Image image; 

    public void paint(Graphics g) { 
     super.paint(g); 
     if (image != null) { 
      g.drawImage(image, /* ... */); 
     } 
    } 

    public void setImage(Image image) { 
     this.image = image; 
     repaint(); 
    } 

} 

И в вашем другом классе:

myFrame.setImage(myImage); 
+0

Проблема заключается в том, что я хочу иметь возможность добавлять много изображений в различные (x, y) координаты. С помощью этого метода я могу только сделать это. Я мог бы сделать так, чтобы он «ставил очереди» на изображения, чтобы рисовать в определенных координатах во время следующего вызова краски, но это кажется излишним. –

+2

Если вам нужно больше изображений, вы можете заменить атрибут 'image' на' List '. Но если вы хотите рисовать непосредственно в JFrame, вы должны переопределить метод 'paint()'. –

1

Как о создании закадрового изображения для рисования в то время как за пределами фактической краски, а затем фактическая краска просто рисует закадровое изображение к фактическому графика? Какая-то двойная буферизация?

1

Индивидуальная окраска должна быть когда-либо сделана в методе paint(), особенно в методе paint() для JFrame. Пользовательская покраска выполняется путем переопределения метода paintComponent() компонента Swing, как правило, JComponent или JPanel. Прочтите раздел из учебника Swing по телефону Custom Painting для получения дополнительной информации и рабочих примеров.

Однако, в этом случае вам не нужно делать какие-либо индивидуальные работы. Вы просто создаете ImageIcon и добавляете значок в JLabel, затем добавляете JLabel на панель. Прочтите раздел из учебника Swing по How to Use Icons для рабочих примеров.

Если вы не можете найти подходящий менеджер компоновки, вы также можете использовать абсолютное позиционирование. Снова вы найдете раздел в руководстве по использованию менеджеров компоновки, который объясняет это более подробно.

1

Создайте графический объект в своем классе, для которого он должен иметь глобальное, а не только локальное существование метода.

public class Graphics2D freefrompaint = null; 

Тогда также имеют логическое значение для потока из-под контроля целей:

private boolean heypaintreturnnow = false; 

и переопределить метод обновления при условии Swing компонента суперкласса() asfollows:

public void update(Graphics g) { 
    if (heypaintreturnnow) return; 
    freefrompaint = (Graphics2D)g; 
    heypaintreturnnow = true; /*and if you want, do => super.update(?) once, or once after boolean hereof is set to false by your code. */ 

Update() очищает весь цвет в буфере неактивных графических данных до текущего цвета фона в GraphicsObject. И вы также должны знать точные три метода, выполняемые внутри краски Swing Components():

(1) он называет свою собственную paintComponent(), здесь делегируется фактическая роспись такого Компонента;

(2) метод покраски его границ; а затем последняя - картина его дочернего Компонента. Последнее очень важное и неизбежное: используйте класс, вложенный, именованный или анонимный, с помощью этого метода Overriden Container. И передайте этот класс методу setContentPane (Container actualgraphicsreference) JFrame; это обязательно. Надеюсь, что я сделал свой объяснительный и информативный подход однозначным. Понятно, что теперь вы можете использовать freefrompaint для рисования за пределами, а вызов операционной системы к repaint() вашей системы не будет вызывать операцию «растрового разметки» по умолчанию «двойная графика», которую теперь вы подавляете при переходе к коду, как я выше инструктирует и рекомендует вам. Благодарим вас за выразительную возможность.

Смежные вопросы