Java Swing线程问题

Java Swing线程问题,java,multithreading,swing,concurrency,Java,Multithreading,Swing,Concurrency,我有一个与在swing中使用线程相关的问题。 我将首先解释这个问题,然后发布我的代码 问题如下。我有两个类,一个包含业务逻辑,另一个包含用户界面。根据界面中的用户操作,我调用包含业务逻辑的类中的方法。 但是,我的下一个任务是让用户单击某个UI元素,基于该单击,我将一个新的鼠标侦听器附加到另一个UI元素,并等待用户单击该另一个UI元素,然后我希望更改初始单击的UI元素。 但是,我的应用程序在单击另一个UI元素后会阻塞。 在示例代码中,初始UI元素和其他UI元素都是相同的,但通常情况下它们不会相同

我有一个与在swing中使用线程相关的问题。 我将首先解释这个问题,然后发布我的代码

问题如下。我有两个类,一个包含业务逻辑,另一个包含用户界面。根据界面中的用户操作,我调用包含业务逻辑的类中的方法。 但是,我的下一个任务是让用户单击某个UI元素,基于该单击,我将一个新的鼠标侦听器附加到另一个UI元素,并等待用户单击该另一个UI元素,然后我希望更改初始单击的UI元素。 但是,我的应用程序在单击另一个UI元素后会阻塞。 在示例代码中,初始UI元素和其他UI元素都是相同的,但通常情况下它们不会相同

示例类:

====================================================================

package threadtests;

import java.awt.Color;

public class LogicClass extends Thread {

    FrameClass fc;
    SelectSynchronizerObject mysso;

    public void run() {
        while(true);
    }

    public void startThisFromFrame() {
        MyMouseListener2 m2 = new MyMouseListener2();
        m2.initialize(fc.jp, mysso);
        fc.jp.addMouseListener(m2);
        mysso.getSelected();
        fc.jp.setBackground(new Color(100,100,100));
        fc.jp.removeMouseListener(m2);
    }

    public static void main(String args[]) {
        SelectSynchronizerObject sso = new SelectSynchronizerObject();
        LogicClass lc = new LogicClass();
        lc.mysso = sso;
        lc.start();
        FrameClass fc = new FrameClass();
        fc.lc = lc;
        lc.fc = fc;
        fc.mysso = sso;
        fc.initialize(lc);
    }

}
package threadtests;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class FrameClass extends JFrame {

    LogicClass lc;
    SelectSynchronizerObject mysso;
    JPanel jp = new JPanel();

    public void initialize(LogicClass arg) {
        lc = arg;
        setSize(100,100);
        MyMouseListener m = new MyMouseListener(); 
        jp.addMouseListener(m);
        m.initialize(jp, lc);
        jp.setBackground(new Color(255,200,200));
        add(jp);

        setVisible(true);
    }

}
package threadtests;

public class SelectSynchronizerObject {

    public int selectednumer = 0;
    public boolean numberset = false;

    public synchronized void panelSelected(int a) {
        selectednumer = a;
        notify();
    }

    public synchronized int getSelected() {
        try {
            wait();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        return selectednumer;
    }

}
package threadtests;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener implements MouseListener  {

    JPanel mypanel;
    LogicClass lc;
    public void initialize(JPanel arg, LogicClass arg2) {
        mypanel = arg;
        lc = arg2;
    }
    public void mouseClicked(MouseEvent e) {
        lc.startThisFromFrame();
    }
    public void mousePressed(MouseEvent e) {

    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
        mypanel.setBackground(new Color(200,255,200));
    }
    public void mouseExited(MouseEvent e) {
        mypanel.setBackground(new Color(255,200,200));
    }

}
package threadtests;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener2 implements MouseListener  {

    JPanel mypanel;
    SelectSynchronizerObject sso;
    public void initialize(JPanel arg, SelectSynchronizerObject arg1) {
        mypanel = arg;
        sso = arg1;
    }
    public void mouseClicked(MouseEvent e) {
        sso.panelSelected(1);
    }
    public void mousePressed(MouseEvent e) {
    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
    }
    public void mouseExited(MouseEvent e) {
    }

}
====================================================================

package threadtests;

import java.awt.Color;

public class LogicClass extends Thread {

    FrameClass fc;
    SelectSynchronizerObject mysso;

    public void run() {
        while(true);
    }

    public void startThisFromFrame() {
        MyMouseListener2 m2 = new MyMouseListener2();
        m2.initialize(fc.jp, mysso);
        fc.jp.addMouseListener(m2);
        mysso.getSelected();
        fc.jp.setBackground(new Color(100,100,100));
        fc.jp.removeMouseListener(m2);
    }

    public static void main(String args[]) {
        SelectSynchronizerObject sso = new SelectSynchronizerObject();
        LogicClass lc = new LogicClass();
        lc.mysso = sso;
        lc.start();
        FrameClass fc = new FrameClass();
        fc.lc = lc;
        lc.fc = fc;
        fc.mysso = sso;
        fc.initialize(lc);
    }

}
package threadtests;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class FrameClass extends JFrame {

    LogicClass lc;
    SelectSynchronizerObject mysso;
    JPanel jp = new JPanel();

    public void initialize(LogicClass arg) {
        lc = arg;
        setSize(100,100);
        MyMouseListener m = new MyMouseListener(); 
        jp.addMouseListener(m);
        m.initialize(jp, lc);
        jp.setBackground(new Color(255,200,200));
        add(jp);

        setVisible(true);
    }

}
package threadtests;

public class SelectSynchronizerObject {

    public int selectednumer = 0;
    public boolean numberset = false;

    public synchronized void panelSelected(int a) {
        selectednumer = a;
        notify();
    }

    public synchronized int getSelected() {
        try {
            wait();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        return selectednumer;
    }

}
package threadtests;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener implements MouseListener  {

    JPanel mypanel;
    LogicClass lc;
    public void initialize(JPanel arg, LogicClass arg2) {
        mypanel = arg;
        lc = arg2;
    }
    public void mouseClicked(MouseEvent e) {
        lc.startThisFromFrame();
    }
    public void mousePressed(MouseEvent e) {

    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
        mypanel.setBackground(new Color(200,255,200));
    }
    public void mouseExited(MouseEvent e) {
        mypanel.setBackground(new Color(255,200,200));
    }

}
package threadtests;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener2 implements MouseListener  {

    JPanel mypanel;
    SelectSynchronizerObject sso;
    public void initialize(JPanel arg, SelectSynchronizerObject arg1) {
        mypanel = arg;
        sso = arg1;
    }
    public void mouseClicked(MouseEvent e) {
        sso.panelSelected(1);
    }
    public void mousePressed(MouseEvent e) {
    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
    }
    public void mouseExited(MouseEvent e) {
    }

}
====================================================================

package threadtests;

import java.awt.Color;

public class LogicClass extends Thread {

    FrameClass fc;
    SelectSynchronizerObject mysso;

    public void run() {
        while(true);
    }

    public void startThisFromFrame() {
        MyMouseListener2 m2 = new MyMouseListener2();
        m2.initialize(fc.jp, mysso);
        fc.jp.addMouseListener(m2);
        mysso.getSelected();
        fc.jp.setBackground(new Color(100,100,100));
        fc.jp.removeMouseListener(m2);
    }

    public static void main(String args[]) {
        SelectSynchronizerObject sso = new SelectSynchronizerObject();
        LogicClass lc = new LogicClass();
        lc.mysso = sso;
        lc.start();
        FrameClass fc = new FrameClass();
        fc.lc = lc;
        lc.fc = fc;
        fc.mysso = sso;
        fc.initialize(lc);
    }

}
package threadtests;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class FrameClass extends JFrame {

    LogicClass lc;
    SelectSynchronizerObject mysso;
    JPanel jp = new JPanel();

    public void initialize(LogicClass arg) {
        lc = arg;
        setSize(100,100);
        MyMouseListener m = new MyMouseListener(); 
        jp.addMouseListener(m);
        m.initialize(jp, lc);
        jp.setBackground(new Color(255,200,200));
        add(jp);

        setVisible(true);
    }

}
package threadtests;

public class SelectSynchronizerObject {

    public int selectednumer = 0;
    public boolean numberset = false;

    public synchronized void panelSelected(int a) {
        selectednumer = a;
        notify();
    }

    public synchronized int getSelected() {
        try {
            wait();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        return selectednumer;
    }

}
package threadtests;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener implements MouseListener  {

    JPanel mypanel;
    LogicClass lc;
    public void initialize(JPanel arg, LogicClass arg2) {
        mypanel = arg;
        lc = arg2;
    }
    public void mouseClicked(MouseEvent e) {
        lc.startThisFromFrame();
    }
    public void mousePressed(MouseEvent e) {

    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
        mypanel.setBackground(new Color(200,255,200));
    }
    public void mouseExited(MouseEvent e) {
        mypanel.setBackground(new Color(255,200,200));
    }

}
package threadtests;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener2 implements MouseListener  {

    JPanel mypanel;
    SelectSynchronizerObject sso;
    public void initialize(JPanel arg, SelectSynchronizerObject arg1) {
        mypanel = arg;
        sso = arg1;
    }
    public void mouseClicked(MouseEvent e) {
        sso.panelSelected(1);
    }
    public void mousePressed(MouseEvent e) {
    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
    }
    public void mouseExited(MouseEvent e) {
    }

}
====================================================================

package threadtests;

import java.awt.Color;

public class LogicClass extends Thread {

    FrameClass fc;
    SelectSynchronizerObject mysso;

    public void run() {
        while(true);
    }

    public void startThisFromFrame() {
        MyMouseListener2 m2 = new MyMouseListener2();
        m2.initialize(fc.jp, mysso);
        fc.jp.addMouseListener(m2);
        mysso.getSelected();
        fc.jp.setBackground(new Color(100,100,100));
        fc.jp.removeMouseListener(m2);
    }

    public static void main(String args[]) {
        SelectSynchronizerObject sso = new SelectSynchronizerObject();
        LogicClass lc = new LogicClass();
        lc.mysso = sso;
        lc.start();
        FrameClass fc = new FrameClass();
        fc.lc = lc;
        lc.fc = fc;
        fc.mysso = sso;
        fc.initialize(lc);
    }

}
package threadtests;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class FrameClass extends JFrame {

    LogicClass lc;
    SelectSynchronizerObject mysso;
    JPanel jp = new JPanel();

    public void initialize(LogicClass arg) {
        lc = arg;
        setSize(100,100);
        MyMouseListener m = new MyMouseListener(); 
        jp.addMouseListener(m);
        m.initialize(jp, lc);
        jp.setBackground(new Color(255,200,200));
        add(jp);

        setVisible(true);
    }

}
package threadtests;

public class SelectSynchronizerObject {

    public int selectednumer = 0;
    public boolean numberset = false;

    public synchronized void panelSelected(int a) {
        selectednumer = a;
        notify();
    }

    public synchronized int getSelected() {
        try {
            wait();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        return selectednumer;
    }

}
package threadtests;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener implements MouseListener  {

    JPanel mypanel;
    LogicClass lc;
    public void initialize(JPanel arg, LogicClass arg2) {
        mypanel = arg;
        lc = arg2;
    }
    public void mouseClicked(MouseEvent e) {
        lc.startThisFromFrame();
    }
    public void mousePressed(MouseEvent e) {

    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
        mypanel.setBackground(new Color(200,255,200));
    }
    public void mouseExited(MouseEvent e) {
        mypanel.setBackground(new Color(255,200,200));
    }

}
package threadtests;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener2 implements MouseListener  {

    JPanel mypanel;
    SelectSynchronizerObject sso;
    public void initialize(JPanel arg, SelectSynchronizerObject arg1) {
        mypanel = arg;
        sso = arg1;
    }
    public void mouseClicked(MouseEvent e) {
        sso.panelSelected(1);
    }
    public void mousePressed(MouseEvent e) {
    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
    }
    public void mouseExited(MouseEvent e) {
    }

}
====================================================================

package threadtests;

import java.awt.Color;

public class LogicClass extends Thread {

    FrameClass fc;
    SelectSynchronizerObject mysso;

    public void run() {
        while(true);
    }

    public void startThisFromFrame() {
        MyMouseListener2 m2 = new MyMouseListener2();
        m2.initialize(fc.jp, mysso);
        fc.jp.addMouseListener(m2);
        mysso.getSelected();
        fc.jp.setBackground(new Color(100,100,100));
        fc.jp.removeMouseListener(m2);
    }

    public static void main(String args[]) {
        SelectSynchronizerObject sso = new SelectSynchronizerObject();
        LogicClass lc = new LogicClass();
        lc.mysso = sso;
        lc.start();
        FrameClass fc = new FrameClass();
        fc.lc = lc;
        lc.fc = fc;
        fc.mysso = sso;
        fc.initialize(lc);
    }

}
package threadtests;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class FrameClass extends JFrame {

    LogicClass lc;
    SelectSynchronizerObject mysso;
    JPanel jp = new JPanel();

    public void initialize(LogicClass arg) {
        lc = arg;
        setSize(100,100);
        MyMouseListener m = new MyMouseListener(); 
        jp.addMouseListener(m);
        m.initialize(jp, lc);
        jp.setBackground(new Color(255,200,200));
        add(jp);

        setVisible(true);
    }

}
package threadtests;

public class SelectSynchronizerObject {

    public int selectednumer = 0;
    public boolean numberset = false;

    public synchronized void panelSelected(int a) {
        selectednumer = a;
        notify();
    }

    public synchronized int getSelected() {
        try {
            wait();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        return selectednumer;
    }

}
package threadtests;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener implements MouseListener  {

    JPanel mypanel;
    LogicClass lc;
    public void initialize(JPanel arg, LogicClass arg2) {
        mypanel = arg;
        lc = arg2;
    }
    public void mouseClicked(MouseEvent e) {
        lc.startThisFromFrame();
    }
    public void mousePressed(MouseEvent e) {

    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
        mypanel.setBackground(new Color(200,255,200));
    }
    public void mouseExited(MouseEvent e) {
        mypanel.setBackground(new Color(255,200,200));
    }

}
package threadtests;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener2 implements MouseListener  {

    JPanel mypanel;
    SelectSynchronizerObject sso;
    public void initialize(JPanel arg, SelectSynchronizerObject arg1) {
        mypanel = arg;
        sso = arg1;
    }
    public void mouseClicked(MouseEvent e) {
        sso.panelSelected(1);
    }
    public void mousePressed(MouseEvent e) {
    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
    }
    public void mouseExited(MouseEvent e) {
    }

}
==========================

package threadtests;

import java.awt.Color;

public class LogicClass extends Thread {

    FrameClass fc;
    SelectSynchronizerObject mysso;

    public void run() {
        while(true);
    }

    public void startThisFromFrame() {
        MyMouseListener2 m2 = new MyMouseListener2();
        m2.initialize(fc.jp, mysso);
        fc.jp.addMouseListener(m2);
        mysso.getSelected();
        fc.jp.setBackground(new Color(100,100,100));
        fc.jp.removeMouseListener(m2);
    }

    public static void main(String args[]) {
        SelectSynchronizerObject sso = new SelectSynchronizerObject();
        LogicClass lc = new LogicClass();
        lc.mysso = sso;
        lc.start();
        FrameClass fc = new FrameClass();
        fc.lc = lc;
        lc.fc = fc;
        fc.mysso = sso;
        fc.initialize(lc);
    }

}
package threadtests;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class FrameClass extends JFrame {

    LogicClass lc;
    SelectSynchronizerObject mysso;
    JPanel jp = new JPanel();

    public void initialize(LogicClass arg) {
        lc = arg;
        setSize(100,100);
        MyMouseListener m = new MyMouseListener(); 
        jp.addMouseListener(m);
        m.initialize(jp, lc);
        jp.setBackground(new Color(255,200,200));
        add(jp);

        setVisible(true);
    }

}
package threadtests;

public class SelectSynchronizerObject {

    public int selectednumer = 0;
    public boolean numberset = false;

    public synchronized void panelSelected(int a) {
        selectednumer = a;
        notify();
    }

    public synchronized int getSelected() {
        try {
            wait();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        return selectednumer;
    }

}
package threadtests;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener implements MouseListener  {

    JPanel mypanel;
    LogicClass lc;
    public void initialize(JPanel arg, LogicClass arg2) {
        mypanel = arg;
        lc = arg2;
    }
    public void mouseClicked(MouseEvent e) {
        lc.startThisFromFrame();
    }
    public void mousePressed(MouseEvent e) {

    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
        mypanel.setBackground(new Color(200,255,200));
    }
    public void mouseExited(MouseEvent e) {
        mypanel.setBackground(new Color(255,200,200));
    }

}
package threadtests;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

public class MyMouseListener2 implements MouseListener  {

    JPanel mypanel;
    SelectSynchronizerObject sso;
    public void initialize(JPanel arg, SelectSynchronizerObject arg1) {
        mypanel = arg;
        sso = arg1;
    }
    public void mouseClicked(MouseEvent e) {
        sso.panelSelected(1);
    }
    public void mousePressed(MouseEvent e) {
    }
    public void mouseReleased(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
    }
    public void mouseExited(MouseEvent e) {
    }

}
感谢您的帮助。

首先:

public void run() {
    while(true);
}
只是把CPU从做其他事情中解放出来

然后:

正在主线程中调用,因此会阻塞

实际上,您不需要invokelater、swingworker或任何东西,您只需要一点GUI事件编程即可。在开始时将事件侦听器连接在一起,然后您将获得所选的面板,而不包含任何线程


一般来说,虽然线程对于相当多的程序来说是必需的,但在不需要线程的地方不需要强制线程,因为它们会给编程增加很多复杂性。

看看SwingUtilities.Invoke实际上,我相信OP需要在后台执行昂贵的任务
invokeLater
意味着对其他线程正在执行的任务进行排队,这些任务需要更新UI(只能通过EDT进行更新),我重新阅读了这个问题,看起来OP想要创建新的UI元素,这最好通过EDT来完成-
invokeLater
看起来是这种情况下的方法。实际上,LogicClass被设置为线程,不是因为它本身需要是线程,但因为我试图解决阻塞问题——使LogicClass成为线程,这样它就不会阻塞EDT。然而,这并没有起到任何作用,程序仍然被阻止。事实上,我知道如何通过更多的编程来解决这个问题,但我拥有的其他解决方案不够精练,无法满足我的需求。我知道线程的理论,但不完全了解它是如何在Java中实现的,因此我可能会研究它。一般来说,让GUI工作不需要线程——这就是我试图解释的。对于需要更长时间的操作,您确实需要线程,并且您希望防止线程阻塞GUI。但是,由于线程增加了很多复杂性(在等待问题上,您刚刚得到了一点复杂性),因此在没有线程的情况下,应该尽可能地做到这一点。在您的情况下,您永远不应该(我的意思是真的永远不应该)在主事件线程上调用wait,因为这样您肯定会阻塞您的GUI。您可以启动一个新线程并在那里调用wait,然后通知它,当它醒来时,它可以使用Swings invokeLater在GUI上进行更改(这是必要的,因为Swing通常不是线程安全的)。