I am trying to have the output in a TextField in a GUI but all I am getting is the thread information. This is just a small set from the full code but the full version has the same problem. The full version has 5 different threads running at the same time. Any help or advice would be appreciated.
我试图在GUI中的TextField中输出,但我得到的只是线程信息。这只是完整代码中的一小部分,但完整版具有相同的问题。完整版本有5个不同的线程同时运行。任何帮助或建议将不胜感激。
public class O21 implements Runnable {
@Override
public void run() {
try {
Scanner O1 = new Scanner(new File("O21.txt"));
O1.useDelimiter(",");
while (O1.hasNext()) {
String a = O1.next();
int aa = Integer.parseInt(a);
Thread.sleep(500); // Time delay to sync output
if (a.trim().isEmpty()) {
continue;
}
System.out.println(a);
}
} catch (Exception f) {
f.printStackTrace();
}}}
This is the main.
这是主要的。
public class Window {
private JFrame frmTest;
private JTextField txtTank1;
private JTextField textField_4;
static String o1;
/**
* Launch the application.
*/
public static void main(String[] args) throws Exception {
Thread a = new Thread(new O21());
a.start();
o1= a.toString();
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Window window = new Window();
window.frmTest.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Window() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmTest = new JFrame();
frmTest.setAlwaysOnTop(true);
frmTest.setResizable(false);
frmTest.setBounds(100, 100, 350, 400);
frmTest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmTest.getContentPane().setLayout(null);
txtTank1 = new JTextField();
txtTank1.setText("Tank1");
txtTank1.setFont(new Font("Tahoma", Font.PLAIN, 20));
txtTank1.setEditable(false);
txtTank1.setColumns(10);
txtTank1.setBounds(10, 60, 150, 50);
frmTest.getContentPane().add(txtTank1);
textField_4 = new JTextField();
textField_4.setEditable(true);
textField_4.setText(o1);
textField_4.setFont(new Font("Tahoma", Font.PLAIN, 20));
textField_4.setColumns(10);
textField_4.setBounds(170, 60, 150, 50);
frmTest.getContentPane().add(textField_4);
}}
1 个解决方案
#1
You're writing to o1 once, and only getting the default toString()
from thread, so I'm not surprised that you're seeing nothing but junk. My suggestion:
你正在写o1一次,并且只从线程获得默认的toString(),所以我并不感到惊讶你除了垃圾之外什么都没看到。我的建议:
- Create a
SwingWorker<Void, String>
inside of your GUI - Run your long running code from within the SwingWorker's doInBackground
- Publish any Strings that the GUI needs by calling
publish(...)
, passing in the String. - Display them in the GUI using the SwingWorker's
process(...)
method. - Don't use a static variable as a kludge to communicate between threads. That is a very easily breakable non-solution.
- Avoid calling
setBounds()
in a Swing GUI. While null layouts andsetBounds()
might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one. Instead learn about and use layout managaers. - Have a look at: Tutorial: Concurrency in Swing.
在GUI内部创建一个SwingWorker
从SwingWorker的doInBackground中运行长时间运行的代码
通过调用发布(...),传入String,发布GUI所需的任何字符串。
使用SwingWorker的process(...)方法在GUI中显示它们。
不要使用静态变量作为线程之间进行通信的kludge。这是一个非常容易破解的非解决方案。
避免在Swing GUI中调用setBounds()。虽然null布局和setBounds()似乎可以像创建复杂GUI的最简单和最好的方式一样使用Swing GUI,但是你创建的Swing GUI越多,在使用它们时就会遇到更严重的困难。当GUI调整大小时,它们不会调整组件大小,它们是增强或维护的皇室女巫,当它们放置在滚动窗格中时它们会完全失败,当它们在所有平台上观看时或者与原始平台不同的屏幕分辨率时它们看起来很糟糕。而是学习并使用布局managaers。
看看:教程:Swing中的并发。
e.g. something like,
例如就像是,
import java.io.File;
import java.util.List;
import java.util.Scanner;
import javax.swing.*;
public class SwingThreadingEg extends JPanel implements MyAppendable {
private JTextArea area = new JTextArea(30, 50);
public SwingThreadingEg() {
JScrollPane scrollPane = new JScrollPane(area);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrollPane);
}
@Override
public void append(String text) {
area.append(text);
}
private static void createAndShowGui() {
SwingThreadingEg mainPanel = new SwingThreadingEg();
MyWorker myWorker = new MyWorker(mainPanel);
// add a Prop Change listener here to listen for
// DONE state then call get() on myWorker
myWorker.execute();
JFrame frame = new JFrame("SwingThreadingEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyWorker extends SwingWorker<Void, String> {
private MyAppendable myAppendable;
public MyWorker(MyAppendable myAppendable) {
this.myAppendable = myAppendable;
}
@Override
protected Void doInBackground() throws Exception {
try (Scanner O1 = new Scanner(new File("O21.txt"))) {
O1.useDelimiter(",");
while (O1.hasNext()) {
String a = O1.next();
int aa = Integer.parseInt(a);
Thread.sleep(500); // Time delay to sync output
if (a.trim().isEmpty()) {
continue;
}
System.out.println(a);
publish(a);
}
} catch (Exception f) {
f.printStackTrace();
}
return null;
}
@Override
protected void process(List<String> chunks) {
for (String text : chunks) {
myAppendable.append(text + "\n");
}
}
}
interface MyAppendable {
public void append(String text);
}
#1
You're writing to o1 once, and only getting the default toString()
from thread, so I'm not surprised that you're seeing nothing but junk. My suggestion:
你正在写o1一次,并且只从线程获得默认的toString(),所以我并不感到惊讶你除了垃圾之外什么都没看到。我的建议:
- Create a
SwingWorker<Void, String>
inside of your GUI - Run your long running code from within the SwingWorker's doInBackground
- Publish any Strings that the GUI needs by calling
publish(...)
, passing in the String. - Display them in the GUI using the SwingWorker's
process(...)
method. - Don't use a static variable as a kludge to communicate between threads. That is a very easily breakable non-solution.
- Avoid calling
setBounds()
in a Swing GUI. While null layouts andsetBounds()
might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one. Instead learn about and use layout managaers. - Have a look at: Tutorial: Concurrency in Swing.
在GUI内部创建一个SwingWorker
从SwingWorker的doInBackground中运行长时间运行的代码
通过调用发布(...),传入String,发布GUI所需的任何字符串。
使用SwingWorker的process(...)方法在GUI中显示它们。
不要使用静态变量作为线程之间进行通信的kludge。这是一个非常容易破解的非解决方案。
避免在Swing GUI中调用setBounds()。虽然null布局和setBounds()似乎可以像创建复杂GUI的最简单和最好的方式一样使用Swing GUI,但是你创建的Swing GUI越多,在使用它们时就会遇到更严重的困难。当GUI调整大小时,它们不会调整组件大小,它们是增强或维护的皇室女巫,当它们放置在滚动窗格中时它们会完全失败,当它们在所有平台上观看时或者与原始平台不同的屏幕分辨率时它们看起来很糟糕。而是学习并使用布局managaers。
看看:教程:Swing中的并发。
e.g. something like,
例如就像是,
import java.io.File;
import java.util.List;
import java.util.Scanner;
import javax.swing.*;
public class SwingThreadingEg extends JPanel implements MyAppendable {
private JTextArea area = new JTextArea(30, 50);
public SwingThreadingEg() {
JScrollPane scrollPane = new JScrollPane(area);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrollPane);
}
@Override
public void append(String text) {
area.append(text);
}
private static void createAndShowGui() {
SwingThreadingEg mainPanel = new SwingThreadingEg();
MyWorker myWorker = new MyWorker(mainPanel);
// add a Prop Change listener here to listen for
// DONE state then call get() on myWorker
myWorker.execute();
JFrame frame = new JFrame("SwingThreadingEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyWorker extends SwingWorker<Void, String> {
private MyAppendable myAppendable;
public MyWorker(MyAppendable myAppendable) {
this.myAppendable = myAppendable;
}
@Override
protected Void doInBackground() throws Exception {
try (Scanner O1 = new Scanner(new File("O21.txt"))) {
O1.useDelimiter(",");
while (O1.hasNext()) {
String a = O1.next();
int aa = Integer.parseInt(a);
Thread.sleep(500); // Time delay to sync output
if (a.trim().isEmpty()) {
continue;
}
System.out.println(a);
publish(a);
}
} catch (Exception f) {
f.printStackTrace();
}
return null;
}
@Override
protected void process(List<String> chunks) {
for (String text : chunks) {
myAppendable.append(text + "\n");
}
}
}
interface MyAppendable {
public void append(String text);
}