Graphics2D и JComponent - PullRequest
       23

Graphics2D и JComponent

3 голосов
/ 28 ноября 2011

Я не очень много использовал Swing / G2D, поэтому, пожалуйста, будьте терпеливы. У меня есть следующий класс, который является компонентом моего GUI (предназначенного для рисования на холсте):

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

public class DrawPanel extends JComponent{
public void paintComponent(Graphics g){
    Graphics2D g2 = (Graphics2D) g;

    g2.setPaint(Color.black);
    g2.fillRect(0, 0, getWidth(), getHeight());

    BrushStroke bs = new BrushStroke();     
    add(bs);
}
}

Я пытался добавить следующее к вышеуказанному JComponent:

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

public class BrushStroke extends JComponent{
public void paintComponent(Graphics g){
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);

    g2.setPaint(Color.red);
    g2.fillOval(0, 0, 10, 10);          
}
}

BrushStroke не отображается на DrawPanel.

Я всегда искал ответ, и каждый пример, на который я смотрю, кажется противоречивым.

Если бы кто-нибудь попытался сделать то, что я есть, то помощь будет принята с благодарностью. Кроме того, если я принимаю совершенно неправильный подход, пожалуйста, скажите.

Ответы [ 2 ]

3 голосов
/ 29 ноября 2011
  1. Никогда не добавляйте компонент на панель любым способом рисования.Методы рисования вызываются всякий раз, когда Swing определяет, что компонент должен быть нарисован.Поэтому вы добавляете компонент на панель несколько раз.

  2. Когда вы выполняете произвольное рисование, вы отвечаете за переопределение метода getPreferredSize (), чтобы задать размер компонента.Таким образом, менеджеры по расположению могут правильно расположить компоненты.Если вы этого не сделаете, тогда предпочтительный размер будет 0, поэтому рисовать нечего.

Прочитайте раздел из учебника Swing по Custom Painting длябольше информации и примеров.

2 голосов
/ 29 ноября 2011

В методе JComponent.add документация гласит:

Примечание. Если компонент был добавлен в отображаемый контейнер, необходимо вызвать validateэтот контейнер для отображения нового компонента.Если добавляется несколько компонентов, вы можете повысить эффективность, вызвав команду validate только один раз после добавления всех компонентов.

Вы должны обновить DrawPanel после добавления в него элемента.Остерегайтесь не делать этого в методе painComponent, вы окажетесь в бесконечной рекурсии.

Вместо этого выполните следующее:

DrawPanel drawPanel = new DrawPanel();
drawPanel.add(new BrushStroke());
drawPanel.repaint();

РЕДАКТИРОВАТЬ Здесьявляется полностью рабочим решением (расширение JPanels вместо JComponent)

public static void main(String[] args){
   JFrame frame = new JFrame();
   DrawPanel drawPanel = new DrawPanel();
   drawPanel.add(new BrushStroke());
   frame.getContentPane().add(drawPanel);
   frame.pack();
   frame.setVisible(true);
}
class DrawPanel extends JPanel{
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setPaint(Color.black);
        g2.fillRect(0, 0, getWidth(), getHeight());
    }
    @Override
    public  Dimension getPreferredSize(){
        return new Dimension(100, 100);
    }
}
class BrushStroke extends JPanel{
    public void paintComponent(Graphics g){
        this.setOpaque(false);
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.red);
        g2.fillOval(0, 0, 10, 10); 
    }
    @Override
    public  Dimension getPreferredSize(){
        return new Dimension(10, 10);
    }
}

Вывод дает следующее:

enter image description here

...