diff --git a/src/main/java/BsK/client/LocalStorage.java b/src/main/java/BsK/client/LocalStorage.java index d6adb58..83e53e0 100644 --- a/src/main/java/BsK/client/LocalStorage.java +++ b/src/main/java/BsK/client/LocalStorage.java @@ -17,10 +17,7 @@ public class LocalStorage { public static String ClinicPhone = "0123456789"; public static String[] doctorsName; public static String[] provinces; - public static String[] districts; public static String[] wards; public static HashMap provinceToId; - public static HashMap districtToId; - public static HashMap cachedDistricts; // cache local areas later will do public static HashMap cachedWards; // cache local areas later will do } \ No newline at end of file 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 3cd0884..2919959 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 @@ -37,29 +37,44 @@ public class AddDialog extends JDialog { private JTextField patientPhoneField; private JTextField cccdField; private JComboBox patientGenderField; - private JComboBox wardComboBox, districtComboBox, provinceComboBox; + private JComboBox wardComboBox, provinceComboBox; private JTextField customerAddressField; private DefaultTableModel patientTableModel; private JTable patientTable; private String[] patientColumns = {"Mã BN", "Tên Bệnh Nhân", "Năm sinh", "Số điện thoại" ,"Địa chỉ"}; private String[][] patientData; private final ResponseListener getRecentPatientResponseListener = this::getRecentPatientHandler; - private final ResponseListener districtResponseListener = this::handleGetDistrictResponse; private final ResponseListener wardResponseListener = this::handleGetWardResponse; private final ResponseListener addPatientResponseListener = this::handleAddPatientResponse; private final ResponseListener addCheckupResponseListener = this::handleAddCheckupResponse; private JComboBox doctorComboBox; private JComboBox checkupTypeComboBox; JButton saveButton; - private DefaultComboBoxModel districtModel, wardModel; + private DefaultComboBoxModel wardModel; private JDatePickerImpl dobPicker; private JButton addPatientButton; private JButton clearButton; + private String targetWard = null; private void handleAddCheckupResponse(AddCheckupResponse response) { log.info("Received AddCheckupResponse"); if (response.isSuccess()) { - JOptionPane.showMessageDialog(this, "Thêm bệnh nhân vào khám thành công"); + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + + JLabel messageLabel = new JLabel("Thêm bệnh nhân vào khám thành công"); + messageLabel.setAlignmentX(Component.CENTER_ALIGNMENT); + messageLabel.setFont(new Font("Arial", Font.PLAIN, 16)); + + JLabel queueLabel = new JLabel("Số thứ tự: " + response.getQueueNumber()); + queueLabel.setFont(new Font("Arial", Font.BOLD, 28)); + queueLabel.setAlignmentX(Component.CENTER_ALIGNMENT); + + panel.add(messageLabel); + panel.add(Box.createVerticalStrut(10)); + panel.add(queueLabel); + + JOptionPane.showMessageDialog(this, panel, "Thành công", JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(this, response.getError()); } @@ -93,15 +108,6 @@ public class AddDialog extends JDialog { 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))) { @@ -111,6 +117,7 @@ public class AddDialog extends JDialog { return -1; } + @Override public void dispose() { // Clean up listeners @@ -118,7 +125,6 @@ public class AddDialog extends JDialog { ClientHandler.deleteListener(AddCheckupResponse.class, addCheckupResponseListener); ClientHandler.deleteListener(AddPatientResponse.class, addPatientResponseListener); ClientHandler.deleteListener(GetRecentPatientResponse.class, getRecentPatientResponseListener); - ClientHandler.deleteListener(GetDistrictResponse.class, districtResponseListener); ClientHandler.deleteListener(GetWardResponse.class, wardResponseListener); super.dispose(); } @@ -218,7 +224,6 @@ 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); ClientHandler.addResponseListener(AddPatientResponse.class, addPatientResponseListener); ClientHandler.addResponseListener(AddCheckupResponse.class, addCheckupResponseListener); @@ -479,7 +484,7 @@ public class AddDialog extends JDialog { addressInfoPanel.add(customerAddressField, gbc); gbc.weightx = 0.0; - // Province, District, Ward ComboBoxes on a single line (Row 1) + // Province, Ward, Ward ComboBoxes on a single line (Row 1) gbc.gridy++; gbc.gridx = 0; // Start from the first column for the combo boxes gbc.gridwidth = 1; // Each combo box takes 1 logical column in this setup @@ -490,20 +495,14 @@ public class AddDialog extends JDialog { addressInfoPanel.add(provinceComboBox, gbc); gbc.gridx = 1; - districtModel = new DefaultComboBoxModel<>(new String[]{"Quận/Huyện"}); - districtComboBox = new JComboBox<>(districtModel); - districtComboBox.setFont(textFont); - districtComboBox.setPreferredSize(comboBoxSize); - districtComboBox.setEnabled(false); - addressInfoPanel.add(districtComboBox, gbc); - - gbc.gridx = 2; - wardModel = new DefaultComboBoxModel<>(new String[]{"Phường/Xã"}); + wardModel = new DefaultComboBoxModel<>(new String[]{"Quận/Huyện"}); wardComboBox = new JComboBox<>(wardModel); wardComboBox.setFont(textFont); wardComboBox.setPreferredSize(comboBoxSize); wardComboBox.setEnabled(false); addressInfoPanel.add(wardComboBox, gbc); + + gbc.gridx = 2; gbc.weightx = 0.0; // Reset weightx for any subsequent components in this panel gbc.gridwidth = 1; // Reset gridwidth @@ -552,35 +551,20 @@ public class AddDialog extends JDialog { @Override public void actionPerformed(ActionEvent e) { int selectedIndex = provinceComboBox.getSelectedIndex(); - districtModel = new DefaultComboBoxModel<>(new String[]{"Quận/Huyện"}); - districtComboBox.setModel(districtModel); // Set district combo box model + wardModel = new DefaultComboBoxModel<>(new String[]{"Quận/Huyện"}); + wardComboBox.setModel(wardModel); // Set ward 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 + NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetWardRequest(LocalStorage.provinceToId .get(provinceComboBox.getSelectedItem().toString()))); } 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 + wardComboBox.setEnabled(false); // Disable ward combo box if "Tỉnh/Thành phố" is selected } } }); - // District ComboBox Listener - districtComboBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - int selectedIndex = districtComboBox.getSelectedIndex(); - 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()))); - } 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 - } - } - }); + // Ward ComboBox Listener + inputPanel.setMinimumSize(new Dimension(400, 0)); // Wrap inputPanel in a JScrollPane @@ -634,15 +618,40 @@ public class AddDialog extends JDialog { JOptionPane.showMessageDialog(this, "Bạn đã chọn bệnh nhân rồi"); return; } - String patientName = patientNameField.getText(); - String patientPhone = patientPhoneField.getText(); + String patientName = patientNameField.getText().trim(); + String patientPhone = patientPhoneField.getText().trim(); String patientGender = (String) patientGenderField.getSelectedItem(); - String customerAddress = customerAddressField.getText(); + String customerAddress = customerAddressField.getText().trim(); String province = (String) provinceComboBox.getSelectedItem(); - String district = (String) districtComboBox.getSelectedItem(); String ward = (String) wardComboBox.getSelectedItem(); - String address = String.join(", ", customerAddress, ward, district, province); - String cccd = cccdField.getText(); + String cccd = cccdField.getText().trim(); + + // Validate required fields + if (patientName.isEmpty() || patientPhone.isEmpty() || customerAddress.isEmpty() || + dobPicker.getJFormattedTextField().getText().isEmpty()) { + JOptionPane.showMessageDialog(this, "Vui lòng điền đầy đủ thông tin"); + return; + } + + // Check if province is selected + if (provinceComboBox.getSelectedIndex() <= 0) { + JOptionPane.showMessageDialog(this, "Vui lòng chọn tỉnh/thành phố"); + return; + } + + // Check if ward is selected and enabled + if (wardComboBox.isEnabled() && wardComboBox.getSelectedIndex() <= 0) { + JOptionPane.showMessageDialog(this, "Vui lòng chọn quận/huyện"); + return; + } + + // Build the full address with proper format + String address; + if (wardComboBox.isEnabled() && wardComboBox.getSelectedIndex() > 0) { + address = String.join(", ", customerAddress, ward, province); + } else { + address = String.join(", ", customerAddress, province); + } //split name into first name and last name String[] nameParts = patientName.split(" "); @@ -656,12 +665,6 @@ public class AddDialog extends JDialog { } String lastNameStr = lastName.toString(); - // check if dobPicker is not null - if (patientName.isEmpty() || patientPhone.isEmpty() || customerAddress.isEmpty() || dobPicker.getJFormattedTextField().getText().isEmpty()) { - JOptionPane.showMessageDialog(this, "Vui lòng điền đầy đủ thông tin"); - return; - } - String dateText = dobPicker.getJFormattedTextField().getText(); SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); @@ -687,13 +690,14 @@ public class AddDialog extends JDialog { // Reset combo boxes patientGenderField.setSelectedIndex(0); provinceComboBox.setSelectedIndex(0); - districtComboBox.setSelectedIndex(0); - districtComboBox.setEnabled(false); wardComboBox.setSelectedIndex(0); wardComboBox.setEnabled(false); doctorComboBox.setSelectedIndex(0); checkupTypeComboBox.setSelectedIndex(0); + // Reset targetWard + targetWard = null; + // Clear date picker dobPicker.getModel().setValue(null); dobPicker.getJFormattedTextField().setText(""); @@ -731,34 +735,41 @@ public class AddDialog extends JDialog { patientGenderField.setSelectedItem(patientGender); cccdField.setText(patientCccd); - // Extract province, district, ward from the address - String[] addressParts = patientAddress.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; + // Reset targetWard + targetWard = null; + + // Extract province, ward, and detailed address from the full address + if (patientAddress != null && !patientAddress.isEmpty()) { + String[] addressParts = patientAddress.split(", "); + + if (addressParts.length >= 2) { + // Last part is province, second last is ward, everything else is address + String province = addressParts[addressParts.length - 1]; + targetWard = addressParts[addressParts.length - 2]; + + // Combine remaining parts as the detailed address + StringBuilder detailedAddress = new StringBuilder(); + for (int i = 0; i < addressParts.length - 2; i++) { + detailedAddress.append(addressParts[i]); + if (i < addressParts.length - 3) { + detailedAddress.append(", "); + } } - } 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); + + customerAddressField.setText(detailedAddress.toString()); + provinceComboBox.setSelectedIndex(findProvinceIndex(province)); + // Ward will be set in the response handler using targetWard + } else { + // If address doesn't have enough parts, just use the whole address as detailed address + customerAddressField.setText(patientAddress); + provinceComboBox.setSelectedIndex(0); // Select default province } + } else { + // Clear address fields if no address is available + customerAddressField.setText(""); + provinceComboBox.setSelectedIndex(0); } + SimpleDateFormat dobFormat; try { Date parsedDate; @@ -797,24 +808,26 @@ public class AddDialog extends JDialog { } - 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 + + // Set the ward after the ward data is loaded + if (targetWard != null) { + int wardIndex = findWardIndex(targetWard); + if (wardIndex >= 0) { + wardComboBox.setSelectedIndex(wardIndex); + } + // We've handled this targetWard, so clear it + targetWard = null; + } } + private void setupDateFieldForDirectInput(JDatePickerImpl datePicker) { JFormattedTextField textField = datePicker.getJFormattedTextField(); 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 69660cf..17f76fa 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java @@ -164,7 +164,6 @@ public class CheckUpPage extends JPanel { private final ResponseListener checkUpQueueUpdateListener = this::handleGetCheckUpQueueUpdateResponse; private final ResponseListener checkUpQueueListener = this::handleGetCheckUpQueueResponse; private final ResponseListener patientHistoryListener = this::handleGetPatientHistoryResponse; - private final ResponseListener districtResponseListener = this::handleGetDistrictResponse; private final ResponseListener wardResponseListener = this::handleGetWardResponse; private final ResponseListener callPatientResponseListener = this::handleCallPatientResponse; private final ResponseListener orderInfoByCheckupListener = this::handleGetOrderInfoByCheckupResponse; @@ -174,7 +173,7 @@ public class CheckUpPage extends JPanel { private JTextField checkupIdField, customerLastNameField, customerFirstNameField,customerAddressField, customerPhoneField, customerIdField, customerCccdDdcnField; private JTextArea suggestionField, diagnosisField, conclusionField; // Changed symptomsField to suggestionField private JTextPane notesField; - private JComboBox doctorComboBox, statusComboBox, genderComboBox, provinceComboBox, districtComboBox, wardComboBox, checkupTypeComboBox, templateComboBox, orientationComboBox; // Added orientationComboBox + private JComboBox doctorComboBox, statusComboBox, genderComboBox, provinceComboBox, wardComboBox, checkupTypeComboBox, templateComboBox, orientationComboBox; // Added orientationComboBox private JComboBox ultrasoundDoctorComboBox; private JCheckBox needRecheckupCheckbox; // Checkbox to indicate if re-checkup is needed private JSpinner customerWeightSpinner, customerHeightSpinner, patientHeartRateSpinner, bloodPressureSystolicSpinner, bloodPressureDiastolicSpinner; @@ -188,10 +187,9 @@ public class CheckUpPage extends JPanel { private AddDialog addDialog = null; private String selectedCheckupId = null; // Use checkupId to track selection instead of row index private boolean saved = true; // Initially true, changed when patient selected or dialog opened. - private DefaultComboBoxModel districtModel, wardModel; + private DefaultComboBoxModel wardModel; - // Variables to store target district and ward when loading patient address - private String targetDistrict = null; + // Variables to store target ward and ward when loading patient address private String targetWard = null; private JComboBox callRoomComboBox; private JButton callPatientButton; @@ -321,15 +319,6 @@ public class CheckUpPage extends JPanel { 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))) { @@ -358,7 +347,6 @@ public class CheckUpPage extends JPanel { ClientHandler.addResponseListener(GetCheckUpQueueUpdateResponse.class, checkUpQueueUpdateListener); ClientHandler.addResponseListener(GetPatientHistoryResponse.class, patientHistoryListener); ClientHandler.addResponseListener(GetOrderInfoByCheckupRes.class, orderInfoByCheckupListener); - ClientHandler.addResponseListener(GetDistrictResponse.class, districtResponseListener); ClientHandler.addResponseListener(GetWardResponse.class, wardResponseListener); ClientHandler.addResponseListener(CallPatientResponse.class, callPatientResponseListener); ClientHandler.addResponseListener(GetAllTemplatesRes.class, getAllTemplatesListener); @@ -426,6 +414,9 @@ public class CheckUpPage extends JPanel { addPatientButton.setBorder(BorderFactory.createEmptyBorder(8, 20, 8, 20)); // Reduced vertical padding from 10 to 8 addPatientButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); addPatientButton.addActionListener(e -> { + // Unregister the listener from the parent page to avoid conflicts + ClientHandler.deleteListener(GetWardResponse.class, wardResponseListener); + // Dispose any existing dialog to ensure clean listener removal if (addDialog != null) { addDialog.dispose(); @@ -435,9 +426,18 @@ public class CheckUpPage extends JPanel { public void dispose() { super.dispose(); addDialog = null; // Clear the reference when dialog is disposed + // Re-register the listener after the dialog is actually disposed + ClientHandler.addResponseListener(GetWardResponse.class, wardResponseListener); + log.info("AddDialog disposed, re-registered ward listener for CheckUpPage."); } }; - addDialog.setVisible(true); + + // Show the dialog without blocking the main thread + SwingUtilities.invokeLater(() -> { + addDialog.setVisible(true); + // The re-registration will now happen inside the dispose() override + }); + updateUpdateQueue(); }); @@ -765,14 +765,7 @@ public class CheckUpPage extends JPanel { patientInfoInnerPanel.add(provinceComboBox, gbcPatient); gbcPatient.gridx = 2; - districtModel = new DefaultComboBoxModel<>(new String[]{"Huyện"}); - districtComboBox = new JComboBox<>(districtModel); - districtComboBox.setFont(fieldFont); - districtComboBox.setEnabled(false); - patientInfoInnerPanel.add(districtComboBox, gbcPatient); - - gbcPatient.gridx = 3; - wardModel = new DefaultComboBoxModel<>(new String[]{"Phường"}); + wardModel = new DefaultComboBoxModel<>(new String[]{"Huyện"}); wardComboBox = new JComboBox<>(wardModel); wardComboBox.setFont(fieldFont); wardComboBox.setEnabled(false); @@ -834,40 +827,19 @@ public class CheckUpPage extends JPanel { if (selectedProvince != null && !selectedProvince.equals("Tỉnh/Thành phố")) { String provinceId = LocalStorage.provinceToId.get(selectedProvince); if (provinceId != null) { - NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetDistrictRequest(provinceId)); - districtComboBox.setEnabled(false); - districtModel.removeAllElements(); - districtModel.addElement("Đang tải quận/huyện..."); + NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetWardRequest(provinceId)); wardComboBox.setEnabled(false); wardModel.removeAllElements(); - wardModel.addElement("Phường"); + wardModel.addElement("Đang tải quận/huyện..."); } } else { - districtComboBox.setEnabled(false); - districtModel.removeAllElements(); - districtModel.addElement("Huyện"); wardComboBox.setEnabled(false); wardModel.removeAllElements(); - wardModel.addElement("Phường"); + wardModel.addElement("Huyện"); } }); - districtComboBox.addActionListener(e -> { - String selectedDistrict = (String) districtComboBox.getSelectedItem(); - if (selectedDistrict != null && LocalStorage.districtToId != null && LocalStorage.districtToId.containsKey(selectedDistrict)) { - String districtId = LocalStorage.districtToId.get(selectedDistrict); - if (districtId != null) { - NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetWardRequest(districtId)); - wardComboBox.setEnabled(false); - wardModel.removeAllElements(); - wardModel.addElement("Đang tải phường/xã..."); - } - } else { - wardComboBox.setEnabled(false); - wardModel.removeAllElements(); - wardModel.addElement("Phường"); - } - }); + // Checkup Info Section JPanel checkupInfoPanel = new JPanel(new BorderLayout(10, 5)); // Reduced vertical gap from 10 to 5 @@ -1810,7 +1782,7 @@ public class CheckUpPage extends JPanel { customerLastNameField.getText() + " " + customerFirstNameField.getText(), dobPicker.getJFormattedTextField().getText(), customerPhoneField.getText(), genderComboBox.getSelectedItem().toString(), - customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (districtComboBox.getSelectedItem() != null ? districtComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""), + customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""), doctorComboBox.getSelectedItem().toString(), diagnosisField.getText(), conclusionField.getText(), regularMeds.toArray(new String[0][]), @@ -1866,7 +1838,7 @@ public class CheckUpPage extends JPanel { customerLastNameField.getText() + " " + customerFirstNameField.getText(), dobPicker.getJFormattedTextField().getText(), (String) genderComboBox.getSelectedItem(), - customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (districtComboBox.getSelectedItem() != null ? districtComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""), + customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""), (String) doctorComboBox.getSelectedItem(), (String) ultrasoundDoctorComboBox.getSelectedItem(), datePicker.getJFormattedTextField().getText(), @@ -1941,7 +1913,7 @@ public class CheckUpPage extends JPanel { customerLastNameField.getText() + " " + customerFirstNameField.getText(), dobPicker.getJFormattedTextField().getText(), (String) genderComboBox.getSelectedItem(), - customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (districtComboBox.getSelectedItem() != null ? districtComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""), + customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""), (String) doctorComboBox.getSelectedItem(), (String) ultrasoundDoctorComboBox.getSelectedItem(), datePicker.getJFormattedTextField().getText(), @@ -2270,44 +2242,47 @@ public class CheckUpPage extends JPanel { NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetOrderInfoByCheckupReq(selectedPatient.getCheckupId())); String fullAddress = selectedPatient.getCustomerAddress(); String[] addressParts = fullAddress.split(", "); - if (addressParts.length > 0) customerAddressField.setText(addressParts[0]); - else if (fullAddress != null) customerAddressField.setText(fullAddress); - if (addressParts.length == 4) { - String ward = addressParts[1]; - String district = addressParts[2]; - String province = addressParts[3]; + // Reset target ward + targetWard = null; + + if (addressParts.length >= 2) { + // Last part is province, second last is ward, everything else is address + String province = addressParts[addressParts.length - 1]; + targetWard = addressParts[addressParts.length - 2]; + log.info("Province: {}", province); + log.info("Target ward: {}", targetWard); + // Combine remaining parts as the detailed address + StringBuilder detailedAddress = new StringBuilder(); + for (int i = 0; i < addressParts.length - 2; i++) { + detailedAddress.append(addressParts[i]); + if (i < addressParts.length - 3) { + detailedAddress.append(", "); + } + } - // Store target district and ward for later setting - targetDistrict = district; - targetWard = ward; + customerAddressField.setText(detailedAddress.toString()); int provinceIdx = findProvinceIndex(province); if (provinceIdx != -1) { provinceComboBox.setSelectedIndex(provinceIdx); - // The province selection will trigger district loading automatically - // District and ward will be set in the response handlers + // The province selection will trigger ward loading automatically + // Ward will be set in the response handler using targetWard } else { log.warn("Province not found: {}", province); - districtModel.removeAllElements(); districtModel.addElement("Huyện"); districtComboBox.setEnabled(false); - wardModel.removeAllElements(); wardModel.addElement("Phường"); wardComboBox.setEnabled(false); - targetDistrict = null; + wardModel.removeAllElements(); wardModel.addElement("Huyện"); wardComboBox.setEnabled(false); targetWard = null; } - } else if (addressParts.length > 1) { // Handle cases with partial address - provinceComboBox.setSelectedIndex(0); - districtModel.removeAllElements(); districtModel.addElement("Huyện"); districtComboBox.setEnabled(false); - wardModel.removeAllElements(); wardModel.addElement("Phường"); wardComboBox.setEnabled(false); - targetDistrict = null; - targetWard = null; - log.warn("Address format not fully standard ({} parts): {}", addressParts.length, fullAddress); - } else { + } else if (addressParts.length == 1) { + // Handle case with only one part customerAddressField.setText(fullAddress); provinceComboBox.setSelectedIndex(0); - districtModel.removeAllElements(); districtModel.addElement("Huyện"); districtComboBox.setEnabled(false); - wardModel.removeAllElements(); wardModel.addElement("Phường"); wardComboBox.setEnabled(false); - targetDistrict = null; - targetWard = null; + wardModel.removeAllElements(); wardModel.addElement("Huyện"); wardComboBox.setEnabled(false); + } else { + // Empty address case + customerAddressField.setText(""); + provinceComboBox.setSelectedIndex(0); + wardModel.removeAllElements(); wardModel.addElement("Huyện"); wardComboBox.setEnabled(false); } // Setup for Supersonic View media for the NEWLY selected patient @@ -2352,33 +2327,6 @@ public class CheckUpPage extends JPanel { saved = false; // Data loaded, any change from now on is "unsaved" until save button. } - private void handleGetDistrictResponse(GetDistrictResponse response) { - SwingUtilities.invokeLater(() -> { - log.info("Received district data"); - LocalStorage.districts = response.getDistricts(); - LocalStorage.districtToId = response.getDistrictToId(); - districtModel.removeAllElements(); - for (String district : LocalStorage.districts) { districtModel.addElement(district); } - districtComboBox.setEnabled(true); - - // If we have a target district to set, try to set it now - if (targetDistrict != null) { - int districtIdx = findDistrictIndex(targetDistrict); - if (districtIdx != -1) { - log.info("Setting target district: {}", targetDistrict); - districtComboBox.setSelectedIndex(districtIdx); - // The district selection will trigger ward loading automatically - } else { - log.warn("Target district not found in loaded data: {}", targetDistrict); - targetDistrict = null; - targetWard = null; - } - } - - wardModel.removeAllElements(); wardModel.addElement("Phường"); wardComboBox.setEnabled(false); - }); - } - private void handleGetWardResponse(GetWardResponse response) { SwingUtilities.invokeLater(() -> { log.info("Received ward data"); @@ -2393,9 +2341,7 @@ public class CheckUpPage extends JPanel { if (wardIdx != -1) { log.info("Setting target ward: {}", targetWard); wardComboBox.setSelectedIndex(wardIdx); - // Clear the target values since we've successfully set them - targetDistrict = null; - targetWard = null; + // The ward selection will trigger ward loading automatically } else { log.warn("Target ward not found in loaded data: {}", targetWard); targetWard = null; @@ -2404,6 +2350,7 @@ public class CheckUpPage extends JPanel { }); } + private void handleGetPatientHistoryResponse(GetPatientHistoryResponse response) { SwingUtilities.invokeLater(() -> { log.info("Received patient history"); @@ -4537,12 +4484,10 @@ public class CheckUpPage extends JPanel { // Construct full address String address = customerAddressField.getText(); String ward = (String) wardComboBox.getSelectedItem(); - String district = (String) districtComboBox.getSelectedItem(); String province = (String) provinceComboBox.getSelectedItem(); String fullAddress = String.format("%s, %s, %s, %s", address, - ward != null && !ward.equals("Phường") ? ward : "", - district != null && !district.equals("Huyện") ? district : "", + ward != null && !ward.equals("Huyện") ? ward : "", province != null && !province.equals("Tỉnh/Thành phố") ? province : "" ).replaceAll(", ,", ",").trim().replaceAll(",$", ""); @@ -4765,14 +4710,13 @@ public class CheckUpPage extends JPanel { customerCccdDdcnField.setText(""); // Clear target address values - targetDistrict = null; targetWard = null; if (doctorComboBox.getItemCount() > 0) doctorComboBox.setSelectedIndex(0); statusComboBox.setSelectedIndex(0); genderComboBox.setSelectedIndex(0); if (provinceComboBox.getItemCount() > 0) provinceComboBox.setSelectedIndex(0); - // district and ward will be cleared by province selection listener + // ward and ward will be cleared by province selection listener checkupTypeComboBox.setSelectedIndex(0); if (templateComboBox.getItemCount() > 0) templateComboBox.setSelectedIndex(0); diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/Debug.java b/src/main/java/BsK/client/ui/component/CheckUpPage/Debug.java new file mode 100644 index 0000000..0e1490c --- /dev/null +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/Debug.java @@ -0,0 +1,49 @@ +package BsK.client.ui.component.CheckUpPage; + +import BsK.client.LocalStorage; +import BsK.client.network.handler.ClientHandler; +import BsK.common.packet.res.GetWardResponse; + +import lombok.extern.slf4j.Slf4j; + +/** + * Debug class to help troubleshoot ward loading issues + * This is just a test class and should be removed after fixing the issue + */ +@Slf4j +public class Debug { + + /** + * Log ward data when received to help diagnose any issues + */ + public static void logWardInfo() { + log.info("DEBUG: Setting up ward monitoring"); + + ClientHandler.addResponseListener(GetWardResponse.class, (response) -> { + log.info("DEBUG: Received ward response with {} wards", + (response.getWards() != null ? response.getWards().length - 1 : 0)); + + if (response.getWards() == null || response.getWards().length <= 1) { + log.warn("DEBUG: Ward data is empty!"); + return; + } + + log.info("DEBUG: First 5 wards:"); + for (int i = 0; i < Math.min(5, response.getWards().length); i++) { + log.info("DEBUG: Ward[{}] = '{}'", i, response.getWards()[i]); + } + + log.info("DEBUG: First 5 ward IDs:"); + int count = 0; + for (String ward : response.getWardToId().keySet()) { + if (count >= 5) break; + log.info("DEBUG: Ward '{}' -> ID '{}'", ward, response.getWardToId().get(ward)); + count++; + } + + // Check LocalStorage after processing + log.info("DEBUG: LocalStorage.wards now contains {} elements", + (LocalStorage.wards != null ? LocalStorage.wards.length : 0)); + }); + } +} \ No newline at end of file diff --git a/src/main/java/BsK/client/ui/component/QueueViewPage/QueueViewPage.java b/src/main/java/BsK/client/ui/component/QueueViewPage/QueueViewPage.java index b564c42..0df6027 100644 --- a/src/main/java/BsK/client/ui/component/QueueViewPage/QueueViewPage.java +++ b/src/main/java/BsK/client/ui/component/QueueViewPage/QueueViewPage.java @@ -56,11 +56,11 @@ public class QueueViewPage extends JFrame { clinicInfoPanel.setOpaque(false); clinicNameLabel = new JLabel("Phòng khám: Đang tải..."); - styleLabelForTv(clinicNameLabel, 28, Font.BOLD, Color.WHITE); + styleLabelForTv(clinicNameLabel, 40, Font.BOLD, Color.WHITE); clinicAddressLabel = new JLabel("Địa chỉ: Đang tải..."); - styleLabelForTv(clinicAddressLabel, 20, Font.PLAIN, Color.LIGHT_GRAY); + styleLabelForTv(clinicAddressLabel, 30, Font.PLAIN, Color.LIGHT_GRAY); clinicPhoneLabel = new JLabel("Điện thoại: Đang tải..."); - styleLabelForTv(clinicPhoneLabel, 20, Font.PLAIN, Color.LIGHT_GRAY); + styleLabelForTv(clinicPhoneLabel, 30, Font.PLAIN, Color.LIGHT_GRAY); clinicInfoPanel.add(clinicNameLabel); clinicInfoPanel.add(Box.createRigidArea(new Dimension(0, 5))); @@ -81,13 +81,13 @@ public class QueueViewPage extends JFrame { room1StatusLabel = new JLabel("PHÒNG 1", SwingConstants.CENTER); styleRoomLabel(room1StatusLabel, room1Panel, Color.GREEN.darker(), "TRỐNG"); // Initial state: Room 1 Empty room1Panel.add(room1StatusLabel, BorderLayout.CENTER); - room1Panel.setPreferredSize(new Dimension(220, 100)); + room1Panel.setPreferredSize(new Dimension(280, 120)); room2Panel = new JPanel(new BorderLayout()); room2StatusLabel = new JLabel("PHÒNG 2", SwingConstants.CENTER); styleRoomLabel(room2StatusLabel, room2Panel, Color.GREEN.darker(), "TRỐNG"); // Initial state: Room 2 Empty room2Panel.add(room2StatusLabel, BorderLayout.CENTER); - room2Panel.setPreferredSize(new Dimension(220, 100)); + room2Panel.setPreferredSize(new Dimension(280, 120)); roomsPanel.add(room1Panel); roomsPanel.add(room2Panel); @@ -103,16 +103,16 @@ public class QueueViewPage extends JFrame { callingPatientDisplayPanel.setBorder(new EmptyBorder(15, 20, 15, 20)); // Padding nowCallingTextLabel = new JLabel("ĐANG GỌI:"); - styleLabelForTv(nowCallingTextLabel, 38, Font.BOLD, new Color(255, 215, 0)); // Gold color + styleLabelForTv(nowCallingTextLabel, 60, Font.BOLD, new Color(255, 215, 0)); // Gold color nowCallingTextLabel.setAlignmentX(Component.CENTER_ALIGNMENT); nowCallingTextLabel.setVisible(false); // Initially hidden nowCallingInfoLine1Label = new JLabel("Phòng 1: TRỐNG"); // Default message - styleLabelForTv(nowCallingInfoLine1Label, 32, Font.BOLD, Color.WHITE); + styleLabelForTv(nowCallingInfoLine1Label, 50, Font.BOLD, Color.WHITE); nowCallingInfoLine1Label.setAlignmentX(Component.CENTER_ALIGNMENT); nowCallingInfoLine2Label = new JLabel("Phòng 2: TRỐNG"); // Default message - styleLabelForTv(nowCallingInfoLine2Label, 32, Font.BOLD, Color.WHITE); + styleLabelForTv(nowCallingInfoLine2Label, 50, Font.BOLD, Color.WHITE); nowCallingInfoLine2Label.setAlignmentX(Component.CENTER_ALIGNMENT); callingPatientDisplayPanel.add(nowCallingTextLabel); @@ -135,17 +135,17 @@ public class QueueViewPage extends JFrame { }; tvQueueTable = new JTable(tvQueueTableModel); - tvQueueTable.setFont(new Font("Arial", Font.BOLD, 26)); - tvQueueTable.setRowHeight(45); + tvQueueTable.setFont(new Font("Arial", Font.BOLD, 50)); + tvQueueTable.setRowHeight(80); tvQueueTable.setFillsViewportHeight(true); tvQueueTable.setBackground(new Color(220, 220, 220)); // Light gray for table background tvQueueTable.setGridColor(Color.GRAY); JTableHeader tableHeader = tvQueueTable.getTableHeader(); - tableHeader.setFont(new Font("Arial", Font.BOLD, 28)); + tableHeader.setFont(new Font("Arial", Font.BOLD, 52)); tableHeader.setBackground(new Color(63, 81, 181)); tableHeader.setForeground(Color.WHITE); - tableHeader.setPreferredSize(new Dimension(0, 50)); // Header height + tableHeader.setPreferredSize(new Dimension(0, 90)); // Header height JScrollPane scrollPane = new JScrollPane(tvQueueTable); scrollPane.setBorder(new EmptyBorder(10, 20, 20, 20)); // Padding around table @@ -165,7 +165,7 @@ public class QueueViewPage extends JFrame { String baseRoomText = label.getText().split("
")[0]; // Get "PHÒNG X" if (baseRoomText.contains("html")) baseRoomText = (label == room1StatusLabel ? "PHÒNG 1" : "PHÒNG 2"); // Fallback if parsing fails - label.setFont(new Font("Segoe UI", Font.BOLD, 22)); + label.setFont(new Font("Segoe UI", Font.BOLD, 32)); label.setForeground(Color.WHITE); label.setText("
" + baseRoomText + "
" + statusText + "
"); panel.setBackground(bgColor); @@ -190,18 +190,18 @@ public class QueueViewPage extends JFrame { if (room1Busy) { nowCallingInfoLine1Label.setText("Phòng 1: " + room1PatientInfo); - styleLabelForTv(nowCallingInfoLine1Label, 32, Font.BOLD, Color.WHITE); + styleLabelForTv(nowCallingInfoLine1Label, 50, Font.BOLD, Color.WHITE); } else { nowCallingInfoLine1Label.setText("Phòng 1: TRỐNG"); - styleLabelForTv(nowCallingInfoLine1Label, 32, Font.ITALIC, Color.LIGHT_GRAY); + styleLabelForTv(nowCallingInfoLine1Label, 50, Font.ITALIC, Color.LIGHT_GRAY); } if (room2Busy) { nowCallingInfoLine2Label.setText("Phòng 2: " + room2PatientInfo); - styleLabelForTv(nowCallingInfoLine2Label, 32, Font.BOLD, Color.WHITE); + styleLabelForTv(nowCallingInfoLine2Label, 50, Font.BOLD, Color.WHITE); } else { nowCallingInfoLine2Label.setText("Phòng 2: TRỐNG"); - styleLabelForTv(nowCallingInfoLine2Label, 32, Font.ITALIC, Color.LIGHT_GRAY); + styleLabelForTv(nowCallingInfoLine2Label, 50, Font.ITALIC, Color.LIGHT_GRAY); } if (room1Busy || room2Busy) { @@ -321,6 +321,12 @@ public class QueueViewPage extends JFrame { } tvQueueTableModel.setDataVector(tvDataList.toArray(new Object[0][0]), tvQueueColumns); + // Set column widths for TV display + tvQueueTable.getColumnModel().getColumn(0).setPreferredWidth(150); // STT + tvQueueTable.getColumnModel().getColumn(0).setMaxWidth(200); + tvQueueTable.getColumnModel().getColumn(2).setPreferredWidth(250); // Năm sinh + tvQueueTable.getColumnModel().getColumn(2).setMaxWidth(300); + // The specific room status (patient ID in box) is now handled by updateSpecificRoomStatus // and markRoomAsFree. The general updateQueueData should not override this detailed status. // If no patients are called, updateNowCallingDisplay will reflect that rooms are free if their info is null. diff --git a/src/main/java/BsK/common/packet/req/GetDistrictRequest.java b/src/main/java/BsK/common/packet/req/GetDistrictRequest.java deleted file mode 100644 index 3ebb4da..0000000 --- a/src/main/java/BsK/common/packet/req/GetDistrictRequest.java +++ /dev/null @@ -1,13 +0,0 @@ -package BsK.common.packet.req; - -import BsK.common.packet.Packet; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@AllArgsConstructor -@Data -public class GetDistrictRequest implements Packet { - String provinceId; -} diff --git a/src/main/java/BsK/common/packet/req/GetWardRequest.java b/src/main/java/BsK/common/packet/req/GetWardRequest.java index 90e89f4..eb9be0e 100644 --- a/src/main/java/BsK/common/packet/req/GetWardRequest.java +++ b/src/main/java/BsK/common/packet/req/GetWardRequest.java @@ -1,14 +1,13 @@ package BsK.common.packet.req; - import BsK.common.packet.Packet; import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; +@Slf4j @AllArgsConstructor @Data -@Slf4j public class GetWardRequest implements Packet { - String districtId; + String provinceId; } diff --git a/src/main/java/BsK/common/packet/res/AddCheckupResponse.java b/src/main/java/BsK/common/packet/res/AddCheckupResponse.java index e33b1de..8137847 100644 --- a/src/main/java/BsK/common/packet/res/AddCheckupResponse.java +++ b/src/main/java/BsK/common/packet/res/AddCheckupResponse.java @@ -9,4 +9,5 @@ import lombok.Data; public class AddCheckupResponse implements Packet { boolean success; String error; + int queueNumber; } diff --git a/src/main/java/BsK/common/packet/res/GetDistrictResponse.java b/src/main/java/BsK/common/packet/res/GetDistrictResponse.java index a9abec5..838740d 100644 --- a/src/main/java/BsK/common/packet/res/GetDistrictResponse.java +++ b/src/main/java/BsK/common/packet/res/GetDistrictResponse.java @@ -10,7 +10,6 @@ import java.util.HashMap; @Slf4j @Data @AllArgsConstructor -public class GetDistrictResponse implements Packet { - String[] districts; - HashMap districtToId; +public class GetWardResponse implements Packet { + String[] wards; } diff --git a/src/main/java/BsK/server/network/handler/ServerHandler.java b/src/main/java/BsK/server/network/handler/ServerHandler.java index c1895b0..0db4f75 100644 --- a/src/main/java/BsK/server/network/handler/ServerHandler.java +++ b/src/main/java/BsK/server/network/handler/ServerHandler.java @@ -542,80 +542,39 @@ public class ServerHandler extends SimpleChannelInboundHandler resultList = new ArrayList<>(); - HashMap districtIdMap = new HashMap<>(); - resultList.add("Quận/Huyện"); + resultList.add("Phường/Xã"); while (rs.next()) { - String districtId = rs.getString("code"); - String districtName = rs.getString("name"); - districtIdMap.put(districtName, districtId); - resultList.add(districtName); + String wardName = rs.getString("name"); + resultList.add(wardName); } String[] resultString = resultList.toArray(new String[0]); - UserUtil.sendPacket(currentUser.getSessionId(), new GetDistrictResponse(resultString, districtIdMap)); + UserUtil.sendPacket(currentUser.getSessionId(), new GetWardResponse(resultString)); } } catch (SQLException e) { throw new RuntimeException(e); } } - - if (packet instanceof GetWardRequest getWardRequest) { - log.debug("Received GetWardRequest"); - - try{ - PreparedStatement preparedStatement = Server.connection.prepareStatement( - "SELECT wards.code, wards.name \n" + - " FROM wards\n" + - " WHERE district_code = ? " + - " ORDER BY wards.name" - ); - preparedStatement.setString(1, getWardRequest.getDistrictId()); - - ResultSet rs = preparedStatement.executeQuery(); - - - if (!rs.isBeforeFirst()) { - System.out.println("No data found in the district table."); - } else { - ArrayList resultList = new ArrayList<>(); - HashMap districtIdMap = new HashMap<>(); - resultList.add("Xã/Phường"); - while (rs.next()) { - String districtId = rs.getString("code"); - String districtName = rs.getString("name"); - districtIdMap.put(districtName, districtId); - resultList.add(districtName); - } - - String[] resultString = resultList.toArray(new String[0]); - UserUtil.sendPacket(currentUser.getSessionId(), new GetWardResponse(resultString)); - } - } catch (SQLException e) { - UserUtil.sendPacket(currentUser.getSessionId(), new ErrorResponse(Error.SQL_EXCEPTION)); - throw new RuntimeException(e); - } - } - if (packet instanceof AddPatientRequest addPatientRequest) { log.debug("Received AddPatientRequest"); try { @@ -753,7 +712,7 @@ public class ServerHandler extends SimpleChannelInboundHandler