问题描述
我正在尝试创建客户端/服务器应用程序。问题是客户端的确认按钮第一次输入工作,但如果我为另一个输入点击相同的按钮,客户端GUI将冻结。
I'm trying to create a client/server application. The problem is the confirm button on client side works for the first time input but if I hit the same button for the another input the client GUI will freeze.
为什么GUI会冻结?
客户:
public class ClientGui
{
private JFrame frmBookPointOf;
private JTextField txtRm;
private JTextArea txtrBookDetails;
private JTextField textField;
private JTextField textField_1;
private JTextField textField_2;
private JTextField textField_3;
private JTextField textField_4;
private JTextField textField_5;
private JComboBox comboBox_1;
private JComboBox comboBox;
private dbController dbCtrl;
private Connection conn;
private static Socket client;
private static BufferedReader fromServer = null;
private static DataOutputStream toServer = null;
/**
* Launch the application.
*/
public static void main(String[] args) {
try {
client = new Socket("127.0.0.1", 9090);
toServer =
new DataOutputStream(client.getOutputStream());
fromServer = new BufferedReader(
new InputStreamReader(client.getInputStream()));
String answer = fromServer.readLine();
JOptionPane.showMessageDialog(null, "Connected!\n" + answer, "Status", JOptionPane.INFORMATION_MESSAGE);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null, e, "Error!", JOptionPane.ERROR_MESSAGE);
System.exit(0);
} catch (IOException e) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null, e, "Error!", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
EventQueue.invokeLater(new Runnable()
{
public void run() {
try {
ClientGui window = new ClientGui();
window.frmBookPointOf.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
/**
*
*/
public ClientGui()
{
frmBookPointOf = new JFrame();
frmBookPointOf.setTitle("Book Point of Sales");
frmBookPointOf.setBounds(100, 100, 850, 500);
frmBookPointOf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lblIsbn = new JLabel("ISBN:");
String[] index = {"--Select ISBN--"};
comboBox = new JComboBox(index);
comboBox.setToolTipText("");
dbCtrl = new dbController();
try {
conn = dbCtrl.getConnection();
String sql = "select isbn from book";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet result = ps.executeQuery();
while (result.next())
{
comboBox.addItem(result.getString("isbn"));
}
conn.close();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
JLabel lblNewLabel = new JLabel("Price:");
JLabel lblNewLabel_1 = new JLabel("Quantity:");
JLabel lblNewLabel_2 = new JLabel("Discount:");
txtRm = new JTextField();
txtRm.setEditable(false);
txtRm.setColumns(10);
comboBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e) {
try {
conn = dbCtrl.getConnection();
String x = comboBox.getSelectedItem().toString();
String sql = "select price from book where isbn= '"+x+"'";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet result = ps.executeQuery();
StringBuilder strBuilder = new StringBuilder();
while (result.next())
{
strBuilder.append(result.getString(1));
}
txtRm.setText(strBuilder.toString());
conn.close();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
textField = new JTextField();
textField.setColumns(10);
comboBox_1 = new JComboBox();
comboBox_1.addItem("0");
comboBox_1.addItem("5");
comboBox_1.addItem("10");
comboBox_1.addItem("20");
comboBox_1.addItem("30");
JButton btnNewButton = new JButton("Clear");
btnNewButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e) {
txtRm.setText(null);
txtrBookDetails.setText(null);
textField.setText(null);
comboBox.setSelectedIndex(0);
comboBox_1.setSelectedIndex(0);
}
});
JButton btnNewButton_1 = new JButton("Confirm");
btnNewButton_1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Confirm();
}
});
JLabel lblNewLabel_3 = new JLabel("Sub Total:");
JLabel lblTotalItem = new JLabel("Total Item:");
JLabel lblTotalPrice = new JLabel("Total Price:");
JLabel lblP = new JLabel("Cash:");
JLabel lblNewLabel_4 = new JLabel("Remainder:");
textField_1 = new JTextField();
textField_1.setEditable(false);
textField_1.setColumns(10);
textField_2 = new JTextField();
textField_2.setEditable(false);
textField_2.setColumns(10);
textField_3 = new JTextField();
textField_3.setEditable(false);
textField_3.setColumns(10);
textField_4 = new JTextField();
textField_4.setColumns(10);
textField_5 = new JTextField();
textField_5.setEditable(false);
textField_5.setColumns(10);
JButton btnNewButton_2 = new JButton("Cash");
btnNewButton_2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Clear();
}
});
JButton btnPrintReceipt = new JButton("Print Receipt");
JLabel lblBookDetails = new JLabel("Book Details");
txtrBookDetails = new JTextArea();
txtrBookDetails.setLineWrap(true);
txtrBookDetails.setWrapStyleWord(true);
txtrBookDetails.setEditable(false);
comboBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e) {
try {
conn = dbCtrl.getConnection();
String y = comboBox.getSelectedItem().toString();
String sql = "select book_title,author,numPages from book where isbn= '"+y+"'";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet result = ps.executeQuery();
StringBuilder strBuilder = new StringBuilder();
while (result.next())
{
strBuilder.append("Title: ");
strBuilder.append(result.getString(1));
strBuilder.append("\nAuthor: ");
strBuilder.append(result.getString(2));
strBuilder.append("\nNumber of Pages: ");
strBuilder.append(result.getString(3));
}
txtrBookDetails.setText(strBuilder.toString());
conn.close();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
JLabel lblSalesDetails = new JLabel("Sales Details");
JTextArea txtrSalesDetails = new JTextArea();
txtrSalesDetails.setLineWrap(true);
txtrSalesDetails.setEditable(false);
txtrSalesDetails.setWrapStyleWord(true);
GroupLayout groupLayout = new GroupLayout(frmBookPointOf.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(121)
.addComponent(btnNewButton, GroupLayout.PREFERRED_SIZE, 77, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.UNRELATED)
.addComponent(btnNewButton_1, GroupLayout.PREFERRED_SIZE, 80, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblNewLabel_1)
.addComponent(lblNewLabel)
.addComponent(lblIsbn)
.addComponent(lblNewLabel_2))
.addGap(69)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
.addComponent(txtRm)
.addComponent(comboBox, GroupLayout.PREFERRED_SIZE, 201, GroupLayout.PREFERRED_SIZE)
.addComponent(comboBox_1, 0, 200, Short.MAX_VALUE)
.addComponent(textField)
.addComponent(textField_1, GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
.addComponent(textField_2, GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
.addComponent(textField_3, GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
.addComponent(textField_4, GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
.addComponent(textField_5, GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnNewButton_2)
.addPreferredGap(ComponentPlacement.UNRELATED)
.addComponent(btnPrintReceipt))))
.addComponent(lblNewLabel_3)
.addComponent(lblTotalItem)
.addComponent(lblTotalPrice)
.addComponent(lblP)
.addComponent(lblNewLabel_4))
.addGap(43)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
.addGroup(groupLayout.createSequentialGroup()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblSalesDetails)
.addComponent(lblBookDetails))
.addGap(251))
.addComponent(txtrSalesDetails, GroupLayout.DEFAULT_SIZE, 412, Short.MAX_VALUE)
.addComponent(txtrBookDetails))
.addContainerGap(33, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(23)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(comboBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblIsbn)
.addComponent(lblBookDetails))
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(txtRm, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblNewLabel))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblNewLabel_1))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(comboBox_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblNewLabel_2))
.addPreferredGap(ComponentPlacement.UNRELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(btnNewButton_1)
.addComponent(btnNewButton)))
.addGroup(groupLayout.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(txtrBookDetails, GroupLayout.PREFERRED_SIZE, 142, GroupLayout.PREFERRED_SIZE)))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblNewLabel_3)
.addComponent(textField_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblSalesDetails))
.addPreferredGap(ComponentPlacement.UNRELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING, false)
.addComponent(txtrSalesDetails, Alignment.LEADING)
.addGroup(Alignment.LEADING, groupLayout.createSequentialGroup()
.addGap(7)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblTotalItem)
.addComponent(textField_2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblTotalPrice)
.addComponent(textField_3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblP)
.addComponent(textField_4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblNewLabel_4)
.addComponent(textField_5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addPreferredGap(ComponentPlacement.UNRELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(btnNewButton_2)
.addComponent(btnPrintReceipt))))
.addContainerGap(89, Short.MAX_VALUE))
);
frmBookPointOf.getContentPane().setLayout(groupLayout);
}
public void Confirm()
{
float numb = 0f;
int numb1 = 0;
int numb2 = 0;
int numb3 = 0;
float numb4 = 0f;
String numbSub = null;
String numbIte = null;
String numbTot = null;
try
{
numb = Float.parseFloat(txtRm.getText());
numb1 = Integer.parseInt(textField.getText());
numb2 = Integer.parseInt(comboBox_1.getSelectedItem().toString());
numb3 = Integer.parseInt(textField_2.getText());
numb4 = Float.parseFloat(textField_3.getText());
}
catch (NumberFormatException ex)
{}
try
{
toServer.writeFloat(numb);
toServer.writeInt(numb1);
toServer.writeInt(numb2);
toServer.writeInt(numb3);
toServer.writeFloat(numb4);
}catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
try
{
numbSub = fromServer.readLine();
numbIte = fromServer.readLine();
numbTot = fromServer.readLine();
} catch (IOException e1)
{
e1.printStackTrace();
}
textField_1.setText(numbSub);
textField_2.setText(numbIte);
textField_3.setText(numbTot);
txtRm.setText(null);
txtrBookDetails.setText(null);
textField.setText(null);
comboBox.setSelectedIndex(0);
comboBox_1.setSelectedIndex(0);
}
public void Clear()
{
float numb5 = 0f;
float numb6 = 0f;
String numbRem = null;
try
{
numb5 = Float.parseFloat(textField_3.getText());
numb6 = Float.parseFloat(textField_4.getText());
}catch (NumberFormatException ex)
{
System.out.println(ex);
}
try
{
toServer.writeFloat(numb5);
toServer.writeFloat(numb6);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try
{
numbRem = fromServer.readLine();
}catch (IOException ex)
{
ex.printStackTrace();
}
textField_5.setText(numbRem);
}
}
服务器:
public class ServerGui{
private JFrame frmBookServer;
private static ServerSocket listener;
private static Socket socket;
private dbController dbCtrl;
private Connection conn;
/**
* Launch the application.
*/
public static void main(String[] args) throws IOException
{
listener = new ServerSocket(9090);
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try {
ServerGui window = new ServerGui();
window.frmBookServer.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*
*/
public ServerGui()
{
frmBookServer = new JFrame();
frmBookServer.setTitle("Book Server");
frmBookServer.setBounds(100, 100, 800, 600);
frmBookServer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnNewButton = new JButton("Start Server");
JButton btnNewButton_1 = new JButton("Stop Server");
JButton btnNewButton_2 = new JButton("Display Sales");
final JTextArea txtrDetailsOfRequest = new JTextArea();
txtrDetailsOfRequest.setEditable(false);
txtrDetailsOfRequest.setWrapStyleWord(true);
GroupLayout groupLayout = new GroupLayout(frmBookServer.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(10)
.addComponent(txtrDetailsOfRequest, GroupLayout.PREFERRED_SIZE, 742, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnNewButton)
.addGap(18)
.addComponent(btnNewButton_1)
.addGap(18)
.addComponent(btnNewButton_2)))
.addGap(22))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(btnNewButton)
.addComponent(btnNewButton_1)
.addComponent(btnNewButton_2))
.addPreferredGap(ComponentPlacement.UNRELATED)
.addComponent(txtrDetailsOfRequest, GroupLayout.PREFERRED_SIZE, 497, GroupLayout.PREFERRED_SIZE)
.addContainerGap(20, Short.MAX_VALUE))
);
frmBookServer.getContentPane().setLayout(groupLayout);
btnNewButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
txtrDetailsOfRequest.setText("Starting Server....");
Thread t = new Thread() {
@Override
public void run()
{
try
{
while(true)
{
socket = listener.accept();
PrintWriter toClient = new PrintWriter(socket.getOutputStream(), true);
toClient.println(new Date().toString());
ServerCalc();
}
}catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
try
{
sleep(10); // milliseconds
}catch (InterruptedException ex) {}
}
};
t.start();
}
});
btnNewButton_1.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
txtrDetailsOfRequest.setText("Closing Server....");
try
{
listener.close();
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
btnNewButton_2.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
dbCtrl = new dbController();
try {
conn = dbCtrl.getConnection();
String sql = "select book_title,quantity from sales";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet result = ps.executeQuery();
StringBuilder strBuilder = new StringBuilder();
while (result.next())
{
strBuilder.append(result.getString(1)).append(" = ").append(result.getString(2));
strBuilder.append("\n");
}
txtrDetailsOfRequest.setText(strBuilder.toString());
conn.close();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
}
public void ServerCalc()
{
try{
PrintWriter toClient = new PrintWriter(socket.getOutputStream(), true);
DataInputStream fromClient = new DataInputStream(socket.getInputStream());
//calculate sub total, total item, total price
float numb = fromClient.readFloat();
int numb1 = fromClient.readInt();
int numb2 = fromClient.readInt();
int numb3 = fromClient.readInt();
float numb4 = fromClient.readFloat();
float dis = (float) (numb2 * 0.01);
float numbSub =numb - ((dis) * numb);
float numbTot =(numbSub * numb1) + numb4;
int numbIte = numb1 + numb3;
toClient.println(numbSub);
toClient.println(numbIte);
toClient.println(numbTot);
//calculate cash remainder
float numb5 = fromClient.readFloat();
float numb6 = fromClient.readFloat();
float numbRem = numb6 - numb5;
toClient.println(numbRem);
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
推荐答案
单击按钮时,会触发 ActionListener
的 actionPerformed
方法事件派遣线程。此线程是负责UI的唯一线程。
When you click on a button, the actionPerformed
method of your ActionListener
is triggered on the Event Dispatch Thread. This thread is the one-and-only thread responsible for the UI.
UI将保持冻结,直到您离开 actionPerformed
方法(因为线程被占用)。因此,如果您的 ActionListener
阻止(例如,使用 fromServer.readLine()
调用),UI将保持冻结状态,直到阻塞调用已结束。
The UI will remain frozen until you leave the actionPerformed
method (as the thread is occupied). So if your ActionListener
blocks (e.g. with your fromServer.readLine()
call), the UI will remain frozen until that blocking call is ended.
这就是为什么一般准则是将长任务卸载到工作线程。 包含更多信息。
That is why the general guideline is to offload long tasks to a worker thread. The Swing concurrency tutorial contains more information.
这篇关于单击按钮后GUI冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!