package dell_anchor; import databases.DBConnector; import dell_targets.Dell_BaseStation; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.table.*; import java.awt.*; import java.awt.event.*; import java.sql.SQLException; import java.util.*; import java.util.List; import java.util.ResourceBundle; import java.util.regex.Pattern; import targets.LocationBaseStation; public class BaseStationSyncConfigPanel extends JPanel { private static final long serialVersionUID = 1L; private JTable syncConfigTable; private DefaultTableModel tableModel; private JTextField searchField; private List allBaseStations; private ResourceBundle messages; public BaseStationSyncConfigPanel(ResourceBundle messages) { this.messages = messages; setLayout(new BorderLayout()); setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // ËÑË÷Ãæ°å JPanel searchPanel = new JPanel(new BorderLayout(5, 5)); searchPanel.setBorder(BorderFactory.createTitledBorder(getMessage("SEARCH"))); // ËÑË÷×é¼þ searchField = new JTextField(15); JButton searchButton = new JButton(getMessage("SEARCH")); JButton editButton = new JButton(getMessage("EDIT")); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5)); buttonPanel.add(searchButton); buttonPanel.add(editButton); searchPanel.add(searchField, BorderLayout.CENTER); searchPanel.add(buttonPanel, BorderLayout.EAST); // ±à¼­°´Å¥Ê¼þ editButton.addActionListener(e -> editSelectedSyncConfig()); searchButton.addActionListener(new SearchAction()); // ±í¸ñÁÐÃû String[] columnNames = { getMessage("BASE_STATION_ID"), getMessage("SYNC_BASE_STATION"), getMessage("BASE_STATION_TYPE"), getMessage("SYNC_STATUS"), getMessage("COMPANY"), getMessage("UPDATE_TIME") }; // ±í¸ñÄ£ÐÍ tableModel = new DefaultTableModel(columnNames, 0) { @Override public boolean isCellEditable(int row, int column) { return false; } }; // ±í¸ñÉèÖà syncConfigTable = new JTable(tableModel); syncConfigTable.setAutoCreateRowSorter(true); syncConfigTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); // ÉèÖÃÁпí TableColumnModel columnModel = syncConfigTable.getColumnModel(); columnModel.getColumn(0).setPreferredWidth(100); // »ùÕ¾±àºÅ columnModel.getColumn(1).setPreferredWidth(100); // ͬ²½»ùÕ¾ columnModel.getColumn(2).setPreferredWidth(80); // »ùÕ¾ÀàÐÍ columnModel.getColumn(3).setPreferredWidth(80); // ͬ²½×´Ì¬ columnModel.getColumn(4).setPreferredWidth(100); // ËùÊô¹«Ë¾ columnModel.getColumn(5).setPreferredWidth(120); // ¸üÐÂʱ¼ä // ÉèÖñíÍ·Ñùʽ JTableHeader header = syncConfigTable.getTableHeader(); header.setDefaultRenderer(new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); setHorizontalAlignment(SwingConstants.LEFT); setBackground(Color.GRAY); setForeground(Color.WHITE); setFont(getFont().deriveFont(Font.BOLD)); return this; } }); JScrollPane scrollPane = new JScrollPane(syncConfigTable); scrollPane.setPreferredSize(new Dimension(1000, 500)); // Ìí¼Ó×é¼þ add(searchPanel, BorderLayout.NORTH); add(scrollPane, BorderLayout.CENTER); // ¼ÓÔØÊý¾Ý loadSyncConfigData(); } private void loadSyncConfigData() { try { allBaseStations = Dell_BaseStation.getBaseStations(); updateTable(allBaseStations); } catch (SQLException ex) { JOptionPane.showMessageDialog(this, getMessage("DATA_LOAD_ERROR") + ": " + ex.getMessage(), getMessage("ERROR"), JOptionPane.ERROR_MESSAGE); } } private void updateTable(List baseStations) { tableModel.setRowCount(0); // Çå¿Õ±í¸ñ for (LocationBaseStation bs : baseStations) { // ת»»»ùÕ¾ÀàÐÍ String baseType = "0".equals(bs.getSyncType()) ? getMessage("SLAVE") : getMessage("MASTER"); // Ìí¼ÓÐÐÊý¾Ý tableModel.addRow(new Object[]{ bs.getCode(), bs.getSyncBaseStation(), baseType, bs.getSyncStatus(), bs.getCompany(), bs.getOnlineTime() // ʹÓÃÉÏÏßʱ¼ä×÷Ϊ¸üÐÂʱ¼ä }); } } // ±à¼­Í¬²½ÅäÖà private void editSelectedSyncConfig() { int[] selectedRows = syncConfigTable.getSelectedRows(); if (selectedRows.length == 0) { JOptionPane.showMessageDialog(this, getMessage("SELECT_BASE_STATION_TO_EDIT"), getMessage("WARNING"), JOptionPane.WARNING_MESSAGE); return; } // »ñȡѡÖеĻùÕ¾ID List deviceIds = new ArrayList<>(); for (int viewRow : selectedRows) { int modelRow = syncConfigTable.convertRowIndexToModel(viewRow); deviceIds.add((String) tableModel.getValueAt(modelRow, 0)); } // µ¯³ö±à¼­¶Ô»°¿ò SyncConfigEditDialog dialog = new SyncConfigEditDialog( (Frame) SwingUtilities.getWindowAncestor(this), messages, deviceIds ); dialog.setVisible(true); if (dialog.isConfirmed()) { String syncBase = dialog.getSyncBaseStation(); String baseType = dialog.getBaseStationType(); // ÑéÖ¤ÊäÈë if (!validateSyncInput(syncBase, baseType)) { return; } int successCount = 0; int failCount = 0; // ¸üÐÂÑ¡ÖеĻùÕ¾ for (String deviceId : deviceIds) { LocationBaseStation bs = findBaseStationById(deviceId); if (bs != null) { // ¸üÐÂÄÚ´æ¶ÔÏó bs.setSyncBaseStation(syncBase); bs.setSyncType(baseType); // ¸üÐÂÊý¾Ý¿â if (updateSyncConfigInDatabase(bs)) { successCount++; } else { failCount++; } } } // ¸üбí¸ñ updateTable(allBaseStations); // ÏÔʾ½á¹û if (failCount == 0) { JOptionPane.showMessageDialog(this, getMessage("SYNC_CONFIG_UPDATE_SUCCESS"), getMessage("SUCCESS"), JOptionPane.INFORMATION_MESSAGE); } else { String message = String.format("%s (%d %s, %d %s)", getMessage("SYNC_CONFIG_UPDATE_FAILED"), successCount, getMessage("SUCCESS"), failCount, getMessage("FAILED")); JOptionPane.showMessageDialog(this, message, getMessage("ERROR"), JOptionPane.ERROR_MESSAGE); } } } // Ñé֤ͬ²½ÅäÖÃÊäÈë private boolean validateSyncInput(String syncBase, String baseType) { // Ñé֤ͬ²½»ùÕ¾ if (syncBase == null || syncBase.trim().isEmpty()) { JOptionPane.showMessageDialog(this, getMessage("SYNC_BASE_STATION_REQUIRED"), getMessage("ERROR"), JOptionPane.ERROR_MESSAGE); return false; } // HEX¸ñʽÑéÖ¤ (0-9, A-F) if (!Pattern.matches("[0-9A-Fa-f]+", syncBase)) { JOptionPane.showMessageDialog(this, getMessage("INVALID_SYNC_BASE_FORMAT"), getMessage("ERROR"), JOptionPane.ERROR_MESSAGE); return false; } // ³¤¶ÈÑéÖ¤ if (syncBase.length() > 6) { JOptionPane.showMessageDialog(this, getMessage("INVALID_SYNC_BASE_FORMAT"), getMessage("ERROR"), JOptionPane.ERROR_MESSAGE); return false; } // ÑéÖ¤»ùÕ¾ÀàÐÍ if (baseType == null || baseType.isEmpty()) { JOptionPane.showMessageDialog(this, getMessage("BASE_STATION_TYPE_REQUIRED"), getMessage("ERROR"), JOptionPane.ERROR_MESSAGE); return false; } return true; } // ¸ù¾ÝID²éÕÒ»ùÕ¾ private LocationBaseStation findBaseStationById(String deviceId) { for (LocationBaseStation bs : allBaseStations) { if (bs.getCode().equals(deviceId)) { return bs; } } return null; } // ¸üÐÂÊý¾Ý¿âÖеÄͬ²½ÅäÖà private boolean updateSyncConfigInDatabase(LocationBaseStation bs) { Map fieldValues = new HashMap<>(); fieldValues.put("sync_base_station", bs.getSyncBaseStation()); fieldValues.put("sync_type", bs.getSyncType()); int dbId = (int) bs.getId(); int result = DBConnector.updateData("location_base_station", fieldValues, dbId); return result > 0; } // ËÑË÷¹¦ÄÜ private class SearchAction implements ActionListener { @Override public void actionPerformed(ActionEvent e) { String keyword = searchField.getText().trim(); if (keyword.isEmpty()) { updateTable(allBaseStations); return; } List filteredList = new ArrayList<>(); for (LocationBaseStation bs : allBaseStations) { if (matchesKeyword(bs, keyword)) { filteredList.add(bs); } } updateTable(filteredList); } private boolean matchesKeyword(LocationBaseStation bs, String keyword) { return (bs.getCode() != null && bs.getCode().contains(keyword)) || (bs.getCompany() != null && bs.getCompany().contains(keyword)); } } private String getMessage(String key) { try { return messages.getString(key); } catch (Exception e) { return "[" + key + "]"; } } } // ͬ²½ÅäÖñ༭¶Ô»°¿ò class SyncConfigEditDialog extends JDialog { private ResourceBundle messages; private JTextArea deviceIdArea; private JTextField syncBaseField; private ButtonGroup typeGroup; private JRadioButton masterRadio; private JRadioButton slaveRadio; private boolean confirmed = false; public SyncConfigEditDialog(Frame parent, ResourceBundle messages, List deviceIds) { super(parent, messages.getString("SYNC_CONFIG_EDIT"), true); this.messages = messages; setLayout(new BorderLayout()); setSize(400, 300); setLocationRelativeTo(parent); JPanel formPanel = new JPanel(new GridLayout(0, 1, 5, 5)); formPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); // É豸IDÏÔʾ JLabel idLabel = new JLabel(messages.getString("BASE_STATION_ID") + ":"); deviceIdArea = new JTextArea(); deviceIdArea.setText(String.join("; ", deviceIds)); deviceIdArea.setEditable(false); deviceIdArea.setBackground(getBackground()); JScrollPane scrollPane = new JScrollPane(deviceIdArea); scrollPane.setPreferredSize(new Dimension(300, 60)); formPanel.add(idLabel); formPanel.add(scrollPane); // ͬ²½»ùÕ¾ JLabel syncLabel = new JLabel(messages.getString("SYNC_BASE_STATION") + ": *"); syncBaseField = new JTextField(); formPanel.add(syncLabel); formPanel.add(syncBaseField); // »ùÕ¾ÀàÐÍ JLabel typeLabel = new JLabel(messages.getString("BASE_STATION_TYPE") + ": *"); JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); masterRadio = new JRadioButton(messages.getString("MASTER")); slaveRadio = new JRadioButton(messages.getString("SLAVE")); typeGroup = new ButtonGroup(); typeGroup.add(masterRadio); typeGroup.add(slaveRadio); radioPanel.add(masterRadio); radioPanel.add(slaveRadio); formPanel.add(typeLabel); formPanel.add(radioPanel); add(formPanel, BorderLayout.CENTER); // °´Å¥Ãæ°å JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); JButton okButton = new JButton(messages.getString("OK")); JButton cancelButton = new JButton(messages.getString("CANCEL")); okButton.addActionListener(e -> { confirmed = true; dispose(); }); cancelButton.addActionListener(e -> dispose()); buttonPanel.add(okButton); buttonPanel.add(cancelButton); add(buttonPanel, BorderLayout.SOUTH); } public String getSyncBaseStation() { return syncBaseField.getText().trim(); } public String getBaseStationType() { if (masterRadio.isSelected()) { return "1"; } else if (slaveRadio.isSelected()) { return "0"; } return null; } public boolean isConfirmed() { return confirmed; } }