【问题标题】:Java newbie: how do i create a thread that controls my paintComponent method?Java新手:如何创建一个控制我的paintComponent方法的线程?
【发布时间】:2016-04-03 17:03:00
【问题描述】:

今年我在学校开始学习 java,我被要求创建一个程序,它有 3 个线程绘制 30 个随机圆圈(每个线程 10 个)。

我不知道如何很好地使用paintComponent,但这是我所做的:

class MioPanel extends JPanel implements Runnable {

@Override
public void paintComponent(Graphics g) {
  super.paintComponent(g); 
  Dimension dimCerchio1 = new Dimension(50, 50);

  for(int i = 0; i < 10; i++) {
    g.setColor(Color.black);
    g.drawOval((int) ((Math.random()*this.getWidth()) - (dimCerchio1.width)), (int) (Math.random()*this.getHeight() - (dimCerchio1.height )), dimCerchio1.width , dimCerchio1.height);
  }

  /*for(int i = 0; i < 10; i++) {
    g.setColor(Color.red);
    g.drawOval((int) ((Math.random()*this.getWidth()) - (dimCerchio1.width)), (int) (Math.random()*this.getHeight() - (dimCerchio1.height )), dimCerchio1.width , dimCerchio1.height);
  }

  for(int i = 0; i < 10; i++) {
    g.setColor(Color.blue);
    g.drawOval((int) ((Math.random()*this.getWidth()) - (dimCerchio1.width)), (int) (Math.random()*this.getHeight() - (dimCerchio1.height )), dimCerchio1.width , dimCerchio1.height);
  }*/
}    

@Override
public void run() {

}

run 方法是空的,因为我实际上不知道如何同时使用线程和绘图

这里是主要的:

public class Main {
  public static void main(String[] args) {        
    MFrame mframe = new MFrame("Cerchi casuali");

    Thread first = new Thread(new MioPanel());

    /*Thread second = new Thread(new MioPanel());

    Thread third = new Thread(new MioPanel());*/
  }
}

如果有什么问题,我会很感激任何帮助,对不起我的英语。

【问题讨论】:

  • 你不能这样做。 Java 的 Swing 组件不是线程安全的。您必须使用单个线程,即事件调度线程来执行这些更新。
  • 那么我该如何做类似的事情呢?
  • 这不是新手作业。此分配似乎更适合中级或高级 Java 类。
  • ...extends JPanel implements Runnable 啊啊啊!它灼伤了我的眼睛!阅读单一责任原则。程序中的每一件事(每个包、每个类、每个对象、每个方法、每个变量……)都应该只有一个存在的理由。 JPanel 存在的原因是作为可见 GUI 元素的容器。存在Runnable 的原因是提供了定义一些任务run() 方法。与使用两个独立对象的程序相比,具有满足这两个职责的单个对象的程序将更难理解(更难更改)。
  • ...我实际上不知道如何同时使用线程和油漆... 你不能。 Swing 框架不是线程安全的。所有的绘制都必须在一个线程中发生——事件调度线程 (EDT)。 Swing 程序可以使用其他线程来执行确定 GUI 对象在屏幕上的外观的计算,但是当计算完成时,工作线程使用SwingUtilities.invokeLater(r) 请求 EDT 调用做实际的绘画。

标签: java multithreading jpanel paintcomponent runnable


【解决方案1】:

你不会试图把所有东西都放在一个类中。

  1. 创建一个在 SwingUtilities invokeLater 方法上启动 Swing 组件的类。在这个类中创建 JFrame。

  2. 创建一个扩展 JPanel 的 DrawingPanel 类。将 DrawingPanel 添加到 JFrame。

  3. 创建一个 Balls 类,生成 10 个球的 x 和 y 中心以及半径。您可以使用 java.awt.Point 类来保持中心。这个类是一个Java对象。它除了保持球的中心和半径之外什么都不做。

  4. 创建一个实现 Runnable 的绘图类。将 Balls 类的实例传递给 Drawing 类。

  5. 创建绘图类的 3 个实例。将绘图类的 3 个实例传递给绘图面板。在paintComponent 方法中使用3 个实例。 除了在paintComponent 方法中绘制球之外什么都不做。

  6. 将 DrawingPanel 的实例传递给 Drawing 类的 3 个实例。

  7. 在 GUI 完成后使用这 3 个实例启动 3 个线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多