单击按钮后GUI冻结

我正在尝试创建一个客户端/服务器应用程序。 问题是客户端的确认按钮第一次输入工作,但如果我为另一个输入点击相同的按钮,客户端GUI将冻结。

为什么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(); } } } 

单击某个按钮时,将在Event Dispatch Thread上触发ActionListeneractionPerformed方法。 该线程是负责UI的唯一线程。

在您离开actionPerformed方法(因为线程被占用)之前,UI将保持冻结状态。 因此,如果您的ActionListener阻塞(例如使用您的fromServer.readLine()调用),UI将保持冻结状态,直到该阻塞调用结束。

这就是为什么一般准则是将长任务卸载到工作线程。 Swing并发教程包含更多信息。