如何在Swing中重绘而不清除窗口?

时间:2019-04-01 21:30:58

标签: java swing draw

我正在实现一个简单的public interface IAllOurInfo { string[] Errors { get; } } public interface IAllOurInfo<T> : IAllOurInfo { T TheData { get; } } public struct AllOurStringInfo : IAllOurInfo<string> { public string[] Errors { get; private set; } public string TheData { get; private set; } public AllOurStringInfo(string[] errors, string theData) : this() { Errors = errors; TheData = theData; } } public struct AllOurStringArrayInfo : IAllOurInfo<string[]> { public string[] Errors { get; private set; } public string[] TheData { get; private set; } public AllOurStringArrayInfo(string[] errors, string[] theData) : this() { Errors = errors; TheData = theData; } } public IAllOurInfo EvaluateData(dynamic dData) { // Figure out the type of data, call the right class // I am just giving an example here if (dData.GetType() == typeof(string)) { return new AllOurStringInfo(new[] { "Hello" }, "Hello"); } // have no idea what I was given, return null or throw return null; } ,在其中可以像现实生活中的纸和铅笔一样绘制项目,而无需每次绘制对象时都清除整个页面。

我到目前为止所拥有的...

一个Canvas来实现绘图:

Canvas

public class Canvas extends JPanel { private final Random random = new Random(); public Canvas() { setOpaque(false); // I thought setting this flag makes the drawn pixels be preserved... } @Override public Dimension getPreferredSize() { return new Dimension(640, 480); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.drawOval(random.nextInt(getWidth()), random.nextInt(getHeight()), 5, 5); } } 作为实际窗口:

Window

还有public class Window extends JFrame { public Window(Canvas canvas) { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); add(canvas); pack(); setVisible(true); } } 和应用程序的入口点。同时启动计时器,以便每秒调用Controller上的repaint来强制绘制另一个圆。

Canvas

问题在于,每绘制一个新圆,就会清除前一个圆。似乎仍有一些过程用白色填充public class Controller { public static void main(String[] args) { Canvas canvas = new Canvas(); SwingUtilities.invokeLater(() -> new Window(canvas)); new Timer(1000, e -> canvas.repaint()).start(); } } 或整个JPanel

2 个答案:

答案 0 :(得分:1)

Swing中的绘画具有破坏性。可以预见,每次绘制组件时,都必须重新从头开始绘制。

您需要定义一个模型来维护所需的信息,以便从头开始恢复状态。

您的绘制例程随后将迭代该模型并每次绘制元素。

这样做的好处是,您可以修改模型,删除或插入元素,从而可以更新简单绘制的内容。

或者,您可以使用“缓冲区”(即soup.find('table'))在其上完成所有绘制,然后在每次绘制组件时将图像简单地绘制到组件上。

但是,这意味着您不能撤消或分层绘画,而是将绘画直接绘制到图像上。这也使调整绘图图像区域的大小变得更加困难,因为您需要手动进行这些更新,而基于“模型”的实现则更具适应性

答案 1 :(得分:0)

考虑调用repaint(...)的备用构造方法

repaint(长tm,int x,int y,int宽度,int高度)

这允许您设置要重新粉刷的指定区域。

您也可以将绘制的内容存储在列表中,然后在调用重画后将图形重新打印到画布上。