2015-06-24 2 views
2

Я прочитал много руководств по рисованию компонентов Graphics2D и добавлению к JPanel/JFrame, но я не могу найти, как просто добавить несколько этих компонентов в один JPanel. Мой код ниже добавляет только 1 компонент (строка), и я не могу найти, почему невозможно добавить больше.Рисование нескольких компонентов graphic2d в JPanel

Что я делаю неправильно?

enter image description here

Желаемая поведение: должно быть 3 красные линии.

Мой весь код:

package Examples; 

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import javax.swing.BorderFactory; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Example1 extends JFrame { 

    private final JPanel panel; 

    public Example1() { 

     // jpanel with graphics 
     panel = new JPanel(); 
     panel.setPreferredSize(new Dimension(200, 200)); 
     panel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
     panel.setBackground(Color.WHITE); 
     add(panel); 


     // adding lines to jpanel 
     AddMyLine(); // 1st: this works well 
     AddMyLine(); // 2nd: this doesn't work 
     AddMyLine(); // 3rd: this doesn't work 


     setLayout(new FlowLayout(FlowLayout.LEFT)); 
     setSize(250, 250); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setVisible(true); 
     setLocationRelativeTo(null); 
    } 


    // add new line to jpanel 
    private void AddMyLine() { 
     MyLine c = new MyLine(); 
     System.out.println(c); 
     panel.add(c); 
    } 



    // line component 
    private class MyLine extends JComponent { 

     public MyLine() { 
      setPreferredSize(new Dimension(200, 200)); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D)g; 
      g2d.setColor(Color.red); 
      g2d.setStroke(new BasicStroke(1)); 
      int x1 = (int)Math.round(Math.random()*200); 
      int y1 = (int)Math.round(Math.random()*200); 
      int x2 = (int)Math.round(Math.random()*200); 
      int y2 = (int)Math.round(Math.random()*200); 
      g2d.drawLine(x1,y1,x2,y2); 
     } 
    } 


    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Example1(); 
      } 
     });  

    } 
} 

ответ

3

Ваш класс MyLine не должен быть компонентом свинг и, следовательно, не должны распространяться JComponent. Скорее, он должен быть логическим сущностью и на самом деле может быть тем, что реализует Shape, например Line2D, или может быть вашим собственным полным классом, но должен знать, как рисовать себя, т. Е. Если он не реализует Shape, тогда он должен имеют некоторый тип метода draw(Graphics2D g), который могут вызвать другие классы. Я думаю, вместо этого вы должны работать над расширением класса JPanel вашей панели, чтобы вы переопределили его метод paintComponent, дайте ему коллекцию для хранения любых элементов MyLine, добавленных к ней, и нарисуйте элементы MyLine в paintComponent.

Другие варианты включают чертеж непосредственно на BufferedImage, а затем отображение этого BufferedImage в методе paintComponent JPanel. Это отлично подходит для статических изображений, но не подходит для изображений, которые необходимо изменить или переместить.

например,

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Line2D; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.*; 

public class DrawChit extends JPanel { 
    private static final int PREF_W = 500; 
    private static final int PREF_H = PREF_W; 
    private List<Shape> shapes = new ArrayList<>(); 

    public DrawChit() { 
     setBackground(Color.white); 
    } 

    public void addShape(Shape shape) { 
     shapes.add(shape); 
     repaint(); 
    } 

    @Override // make it bigger 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
     return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     for (Shape shape : shapes) { 
     g2.draw(shape); 
     } 
    } 

    private static void createAndShowGui() { 
     DrawChit drawChit = new DrawChit(); 

     drawChit.addShape(new Line2D.Double(10, 10, 100, 100)); 
     drawChit.addShape(new Ellipse2D.Double(120, 120, 200, 200)); 

     JFrame frame = new JFrame("DrawChit"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(drawChit); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

Или пример, используя мой собственный MyDrawable класс, который производит графический интерфейс, который выглядит следующим образом:

enter image description here

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.Stroke; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Line2D; 
import java.awt.geom.Rectangle2D; 
import java.awt.geom.RoundRectangle2D; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

@SuppressWarnings("serial") 
public class DrawChit extends JPanel { 
    private static final int PREF_W = 600; 
    private static final int PREF_H = PREF_W; 
    private List<MyDrawable> drawables = new ArrayList<>(); 

    public DrawChit() { 
     setBackground(Color.white); 
    } 

    public void addMyDrawable(MyDrawable myDrawable) { 
     drawables.add(myDrawable); 
     repaint(); 
    } 

    @Override 
    // make it bigger 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
     return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     for (MyDrawable myDrawable : drawables) { 
     myDrawable.draw(g2); 
     } 
    } 

    public void clearAll() { 
     drawables.clear(); 
     repaint(); 
    } 

    private static void createAndShowGui() { 
     final List<MyDrawable> myDrawables = new ArrayList<>(); 
     myDrawables.add(new MyDrawable(new Line2D.Double(100, 40, 400, 400), 
      Color.red, new BasicStroke(40))); 
     myDrawables.add(new MyDrawable(new Ellipse2D.Double(50, 10, 400, 400), 
      Color.blue, new BasicStroke(18))); 
     myDrawables.add(new MyDrawable(new Rectangle2D.Double(40, 200, 300, 300), 
      Color.cyan, new BasicStroke(25))); 
     myDrawables.add(new MyDrawable(new RoundRectangle2D.Double(75, 75, 490, 450, 40, 40), 
      Color.green, new BasicStroke(12))); 

     final DrawChit drawChit = new DrawChit(); 

     JFrame frame = new JFrame("DrawChit"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(drawChit); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 

     int timerDelay = 1000; 
     new Timer(timerDelay, new ActionListener() { 
     private int drawCount = 0; 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (drawCount >= myDrawables.size()) { 
       drawCount = 0; 
       drawChit.clearAll(); 
      } else { 
       drawChit.addMyDrawable(myDrawables.get(drawCount)); 
       drawCount++; 
      } 
     } 
     }).start(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

class MyDrawable { 
    private Shape shape; 
    private Color color; 
    private Stroke stroke; 

    public MyDrawable(Shape shape, Color color, Stroke stroke) { 
     this.shape = shape; 
     this.color = color; 
     this.stroke = stroke; 
    } 

    public Shape getShape() { 
     return shape; 
    } 

    public Color getColor() { 
     return color; 
    } 

    public Stroke getStroke() { 
     return stroke; 
    } 

    public void draw(Graphics2D g2) { 
     Color oldColor = g2.getColor(); 
     Stroke oldStroke = g2.getStroke(); 

     g2.setColor(color); 
     g2.setStroke(stroke); 
     g2.draw(shape); 

     g2.setColor(oldColor); 
     g2.setStroke(oldStroke); 
    } 

    public void fill(Graphics2D g2) { 
     Color oldColor = g2.getColor(); 
     Stroke oldStroke = g2.getStroke(); 

     g2.setColor(color); 
     g2.setStroke(stroke); 
     g2.fill(shape); 

     g2.setColor(oldColor); 
     g2.setStroke(oldStroke); 
    } 

} 
-1

Ваш код добавляет три компонента, но панель не является достаточно большим, чтобы показать два других компонента

panel.setPreferredSize(new Dimension(200, 600)); 
    setSize(250, 800);