gpt4 book ai didi

java - 当类在 main() 之外实例化时,GUI 无响应

转载 作者:行者123 更新时间:2023-12-01 21:18:17 25 4
gpt4 key购买 nike

我开始学习 Java,我想使用 OpenCV 创建一个简单的相机源查看器。当从它自己的 main() 方法实例化时,或者当从调用者类的 main() 方法中进行调用时,MyCV 类可以正常工作。然后,我构建了一个“MyClient”类,其中包含一个 main() 方法和一个简单的 GUI(实际上只是一个 JFrame 和一个 JButton),因为我希望在按下 MyClient GUI 中的按钮时显示 MyCV GUI。

问题是,当“调用者”类拥有自己的 JFrame 和关联的 GUI 元素时,当我单击按钮时,整个 GUI 卡住,MyCV 类中的框架显示为空,并且两个窗口都变得无响应。

我还尝试了 SwingUtilities.invokeLater() 类,但没有成功。

正如我所说,我是 Java/Swing 的新手,在我看来这像是一个 PaintComponent() 问题,但对于我的一生来说,我无法修复它。

非常感谢任何帮助

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

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

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.videoio.VideoCapture;


public class MyCV {
public static void main(String args[]){
MyCV cv=new MyCV();
}

public MyCV(){
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
//-- Video capture structure
VideoCapture feed=new VideoCapture(0);
//-- Mat structures
Mat imgFeed1=new Mat();
Mat imgFeed2=new Mat();
Mat imgFeed3=new Mat();
Mat imgFeed4=new Mat();

imgPanel feedPanel1=new imgPanel(); feedPanel1.setPreferredSize(new Dimension(400,400));
imgPanel feedPanel2=new imgPanel(); feedPanel2.setPreferredSize(new Dimension(400,400));
imgPanel feedPanel3=new imgPanel(); feedPanel3.setPreferredSize(new Dimension(400,400));
imgPanel feedPanel4=new imgPanel(); feedPanel4.setPreferredSize(new Dimension(400,400));
JPanel container=new JPanel(); container.setPreferredSize(new Dimension(800,800));
container.add(feedPanel1);
container.add(feedPanel2);
container.add(feedPanel3);
container.add(feedPanel4);

JFrame f=new JFrame("MyChild");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.add(container);
f.setSize(1300, 800);
f.setVisible(true);

//-- clear resources on exit
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
feed.release();
f.dispose();
}
});

//-- main loop
while(true){
if(!feed.isOpened()) break;
feed.read(imgFeed1);
if(imgFeed1.size().width==0) break;

//-- display images in panels (Colors +Feed +Norm)
feedPanel1.setimagewithMat(imgFeed1);
feedPanel2.setimagewithMat(imgFeed1);
feedPanel3.setimagewithMat(imgFeed1);
feedPanel4.setimagewithMat(imgFeed1);

// repaint frame
container.repaint();
}

}


class imgPanel extends JPanel{
private static final long serialVersionUID=1L;
private BufferedImage image;
//public imgPanel(){ super(); }
private BufferedImage getimage(){ return image; }
public void setimage(BufferedImage newimage){image=newimage; return; }
//-- called method
public void setimagewithMat(Mat newimage){
image=matToBufferedImage(newimage);
return;
}
//--
//--
public BufferedImage matToBufferedImage(Mat matrix) {
int cols = matrix.cols();
int rows = matrix.rows();
int elemSize = (int)matrix.elemSize();
byte[] data = new byte[cols * rows * elemSize];
int type;
matrix.get(0, 0, data);
switch (matrix.channels()) {
case 1:
type = BufferedImage.TYPE_BYTE_GRAY;
break;
case 3:
type = BufferedImage.TYPE_3BYTE_BGR;
// bgr to rgb
byte b;
for(int i=0; i<data.length; i=i+3) {
b = data[i];
data[i] = data[i+2];
data[i+2] = b;
}
break;
default:
return null;
}
BufferedImage image2 = new BufferedImage(cols, rows, type);
image2.getRaster().setDataElements(0, 0, cols, rows, data);
return image2;
}

@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
BufferedImage temp=getimage();
if(temp!=null){
g.drawImage(temp, 0, 0, temp.getWidth(), temp.getHeight(), this);
}
}
}
}

MyClient.java:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MyClient {
public static void main(String args[]){
//MyCV cv=new MyCV();
//MyClient cli=new MyClient();
JFrame f=new JFrame("My Client");
f.setSize(300, 300);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setVisible(true);

JButton button=new JButton("call Color Detector");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
MyCV cv=new MyCV();
}
});

f.add(button);

}

public MyClient(){
JFrame f=new JFrame("My Client");
f.setSize(300, 300);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setVisible(true);

JButton button=new JButton("call Color Detector");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
MyCV cv=new MyCV();
}
});

f.add(button);

}
}

最佳答案

while(true){

上面是在事件调度线程(又名EDT)上运行的无限循环。 Swing 是单线程的 - 所有事件、绘画等......都发生在单个线程(EDT)上 - 如果该线程由于任何原因被束缚在工作上,则它的任何其他职责都不会发生(换句话说,看起来您的用户界面已锁定)。 main 方法在单独的线程上运行,因此您不会看到相同的行为(尽管对 Swing 组件的所有调用都应放在 EDT 上,所以我不一定会将此称为解决问题的正确方法)行为)。三个选项:

  1. 启动一个或多个新线程,并将所有长时间运行的任务放入该线程中(请注意,对 Swing 组件的任何调用都应使用 SwingUtilities 放在 EDT 上)
  2. 使用 SwingWorker
  3. 如果您希望定期执行某些操作,例如动画,可以使用 java.swing.Timer

示例 1:

//long running task inside a new Thread
new Thread(new Runnable(){

@Override
public void run(){
while(true){

}
}

});

关于java - 当类在 main() 之外实例化时,GUI 无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39577420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com