2015-06-24 40 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類不應該是一個Swing組件,因此不應該JComponent的子類。相反,它應該是一個邏輯實體,事實上它可以是實現Shape的東西,比如Line2D,或者可以是你自己的完整類,但應該知道如何繪製自己,也就是說,如果它沒有實現Shape,那麼它應該有其他類可以調用的某種類型的draw(Graphics2D g)方法。相反,我認爲你應該努力擴展你的面板的JPanel類,以便覆蓋它的paintComponent方法,給它一個集合以保存添加到它的任何MyLine項目,並在paintComponent中繪製MyLine項目。

其他選項包括直接繪製到BufferedImage,然後在您的JPanel的paintComponent方法中顯示該BufferedImage。這對靜態圖像非常有用,但對於需要更改或移動的圖像不太有用。

例如,

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);