2016-02-05 20 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