【问题标题】:JPanel repaint from another classJPanel 从另一个类重绘
【发布时间】:2012-08-11 21:50:24
【问题描述】:

我有一个显示图像的 JPanel。在一个单独的类中,我从一个 xml 文件点读取。我首先从这些点创建一个三角形的数组列表。但是我需要在图像上显示三角形,即绘制它们! (是的,这应该很简单)。但是由于这些点和三角形是在另一个类中创建的,我似乎无法在 GUI 类中已经显示的图像上绘制它们。我尝试在 JPanel 本身中创建一个 ArrayList,我对其进行更新然后想要重新绘制,尽管它不会让我这样做,如下所示:

triangles = clips.getTriangles();
tempPanel.setTriangles(triangles){

JPanel

 public void settriangles(ArrayList<Point[]> t){
 triangles = t;
 repaint();
}

我唯一的另一个想法是让 JPanel 有一个侦听器等待返回三角形,更新字段,然后重新绘制。

有什么想法吗?

谢谢

编辑:绘图代码

public void settriangles(ArrayList<Point[]> t){
    triangles = t;
    repaint();
}

public void paintComponent(Graphics g) {

    System.out.println("in paint component");
if (g != null) {
    Graphics2D graphics = (Graphics2D) g;
    try {
        Rectangle back_rect = new Rectangle(0, 0, getWidth(),
                getHeight());
        graphics.setColor(GuiComponentGenerator.GUI_BACKGROUND_COLOUR);
        graphics.fill(back_rect);
        if (image != null) {
            int width = Math.round(image.getWidth() * magnification);
            int height = Math.round(image.getHeight() * magnification);
            Rectangle image_rect = new Rectangle(offset.x, offset.y,
                    width, height);
            graphics.setColor(Color.BLACK);
            graphics.draw(image_rect);
            graphics.drawImage(image, offset.x, offset.y, width,
                    height, null);
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            for(int pos = 0; pos < triangles.size(); pos++){
                Point[] current = triangles.get(pos);                   
                ArrayList<Point> current_triangle = new ArrayList<Point>();
                current_triangle.add(current[0]);
                current_triangle.add(current[1]);
                current_triangle.add(current[2]);
                drawRegion(graphics, current_triangle); 
            }
        }
    }

finally {
        graphics.dispose();
}
}



private void drawRegion(Graphics2D graphics, ArrayList<Point> points) {
    graphics.setColor(trans_grey);
    Area area = getArea(points);
    graphics.fill(area);
    graphics.setStroke(new BasicStroke(2));
    graphics.setColor(Color.BLACK);
    graphics.draw(area);
}

private Area getArea(ArrayList<Point> points) {
    Area area = new Area(getPath(points, true));
    return area;
}

private GeneralPath getPath(ArrayList<Point> points, boolean close_path) {
    GeneralPath path = new GeneralPath();
    Point current_screen_point = calculateScreenPoint(points.get(0));
    path.moveTo(current_screen_point.x, current_screen_point.y);
    for (int point_num = 1; point_num < points.size(); point_num++) {
        current_screen_point = calculateScreenPoint(points.get(point_num));
        path.lineTo(current_screen_point.x, current_screen_point.y);
    }
    if (close_path)
        path.closePath();
    return path;
}

public Point calculateScreenPoint(Point image_point) {
    float h_proportion = (float) image_point.x / (float) image.getWidth();
    float v_proportion = (float) image_point.y / (float) image.getHeight();
    float image_width_in_panel = (float) image.getWidth() * magnification;
    float image_height_in_panel = (float) image.getHeight() * magnification;

    Point on_screen_point = new Point(0, 0);
    on_screen_point.x = offset.x
            + Math.round(h_proportion * image_width_in_panel);
    on_screen_point.y = offset.y
            + Math.round(v_proportion * image_height_in_panel);
    return on_screen_point;
}

【问题讨论】:

  • 你在哪里明确地画它们?
  • 你是怎么画的?作为图像或直接到 Graphics2D
  • @MimiEAM 我直接使用 Graphics2D 在 JPanel 中显式绘制它们,因此我更新了 JPanel 中的三角形,然后需要以某种方式使用重绘
  • @redrubia 向我们展示你绘制它们的代码
  • @MimiEAM 已添加!感谢您的帮助!

标签: java swing drawing jpanel paintcomponent


【解决方案1】:

您的paintComponent 有一些不足之处;)

首先,除非paint 方法被正确调用,否则你永远不应该得到一个空图形,以防它们失败。

您应该尝试使用Graphics.create 创建传入Graphics 上下文的副本。这使您可以在不影响原始属性的情况下弄乱Graphics 属性(例如转换等)

我不知道image 是什么意思,但基本上,如果是null,你的三角形将永远不会绘制(不知道这是否是你想要的)。

我不知道offset 与什么有关,但以防万一,0x0 点始终是组件的左上角。

public void paintComponent(Graphics g) {

    // This is important, you will to have a very good reason not to call this
    super.paintComponent(g);

    System.out.println("in paint component");
    // Should never need this.  You should never call the paintComponent
    // directly.
    // if (g != null) {
    // Create a copy of the graphics, with which you can play...
    Graphics2D graphics = (Graphics2D) g.create();
    try {
        Rectangle back_rect = new Rectangle(0, 0, getWidth(),
                        getHeight());
        graphics.setColor(Color.GREEN);
        graphics.fill(back_rect);
        // What's this trying to do...
        // Where do you produce this???
        // Because I didn't know where the image was been produced
        // I commented out the code, but you should be aware
        // That if the image is null, you triangles will never paint...
//            if (image != null) {
//                int width = Math.round(image.getWidth() * magnification);
//                int height = Math.round(image.getHeight() * magnification);
//                
//                Rectangle image_rect = new Rectangle(offset.x, offset.y,
//                                width, height);
//                graphics.setColor(Color.BLACK);
//                graphics.draw(image_rect);
//                graphics.drawImage(image, offset.x, offset.y, width,
//                                height, null);
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
            for (int pos = 0; pos < triangles.size(); pos++) {
                Point[] current = triangles.get(pos);
                ArrayList<Point> current_triangle = new ArrayList<Point>(3);
                current_triangle.add(current[0]);
                current_triangle.add(current[1]);
                current_triangle.add(current[2]);
                drawRegion(graphics, current_triangle);
            }
        //} // From the image != null
    } finally {
        graphics.dispose();
    }
}

我也建议你通读一遍

如果你还没有;)

【讨论】:

  • 谢谢!看起来好多了,但我的问题是另一个类需要更新图像面板,从而使三角形绘制在上面!启动时,图像正在此面板中生成并显示(这部分有效:))
  • 如果需要叠加,请将此面板设置为透明(setOpaque(false))
【解决方案2】:

本文将为您提供所需的所有信息http://java.sun.com/products/jfc/tsc/articles/painting/

但我认为你不见了—— super.paintComponent(g);

public class MyPanel extends JPanel {
    protected void paintComponent(Graphics g) {
    // Let UI delegate paint first 
    // (including background filling, if I'm opaque)
    super.paintComponent(g); 
    // paint my contents next....
    }
}

【讨论】:

    【解决方案3】:

    当通过arrayList时,我研究了如何在图像上绘制三角形,其中每个Point[]代表三角形的点。

    请注意,这现在是在传递信息的单个完整类中,而不是尝试从另一个类调用重绘。

    public AnnotatedDisplayTriangles(BufferedImage image, String image_path, ArrayList<Point[]> triangles) {
    
        this.image = image;
        this.image_path = image_path;
        this.triangles = triangles;
    
    }
    
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // Draw image centered.
        int x = (getWidth() - image.getWidth())/2;
        int y = (getHeight() - image.getHeight())/2;
        g.drawImage(image, x, y, this);
    
        Stroke drawingStroke = new BasicStroke(2);
        Graphics2D graph = (Graphics2D)g;
        graph.setStroke(drawingStroke);
        graph.setPaint(Color.black);
    
    
        for(int p = 0; p < triangles.size(); p++){
    
            Point[] current_triangles = triangles.get(p);
    
            for(int triangle = 0; triangle < current_triangles.length; triangle++ ){
    
                Point current = current_triangles[triangle];
                Point next;
                if(triangle == current_triangles.length -1 )
                    next = current_triangles[0];
                else
                    next = current_triangles[triangle + 1];
    
                Line2D line = new Line2D.Double(current.x, current.y, next.x, next.y);
                graph.draw(line);
    
            }
        }
    }
    
    public static void main(String image_path,ArrayList<Point[]> triangles, String panel_name) throws IOException {
        String path = image_path;
        BufferedImage image = ImageIO.read(new File(path));
        AnnotatedDisplayTriangles contentPane = new AnnotatedDisplayTriangles(image, path, triangles);
        // You'll want to be sure this component is opaque
        // since it is required for contentPanes. Some
        // LAFs may use non-opaque components.
        contentPane.setOpaque(true);
    
        int w = image.getWidth();
        int h = image.getHeight();
    
        JFrame f = new JFrame(panel_name);
    //  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(contentPane);
        f.setSize(w,h);
        f.setLocation(200,200);
        f.setVisible(true);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多