2

我正在尝试创建一个客户端/服务器应用程序。问题是客户端的确认按钮在第一次输入时有效,但如果我为另一个输入点击相同的按钮,客户端 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();
    }

}
}
4

1 回答 1

8

当您单击一个按钮时,actionPerformed您的方法ActionListener会在事件调度线程上触发。该线程是负责 UI 的唯一线程。

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

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

于 2013-03-25T14:04:35.903 回答