Java 此代码显示在窗口控制台上的代码,但不显示在我使用的文本区域上
下面是我的代码:Java 此代码显示在窗口控制台上的代码,但不显示在我使用的文本区域上,java,swing,awt,jtextfield,jtextarea,Java,Swing,Awt,Jtextfield,Jtextarea,下面是我的代码: package Project1; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.JTextArea; import javax.swing.JTextField; import ja
package Project1;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Font;
import javax.swing.JScrollBar;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class DonorChat extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
String get=null;
String s1=null;
DataOutputStream dos;
DataInputStream dis;
JButton btnNewButton;
private JPanel contentPane;
public JTextField textField;
public JTextArea textArea ;
public JButton btnNewButton_1;
public DonorChat() {
setTitle("Donor Chat");
// setIconImage(Toolkit.getDefaultToolkit().getImage("E:\\algorithm\\Project1\\Project1\\Blood.png"));
setIconImage(Toolkit.getDefaultToolkit().getImage("E:\\algorithm\\Project1\\Project1\\Blood.png"));
setForeground(Color.RED);
setFont(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(0, 0, 800, 1000);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
textArea= new JTextArea();
textArea.setFont(new Font("Tahoma", Font.BOLD, 17));
textArea.setBounds(31, 222, 707, 522);
contentPane.add(textArea);
textField = new JTextField();
textField.setFont(new Font("Tahoma", Font.BOLD, 17));
textField.setBounds(31, 793, 510, 105);
contentPane.add(textField);
textField.setColumns(10);
textField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
});
btnNewButton = new JButton("Send\r\n");
btnNewButton.setFont(new Font("Tahoma", Font.BOLD, 17));
btnNewButton.setForeground(Color.RED);
btnNewButton.setBackground(Color.LIGHT_GRAY);
btnNewButton.setBounds(602, 820, 125, 47);
contentPane.add(btnNewButton);
JScrollBar scrollBar = new JScrollBar();
scrollBar.setBounds(717, 222, 21, 522);
contentPane.add(scrollBar);
btnNewButton_1 = new JButton("CONNECT TO SERVER");
btnNewButton_1.setBackground(Color.RED);
btnNewButton_1.setForeground(Color.DARK_GRAY);
btnNewButton_1.setFont(new Font("Times New Roman", Font.BOLD, 29));
btnNewButton_1.setBounds(31, 60, 707, 86);
contentPane.add(btnNewButton_1);
btnNewButton_1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
try {
ServerSocket ss=new ServerSocket(9995);
Socket snSocket=ss.accept();
dos=new DataOutputStream(snSocket.getOutputStream());
dis=new DataInputStream(snSocket.getInputStream());
getValue();
ss.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
setVisible(true);
}
public void getValue() throws IOException{
btnNewButton.removeActionListener(null);
while(true){
s1=dis.readUTF();
if (s1.equals("stop")){
textArea.setText("Client Want to Stop:"+s1);
break;
}
else{
System.out.println("Client Says:"+s1);
textArea.setText("Client Says:"+s1);
}
System.out.println("Type Something for Client");
btnNewButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0){
try {
dos.writeUTF(get);
}
catch(Exception e){
}
}
});
}
}
}
我正在为服务器构建一个窗口,该窗口需要一个连接按钮来连接服务器套接字,但在为该服务器设置客户端并向客户端发送消息后,该消息显示在eclipse控制台上,而不是我实际想要的文本区域上
所以请帮我看看我的代码。有两个问题:
while(true)
循环正在阻止AWT事件分派线程getValue()
,并且getValue()从套接字读取,直到遇到“stop”
,所有事件处理都将暂停。没有东西会被重新粉刷。将不会对鼠标或键盘输入做出响应,因为不会处理MouseeEvents和KeyEvents
您必须执行I/O操作,如从不同线程上的套接字读取。但是,Swing方法必须在AWT事件调度线程中执行
一种解决方案是使用类,它的publish
和process
方法允许您将多个数据元素从后台线程发送到AWT甚至调度线程
要发送到套接字,可以使用线程安全的BlockingQueue存储要发送的行,然后在不同的线程(不是AWT事件分派线程)中使用循环从该BlockingQueue获取文本并将其发送到套接字
只添加一次侦听器
方法addActionListener
实际上是向按钮添加一个侦听器。按下按钮时,将调用您添加的所有侦听器
因此,如果您每次执行循环时都调用addActionListener
,那么您将为从套接字读取的每段数据添加一个侦听器
通常在创建按钮之后,只应向按钮添加一次ActionListener
代码
因此,如果我们将I/O移动到其他线程,并使用BlockingQueue跟踪要发送的行,它看起来是这样的:
private final BlockingQueue<String> linesToSend =
new LinkedBlockingDeque<>();
public DonorChat() {
// ...
textField.addActionListener(new ActionListener() {
linesToSend.add(textField.getText());
});
btnNewButton.addActionListener(new ActionListener() {
linesToSend.add(textField.getText());
});
// ...
}
private void getValue(Socket snSocket) {
textArea.setText("");
SwingWorker<Void, String> socketReader =
new SwingWorker<Void, String>() {
@Override
protected Void doInBackground()
throws IOException {
// Runs in another thread.
// No AWT/Swing calls allowed here!
dis = new DataInputStream(snSocket.getInputStream());
while (true) {
String s1 = dis.readUTF();
if (s1.equals("stop")) {
publish("Client wants to stop.");
break;
}
publish("Client says: " + s1);
}
snSocket.close();
return null;
}
@Override
protected void process(List<String> linesRead) {
// Runs in event dispatch thread thread.
// AWT/Swing calls only; no I/O allowed here!
for (String line : linesRead) {
textArea.append(line + "\n");
}
}
};
socketReader.execute();
// Lines to send were added in AWT event dispatch thread
// by ActionListeners.
// We want to send them to the socket in a different thread.
Runnable linesSender = new Runnable() {
@Override
public void run() {
try {
dos = new DataOutputStream(snSocket.getOutputStream());
while (true) {
dos.writeUTF(linesToSend.take());
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(linesSender).start();
}
private final blocking队列行发送=
新的LinkedBlockingDeque();
公共捐款人{
// ...
addActionListener(新ActionListener(){
linesToSend.add(textField.getText());
});
addActionListener(新ActionListener(){
linesToSend.add(textField.getText());
});
// ...
}
私有void getValue(套接字snSocket){
textArea.setText(“”);
SwingWorker socketReader=
新SwingWorker(){
@凌驾
受保护的Void doInBackground()
抛出IOException{
//在另一个线程中运行。
//这里不允许AWT/Swing呼叫!
dis=新的DataInputStream(snSocket.getInputStream());
while(true){
字符串s1=dis.readUTF();
如果(s1等于(“停止”)){
发布(“客户想要停止”);
打破
}
发布(“客户说:”+s1);
}
snSocket.close();
返回null;
}
@凌驾
受保护的无效进程(列表行读取){
//在事件分派线程中运行。
//仅限AWT/Swing调用;此处不允许I/O!
用于(字符串行:linesRead){
textArea.append(第+行“\n”);
}
}
};
socketReader.execute();
//要发送的行已添加到AWT事件调度线程中
//由ActionListeners提供。
//我们想用不同的线程将它们发送到套接字。
Runnable linesSender=new Runnable(){
@凌驾
公开募捐{
试一试{
dos=新的DataOutputStream(snSocket.getOutputStream());
while(true){
writeUTF(linesToSend.take());
}
}捕获(IOException | InterruptedException e){
e、 printStackTrace();
}
}
};
新螺纹(linesSender).start();
}
其他一些重要注意事项:
- 切勿写入空的
块。异常告诉您哪里出了问题,哪里出了问题,这是非常有价值的信息。如果您不确定在catch
块中放入什么,请编写catch
e.printStackTrace()代码>以便您可以查看异常的完整详细信息
- 空布局将使您的计算机看起来正常,但在其他计算机上会出现问题,因为安装的字体不同,字体呈现的大小也不同。(“17分”是指ª⁷⁄₇₂ 英寸,在120 DPI显示器上渲染的像素比在96 DPI显示器上渲染的像素多。)此外,空布局意味着您无法调整窗口大小以使JTextArea和JTextField变大或变小
while(true)
是从事件侦听器调用的,因此AWT无法处理任何其他事件:它无法绘制任何内容,也无法响应用户输入。看见另外,addActionListener
字面上*将一个侦听器添加到组件的侦听器列表*-这意味着在循环的第二次迭代之后,有两个侦听器,下次有三个侦听器,然后是四个,五个,依此类推。不要在循环中调用addActionListener
。嘿……所以请建议我在这里使用的想法。