2016-02-05 50 views
1

我正在寫一個JApplet,它顯示一個圖表,其中包含圓圈和連接圓圈的行中的數字。我創建了一個擴展JComponent以充當圈子的類。我重寫了paintComponent()方法來繪製一個帶有數字的圓,並且將這些圓放置在我的小程序上,在該小程序上我繪製了paint()方法中的各行。如何繪製一個自定義的圓形JComponent而沒有「隱形框」呢?

但是,如果線條以某個角度碰到圓圈,它們會在圍繞整個JComponent的方形的圓圈之前切出,儘管背景應該是透明的。這在圓周圍形成了一個「看不見的盒子」。

我已經準備了一個小程序來演示這個問題: Example of lines stopping at the "invisible square"

這裏是這個例子的代碼:被抽

import java.awt.*; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Line2D; 

import javax.swing.*; 

public class Circle extends JApplet { 
    private static final long serialVersionUID = 1L; 

    myCircle myC = new myCircle(10, 215, 215); // custom circle 
    Container c; 

    public void init() { 
     setSize(500, 500); 
     c = getContentPane(); 
     c.setLayout(null); 
     c.setBackground(Color.lightGray); 
     c.add(myC); 
    } 

    public void paint(Graphics g) { 
     super.paint(g); 
     Graphics2D g2d = (Graphics2D)g; 
     g2d.setRenderingHint(
       RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setColor(Color.black); 
     g2d.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT,  BasicStroke.JOIN_MITER)); 

     //draw lines 
     g2d.draw(new Line2D.Double(0f, 0f, 500f, 500f)); 
     g2d.draw(new Line2D.Double(0f, 500f, 500f, 0f)); 
     g2d.draw(new Line2D.Double(0f, 250f, 500f, 250f)); 
     g2d.draw(new Line2D.Double(250f, 0f, 250f, 500f)); 
     g2d.draw(new Line2D.Double(150f, 0f, 350f, 500f)); 
     myC.repaint(); // put the circle on top 
    } 

    public class myCircle extends JComponent { 
     private static final long serialVersionUID = 1L; 

     int number; // number to display 

     public myCircle(int num, int x, int y) { 
      this.number = num; 
      this.setLocation(x, y); 
      this.setSize(75, 75); 
     } 

     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D)g; 
      g2d.setRenderingHint(
        RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
      g2d.setRenderingHint(
        RenderingHints.KEY_TEXT_ANTIALIASING, 
        RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
      g2d.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT,  BasicStroke.JOIN_MITER)); 
      g2d.setColor(Color.white); 
      g2d.fill(new Ellipse2D.Float(1f, 1f, 70f, 70f)); 
      g2d.setColor(Color.black); 
      g2d.draw(new Ellipse2D.Float(1f, 1f, 70f, 70f)); 
      g2d.drawString(Integer.toString(number), 15f, 20f); 
     } 
    } 
} 
+0

爲什麼你用draw來代替drawEllipse?有沒有可以使用的東西? – Zymus

回答

2

我不會用組件來表示單獨的圓形狀。相反,只是油漆都放在同一JPanel(我使用JFrame,而不是一個applet的):

enter image description here

public class Circle extends JPanel { 

    int number = 10; 
    float size = 500f; 
    float rad = 70f; 
    float stringLocX = 15f, stringLocy = 20f; 

    public void paintComponent(Graphics g) { 

     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.LIGHT_GRAY); 
     g2d.fillRect(0, 0, getWidth(), getHeight()); 

     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
     g2d.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); 

     g2d.setColor(Color.BLACK); 
     g2d.draw(new Line2D.Double(0f, 0f, size, size)); 
     g2d.draw(new Line2D.Double(0f, size, size, 0f)); 
     g2d.draw(new Line2D.Double(0f, size/2, size, size/2)); 
     g2d.draw(new Line2D.Double(size/2, 0f, size/2, size)); 
     g2d.draw(new Line2D.Double(150f, 0f, 350f, 500f)); 

     Ellipse2D.Float circle = new Ellipse2D.Float((size - rad)/2, (size - rad)/2, rad, rad); 
     g2d.setColor(Color.WHITE); 
     g2d.fill(circle); 
     g2d.setColor(Color.BLACK); 
     g2d.draw(circle); 
     g2d.drawString(Integer.toString(number), (size - rad)/2 + stringLocX, 
         (size - rad)/2 + stringLocy); 
    } 

    @Override 
    public Dimension getPreferredSize() { 

     return new Dimension((int) size, (int) size); 
    } 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(() -> { 
      JFrame frame = new JFrame(); 
      frame.add(new Circle()); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.pack(); 
      frame.setVisible(true); 
     }); 
    } 
} 

取決於你有多少圈都有,他們必須包含什麼樣的數據,你可以只需保留這些數字的列表,然後遍歷painComponent中的列表並繪製它們。

注:

  • 不要使用null佈局。
  • 更好地將硬編碼數字保留爲字段,以便您可以更容易地更改它們,可能使它們變成final
+1

我改變了我的程序,使用BorderLayout和繪製的部分作爲中心的JPanel。我使用JPanel中的paint繪製圖形,並創建一個對象來存儲有關圓圈的數據,而不是JComponents。 – user268639

+0

@ user268639是!這正是我所展示的:) – user1803551

0

你需要看一下線的長度。從你身材的邊緣到圓圈的角度比兩側長。回想一下45度,45度和90度角的三角形,邊長的比例是1:1:sqrt(2)

+0

請查看我的paint()方法。我畫了5條線,每條線的中心位於圓圈下方,所以線條的長度不成問題。 – user268639