diff --git a/src/main/java/BsK/client/network/handler/ClientHandler.java b/src/main/java/BsK/client/network/handler/ClientHandler.java index 27e0b33..8368475 100644 --- a/src/main/java/BsK/client/network/handler/ClientHandler.java +++ b/src/main/java/BsK/client/network/handler/ClientHandler.java @@ -32,24 +32,16 @@ public class ClientHandler extends SimpleChannelInboundHandler, ResponseListener> listeners = new ConcurrentHashMap<>(); + private static final Map, List>> listeners = new ConcurrentHashMap<>(); public static void addResponseListener(Class responseType, ResponseListener listener) { - listeners.computeIfAbsent(responseType, k -> listener); + listeners.computeIfAbsent(responseType, k -> new ArrayList<>()).add(listener); } public static void clearListeners() { listeners.clear(); } -// public static void removeResponseListener(Class responseType, ResponseListener listener) { -// var listenerList = listeners.get(responseType); -// if (listenerList != null) { -// log.info("Removing listener for response type: {}", responseType.getName()); -// listenerList.remove(listener); -// } -// } - @Override protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) { log.debug("Received message: {}", frame.text()); @@ -90,31 +82,19 @@ public class ClientHandler extends SimpleChannelInboundHandler { log.debug("Key: {}", key.getName()); }); // Process other packets - var responseListeners = listeners.get(packet.getClass()); - if (responseListeners != null) { - notifyListener(responseListeners, packet); + List> responseListeners = listeners.get(packet.getClass()); + if (responseListeners != null && !responseListeners.isEmpty()) { + for (ResponseListener listener : new ArrayList<>(responseListeners)) { + notifyListener(listener, packet); + } } else { - log.warn("No listeners registered for response type: {}", packet.getClass().getName()); + log.debug("No listeners registered for response type: {}", packet.getClass().getName()); } } else { log.warn("Unknown or null packet received: {}", frame.text()); diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/AddDialog/AddDialog.java b/src/main/java/BsK/client/ui/component/CheckUpPage/AddDialog/AddDialog.java index cf4fe0d..52b9233 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/AddDialog/AddDialog.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/AddDialog/AddDialog.java @@ -7,9 +7,7 @@ import BsK.common.packet.req.GetDistrictRequest; import BsK.common.packet.req.GetDoctorGeneralInfo; import BsK.common.packet.req.GetRecentPatientRequest; import BsK.common.packet.req.GetWardRequest; -import BsK.common.packet.res.GetDoctorGeneralInfoResponse; -import BsK.common.packet.res.GetMedInfoResponse; -import BsK.common.packet.res.GetRecentPatientResponse; +import BsK.common.packet.res.*; import BsK.common.util.network.NetworkUtil; import BsK.common.util.text.TextUtils; import lombok.extern.slf4j.Slf4j; @@ -36,7 +34,11 @@ public class AddDialog extends JDialog { private String[] patientColumns = {"Patient ID", "Patient Name", "Patient Year", "Patient Phone" ,"Patient Address"}; private String[][] patientData; private final ResponseListener getRecentPatientResponseListener = this::getRecentPatientHandler; + private final ResponseListener districtResponseListener = this::handleGetDistrictResponse; + private final ResponseListener wardResponseListener = this::handleGetWardResponse; private JComboBox doctorComboBox; + JButton saveButton; + private DefaultComboBoxModel districtModel, wardModel; private void sendGetRecentPatientRequest() { log.info("Sending GetRecentPatientRequest"); @@ -89,7 +91,8 @@ public class AddDialog extends JDialog { // Send request to get the latest 20 patients in the database sendGetRecentPatientRequest(); - + ClientHandler.addResponseListener(GetDistrictResponse.class, districtResponseListener); + ClientHandler.addResponseListener(GetWardResponse.class, wardResponseListener); // Add patent table on the right side // Add a scroll pane to the table @@ -140,11 +143,28 @@ public class AddDialog extends JDialog { gbc.gridwidth = 1; inputPanel.add(new JLabel("Patient name:"), gbc); - gbc.gridwidth = 3; + gbc.gridwidth = 2; gbc.gridx = 1; patientNameField = new JTextField(20); inputPanel.add(patientNameField, gbc); + ImageIcon addIcon = new ImageIcon("src/main/java/BsK/client/ui/assets/icon/add.png"); + JButton addButton = new JButton(addIcon); + addButton.setPreferredSize(new Dimension(30, 30)); // Make the button square + + addButton.addActionListener(e -> { + patientNameField.setText(""); + patientYearField.setText(""); + patientIdField.setText(""); + patientPhoneField.setText(""); + customerAddressField.setText(""); + doctorComboBox.setSelectedIndex(0); + provinceComboBox.setSelectedIndex(0); + }); + gbc.gridwidth = 1; + gbc.gridx = 4; + inputPanel.add(addButton, gbc); + patientNameField.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { @@ -176,6 +196,7 @@ public class AddDialog extends JDialog { String searchText = patientNameField.getText().trim(); if (searchText.isEmpty()) { // Clear selection if search text is empty + saveButton.setEnabled(false); patientTable.clearSelection(); return; } @@ -193,7 +214,11 @@ public class AddDialog extends JDialog { } if (!found) { - patientTable.clearSelection(); // No matches found + patientTable.clearSelection(); + saveButton.setEnabled(false); + } + else { + saveButton.setEnabled(true); } } }); @@ -277,26 +302,11 @@ public class AddDialog extends JDialog { @Override public void actionPerformed(ActionEvent e) { int selectedIndex = provinceComboBox.getSelectedIndex(); - DefaultComboBoxModel districtModel = new DefaultComboBoxModel<>(new String[]{"Quận/Huyện"}); + districtModel = new DefaultComboBoxModel<>(new String[]{"Quận/Huyện"}); districtComboBox.setModel(districtModel); // Set district combo box model if (selectedIndex != 0) { // If the selected index is not 0 (which corresponds to "Tỉnh/Thành phố") NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetDistrictRequest(LocalStorage.provinceToId .get(provinceComboBox.getSelectedItem().toString()))); - while (LocalStorage.districts == null || districtComboBox.getItemCount() <= 1) { - try { - Thread.sleep(100); // Wait for the district data to be fetched - if(LocalStorage.districts != null) { - districtModel = new DefaultComboBoxModel<>(LocalStorage.districts); - districtComboBox.setModel(districtModel); - } - } catch (InterruptedException interruptedException) { - interruptedException.printStackTrace(); - } - } - // Set district combo box model - districtComboBox.setEnabled(true); // Enable district combo box - wardComboBox.setSelectedItem("Xã/Phường"); // Set ward combo box to default value - wardComboBox.setEnabled(false); } else { districtComboBox.setEnabled(false); // Disable district combo box if "Tỉnh/Thành phố" is selected wardComboBox.setEnabled(false); // Disable ward combo box as well @@ -310,26 +320,11 @@ public class AddDialog extends JDialog { @Override public void actionPerformed(ActionEvent e) { int selectedIndex = districtComboBox.getSelectedIndex(); - DefaultComboBoxModel wardModel = new DefaultComboBoxModel<>(new String[]{"Xã/Phường"}); + wardModel = new DefaultComboBoxModel<>(new String[]{"Xã/Phường"}); wardComboBox.setModel(wardModel); // Set district combo box model if (selectedIndex != 0) { // If the selected index is not 0 (which corresponds to "Quận/Huyện") NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetWardRequest(LocalStorage.districtToId .get(districtComboBox.getSelectedItem().toString()))); - log.info("Sending GetWardRequest with district ID: {}", LocalStorage.districtToId - .get(districtComboBox.getSelectedItem().toString())); - while (LocalStorage.wards == null || wardComboBox.getItemCount() <= 1) { - try { - Thread.sleep(100); // Wait for the district data to be fetched - if(LocalStorage.wards != null) { - wardModel = new DefaultComboBoxModel<>(LocalStorage.wards); - wardComboBox.setModel(wardModel); - } - } catch (InterruptedException interruptedException) { - interruptedException.printStackTrace(); - } - } - wardComboBox.setSelectedItem("Xã/Phường"); // Set ward combo box to default value - wardComboBox.setEnabled(true); // Enable ward combo box } else { districtComboBox.setEnabled(false); // Disable district combo box if "Tỉnh/Thành phố" is selected wardComboBox.setEnabled(false); // Disable ward combo box as well @@ -338,7 +333,7 @@ public class AddDialog extends JDialog { }); JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, inputPanel, scrollPane); - splitPane.setResizeWeight(0.1); + splitPane.setResizeWeight(0.6); add(splitPane, BorderLayout.CENTER); @@ -349,10 +344,11 @@ public class AddDialog extends JDialog { }); ButtonPanel.add(closeButton); - JButton saveButton = new JButton("Save"); + saveButton = new JButton("Save"); saveButton.addActionListener(e -> { // Send request to save the patient }); + saveButton.setEnabled(false); ButtonPanel.add(saveButton); add(ButtonPanel, BorderLayout.SOUTH); @@ -402,10 +398,28 @@ public class AddDialog extends JDialog { } catch (InterruptedException e) { throw new RuntimeException(e); } - } } + private void handleGetDistrictResponse(GetDistrictResponse response) { + log.info("Received dialog district data"); + + LocalStorage.districts = response.getDistricts(); + LocalStorage.districtToId = response.getDistrictToId(); + districtModel = new DefaultComboBoxModel<>(LocalStorage.districts); + districtComboBox.setModel(districtModel); + districtComboBox.setEnabled(true); // Enable district combo box + } + + private void handleGetWardResponse(GetWardResponse response) { + log.info("Received dialog ward data"); + LocalStorage.wards = response.getWards(); + wardModel = new DefaultComboBoxModel<>(LocalStorage.wards); + wardComboBox.setModel(wardModel); + wardComboBox.setEnabled(true); // Enable ward combo box + } + + public static void main(String[] args) { // add a button to open the dialog JFrame frame = new JFrame(); diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java b/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java index 7286cb7..0275665 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java @@ -11,11 +11,9 @@ import BsK.client.ui.component.MainFrame; import BsK.client.ui.component.common.DateLabelFormatter; import BsK.client.ui.component.common.RoundedPanel; import BsK.common.packet.req.*; -import BsK.common.packet.res.ErrorResponse; -import BsK.common.packet.res.GetCheckUpQueueResponse; -import BsK.common.packet.res.GetCustomerHistoryResponse; -import BsK.common.packet.res.GetDoctorGeneralInfoResponse; +import BsK.common.packet.res.*; import BsK.common.util.network.NetworkUtil; +import BsK.common.util.text.TextUtils; import lombok.extern.slf4j.Slf4j; import org.jdatepicker.impl.JDatePanelImpl; import org.jdatepicker.impl.JDatePickerImpl; @@ -44,7 +42,8 @@ public class CheckUpPage extends JPanel { private JTable table1, historyTable; private final ResponseListener checkUpQueueListener = this::handleGetCheckUpQueueResponse; private final ResponseListener customerHistoryListener = this::handleGetCustomerHistoryResponse; - + private final ResponseListener districtResponseListener = this::handleGetDistrictResponse; + private final ResponseListener wardResponseListener = this::handleGetWardResponse; private JTextField checkupIdField, customerLastNameField, customerFirstNameField,customerAddressField, customerPhoneField, customerIdField; private JTextArea symptomsField, diagnosisField, notesField; private JComboBox doctorComboBox, statusComboBox, genderComboBox, provinceComboBox, districtComboBox, wardComboBox; @@ -58,20 +57,47 @@ public class CheckUpPage extends JPanel { private AddDialog addDialog = null; private int previousSelectedRow = -1; private boolean saved = false; - + private DefaultComboBoxModel districtModel, wardModel; boolean returnCell = false; public void updateQueue() { ClientHandler.addResponseListener(GetCheckUpQueueResponse.class, checkUpQueueListener); NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetCheckUpQueueRequest()); } + private int findProvinceIndex(String province) { + for (int i = 0; i < LocalStorage.provinces.length; i++) { + if (TextUtils.removeAccents(LocalStorage.provinces[i]).equals(TextUtils.removeAccents(province))) { + return i; + } + } + return -1; + } + private int findDistrictIndex(String district) { + for (int i = 0; i < LocalStorage.districts.length; i++) { + if (TextUtils.removeAccents(LocalStorage.districts[i]).equals(TextUtils.removeAccents(district))) { + return i; + } + } + return -1; + } + + private int findWardIndex(String ward) { + for (int i = 0; i < LocalStorage.wards.length; i++) { + if (TextUtils.removeAccents(LocalStorage.wards[i]).equals(TextUtils.removeAccents(ward))) { + return i; + } + } + return -1; + } public CheckUpPage(MainFrame mainFrame) { setLayout(new BorderLayout()); // add history listener ClientHandler.addResponseListener(GetCustomerHistoryResponse.class, customerHistoryListener); + ClientHandler.addResponseListener(GetDistrictResponse.class, districtResponseListener); + ClientHandler.addResponseListener(GetWardResponse.class, wardResponseListener); updateQueue(); // Navigation bar @@ -349,26 +375,11 @@ public class CheckUpPage extends JPanel { @Override public void actionPerformed(ActionEvent e) { int selectedIndex = provinceComboBox.getSelectedIndex(); - DefaultComboBoxModel districtModel = new DefaultComboBoxModel<>(new String[]{"Quận/Huyện"}); + districtModel = new DefaultComboBoxModel<>(new String[]{"Quận/Huyện"}); districtComboBox.setModel(districtModel); // Set district combo box model if (selectedIndex != 0) { // If the selected index is not 0 (which corresponds to "Tỉnh/Thành phố") NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetDistrictRequest(LocalStorage.provinceToId .get(provinceComboBox.getSelectedItem().toString()))); - while (LocalStorage.districts == null || districtComboBox.getItemCount() <= 1) { - try { - Thread.sleep(100); // Wait for the district data to be fetched - if(LocalStorage.districts != null) { - districtModel = new DefaultComboBoxModel<>(LocalStorage.districts); - districtComboBox.setModel(districtModel); - } - } catch (InterruptedException interruptedException) { - interruptedException.printStackTrace(); - } - } - // Set district combo box model - districtComboBox.setEnabled(true); // Enable district combo box - wardComboBox.setSelectedItem("Xã/Phường"); // Set ward combo box to default value - wardComboBox.setEnabled(false); } else { districtComboBox.setEnabled(false); // Disable district combo box if "Tỉnh/Thành phố" is selected wardComboBox.setEnabled(false); // Disable ward combo box as well @@ -382,28 +393,12 @@ public class CheckUpPage extends JPanel { @Override public void actionPerformed(ActionEvent e) { int selectedIndex = districtComboBox.getSelectedIndex(); - DefaultComboBoxModel wardModel = new DefaultComboBoxModel<>(new String[]{"Xã/Phường"}); + wardModel = new DefaultComboBoxModel<>(new String[]{"Xã/Phường"}); wardComboBox.setModel(wardModel); // Set district combo box model if (selectedIndex != 0) { // If the selected index is not 0 (which corresponds to "Quận/Huyện") NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetWardRequest(LocalStorage.districtToId .get(districtComboBox.getSelectedItem().toString()))); - log.info("Sending GetWardRequest with district ID: {}", LocalStorage.districtToId - .get(districtComboBox.getSelectedItem().toString())); - while (LocalStorage.wards == null || wardComboBox.getItemCount() <= 1) { - try { - Thread.sleep(100); // Wait for the district data to be fetched - if(LocalStorage.wards != null) { - wardModel = new DefaultComboBoxModel<>(LocalStorage.wards); - wardComboBox.setModel(wardModel); - } - } catch (InterruptedException interruptedException) { - interruptedException.printStackTrace(); - } - } - wardComboBox.setSelectedItem("Xã/Phường"); // Set ward combo box to default value - wardComboBox.setEnabled(true); // Enable ward combo box } else { - districtComboBox.setEnabled(false); // Disable district combo box if "Tỉnh/Thành phố" is selected wardComboBox.setEnabled(false); // Disable ward combo box as well } } @@ -717,7 +712,6 @@ public class CheckUpPage extends JPanel { String customerGender = queue[selectedRow][14]; String customerDob = queue[selectedRow][15]; - log.info("Selected customer: {}", customerId); checkupIdField.setText(checkupId); @@ -781,8 +775,54 @@ public class CheckUpPage extends JPanel { customerHeightSpinner.setValue(Double.parseDouble(customerHeight)); NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetCustomerHistoryRequest(Integer.parseInt(queue[selectedRow][9]))); + + // Extract province, district, ward from the address + String[] addressParts = customerAddress.split(", "); + if (addressParts.length == 4) { + String address = addressParts[0]; + String ward = addressParts[1]; + String district = addressParts[2]; + String province = addressParts[3]; + customerAddressField.setText(address); + provinceComboBox.setSelectedIndex(findProvinceIndex(province)); + try { + Thread.sleep(100); + while(!districtComboBox.isEditable()) { + districtComboBox.setSelectedIndex(findDistrictIndex(district)); + break; + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + try { + Thread.sleep(100); + while(!wardComboBox.isEditable()) { + wardComboBox.setSelectedIndex(findWardIndex(ward)); + break; + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } } + private void handleGetDistrictResponse(GetDistrictResponse response) { + log.info("Received district data"); + + LocalStorage.districts = response.getDistricts(); + LocalStorage.districtToId = response.getDistrictToId(); + districtModel = new DefaultComboBoxModel<>(LocalStorage.districts); + districtComboBox.setModel(districtModel); + districtComboBox.setEnabled(true); // Enable district combo box + } + + private void handleGetWardResponse(GetWardResponse response) { + log.info("Received ward data"); + LocalStorage.wards = response.getWards(); + wardModel = new DefaultComboBoxModel<>(LocalStorage.wards); + wardComboBox.setModel(wardModel); + wardComboBox.setEnabled(true); // Enable ward combo box + } private void handleGetCustomerHistoryResponse(GetCustomerHistoryResponse response) { log.info("Received customer history");