单击按钮后GUI冻结

时间:2013-03-25 13:52:03

标签: java multithreading swing jbutton event-dispatch-thread

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

}
}

1 个答案:

答案 0 :(得分:7)

单击某个按钮时,会在事件发送线程上触发actionPerformed的{​​{1}}方法。该线程是负责UI的唯一线程。

在您离开ActionListener方法(因为线程被占用)之前,UI将保持冻结状态。因此,如果您actionPerformed阻止(例如通过ActionListener通话),则UI将一直处于冻结状态,直到该阻止呼叫结束。

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