【问题标题】:Java repaint() not workingJava重绘()不起作用
【发布时间】:2014-01-10 01:43:17
【问题描述】:

我正在制作一个简单的程序来绘制图形和其中的一些点。这些点应该在更改g.fillOval 的坐标时使用方法制作,但实际上它只绘制最后一个点。

代码如下:

import javax.swing.*;
import java.awt.*;
public class PointGraphWriter extends JPanel
{
   JFrame korniza = new JFrame();
   private int x;
   private int y;
   private int length;
   private String OX;
   private String OY;
   private String emri;
   private int y_height;
   private int x_num;

   public PointGraphWriter()
   {
      int width= 500;
      korniza.setSize(width,width);
      korniza.setVisible(true);
      korniza.setTitle(emri);
      korniza.getContentPane().add(this);

   }

   public void paintComponent(Graphics g)
   {
      g.drawLine(x,y,x+length,y);
      g.drawLine(x,y,x,y-length);
      g.drawString(OX,x+length, y+15);
      g.drawString(OY,x-15,y-length);
      g.drawString("0", x -15,y);
      g.drawString("0", x,y+15);
      g.fillOval(x_num,y-y_height-2, 4 ,4);
   }

   public void setTitle(String name)
   {
      emri= name;
      this.repaint();
   }

   public void setAxes(int x_pos, int y_pos, int axis_length, String x_label, String y_label)
   {
      x= x_pos;
      y=y_pos;
      length= axis_length;
      OX = x_label;
      OY = y_label;   
   }

   public void setPoint1(int height)
   {
      y_height=height;
      x_num = x-2;
      this.repaint();
   }

   public void setPoint2(int height)
   {
      y_height=height;
      x_num = x + length/5-2;
      this.repaint();
   }   
}   

这里是主要方法:

public class TestPlot
{
   public static void main(String[] a)
   { 
      PointGraphWriter e = new PointGraphWriter();
      e.setTitle("Graph of y = x*x");
      e.setAxes(50, 110, 90, "5", "30");
      int scale_factor = 3;
      e.setPoint1(0 * scale_factor); 
      e.setPoint2(1 * scale_factor);
   }
}

【问题讨论】:

  • 您需要在一些Collections 中保存坐标 并在Collection 上迭代以每次绘制所有点(一个新点添加到前一个列表)
  • 嗯,我实际上是一个初学者,不知道该怎么做。我只是把这个练习作为我学校的一个项目。 img856.imageshack.us/img856/8932/9n1b.png 这是练习。目前我只使用了 setPoint1 和 setPoint 2 但我无法解决这个问题。
  • 你可以看看这个thread。恐怕,我不能为你做作业。虽然一个小例子很快就会出现......,如果你仍然不清楚这个想法:-)
  • 是的,我只是认为我可以只使用 repaint() 来完成那里的工作,但它似乎不起作用。还是谢谢
  • Swing 组件不能从事件分派线程的任何其他线程中使用。将 main 方法的代码包装在 SwingUtilities.invokeLater() 调用中,一切都会好起来的。 docs.oracle.com/javase/tutorial/uiswing/concurrency/…

标签: java swing repaint


【解决方案1】:

请看一下这个例子。与此类似的东西,您可能必须将其合并到您的示例中才能使其正常工作。只需使用Collection 来存储您之前绘制的内容,当新事物出现时,只需将该事物添加到列表中,然后再次重新绘制整个Collection。如下图:

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;

public class RectangleExample {

    private DrawingBoard customPanel;
    private JButton button;

    private Random random;

    private java.util.List<Rectangle2D.Double> rectangles;

    private ActionListener buttonActions = 
                        new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            Rectangle2D.Double rectangle = new Rectangle2D.Double(
                        (double) random.nextInt(100), (double) random.nextInt(100),
                        (double) random.nextInt(100), (double) random.nextInt(100));
            rectangles.add(rectangle);
            customPanel.setValues(rectangles);
        }
    };

    public RectangleExample() {
        rectangles = new ArrayList<Rectangle2D.Double>();
        random = new Random();
    }   

    private void displayGUI() {
        JFrame frame = new JFrame("Rectangle Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new BorderLayout(5, 5));

        customPanel = new DrawingBoard();
        contentPane.add(customPanel, BorderLayout.CENTER);

        button = new JButton("Create Rectangle");
        button.addActionListener(buttonActions);
        contentPane.add(button, BorderLayout.PAGE_END);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

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

class DrawingBoard extends JPanel {

    private java.util.List<Rectangle2D.Double> rectangles = 
                                new ArrayList<Rectangle2D.Double>();

    public DrawingBoard() {
        setOpaque(true);
        setBackground(Color.WHITE);
    }

    public void setValues(java.util.List<Rectangle2D.Double> rectangles) {
        this.rectangles = rectangles;
        repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        return (new Dimension(300, 300));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Rectangle2D.Double rectangle : rectangles) {
            g.drawRect((int)rectangle.getX(), (int)rectangle.getY(),
                    (int)rectangle.getWidth(), (int)rectangle.getHeight());
        }
        System.out.println("WORKING");
    }
}

【讨论】:

    【解决方案2】:

    请参阅Custom Painting Approaches 了解两种常用绘画方法的示例:

    1. 保留要绘制的对象的列表
    2. 在 BufferedImage 上绘制

    您选择的方法将取决于您的具体要求。

    【讨论】:

      猜你喜欢
      • 2014-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多