【问题标题】:Multithreading extended panel多线程扩展面板
【发布时间】:2016-03-29 07:28:44
【问题描述】:

我正在尝试分配一个在JFrame 中实现Runnable 接口的JPanel。我制作了这个样本来解释我的想法。我想添加一个多线程面板,该面板将文本作为演示显示到窗口中,String 作为新实例的参数。面板应该有独立的进程,所以我实现了Runnable 接口。但是当我尝试使用我的类的新实例创建一个新的面板实例时,它不起作用。

我做错了什么?

imagePanel 面板类:

public class imagePanel extends JPanel implements Runnable{
    JLabel imageTest;

    public imagePanel(String textLabel)
    {
        this.setPreferredSize(new Dimension(300,300));
        imageTest = new JLabel(textLabel);
        imageTest.setPreferredSize(this.getPreferredSize());
    }

    public void setImageText(String newText){
        imageTest.setText(newText);
    }

    public void run(){
        this.add(imageTest);
    }

}

主类测试类:

public class test {
    public static void main(){
        JFrame frame = new JFrame("Test Window");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(300,300));            

        JPanel panel = new imagePanel("Text label");
        panel.setPreferredSize(frame.getPreferredSize());

        frame.add(panel);
        frame.setVisible(true);
    }
}

【问题讨论】:

  • 创建一个“多线程面板”不是很漂亮。 Panel 是一个用户界面组件,它不应该对线程做任何事情。同样在你的代码中run() 永远不会被调用,所以它也被“破坏”了。
  • 您忘记给面板添加标签
  • @SergiyMedvynskyy 虽然发布的示例肯定不会添加标签,但假设他们创建了一个 Thread,它在实际代码中的某个位置包装了 panel 的实例 this.add(imageTest);应该被调用......但这是很多“如果”
  • 对不起,这只是我正在尝试做的工作的一个示例,我写得很快,我正在使用 Opencv API 使用相机进行人脸识别,需要一个独立的进程用于该类并直接显示在面板中。
  • 回复:“一个实现 Runnable 的 JPanel”听起来明显违反了单一职责原则 (en.wikipedia.org/wiki/Single_responsibility_principle)

标签: java multithreading swing runnable


【解决方案1】:
  1. Swing 不是线程安全的,这意味着对 UI 的更新只能在事件调度线程的上下文中进行。请参阅Concurrency in Swing 了解更多详情,Worker Threads and SwingWorker 了解可能的解决方案
  2. Swing 布局是惰性的,这是一件好事,它们不会更新,直到您告诉它们(或某些其他事件需要它们更新,例如容器大小调整)。您可以通过在要更新的容器上调用 revalidaterepaint 来触发更新
  3. 创建一个新的类实例并不能神奇地连接您可能拥有的所有实例,这会使程序相当难以管理

【讨论】:

    【解决方案2】:

    缺少一些东西

    非常重要 - 除了 AWT EventDispatcher 线程之外,您不应更新 UI。使用 Swing 它甚至可能导致死锁。 this post

    您必须使用 SwingUtilities 来更新 Swing UI 组件。

    SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            // update your UI components
        }
    });
    

    下一条信息 - 如何创建多线程线程?您错过的是运行“运行”方法的入口点:

    public class MyMultiThreadedType implements Runnable {
        public void run() {
            // this will run in parallel
        }
    
        public static void main(String[] args) {
        MyMultiThreadedType mmt = new MyMultiThreadedType ();
        Thread t = new Thread(mmt);
        t.start(); // this will start a parallel thread
      } 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-14
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 2018-12-30
      相关资源
      最近更新 更多