package com.mes.component; import com.mes.ui.MesClient; import com.mes.ui.YgslUtil; import com.mes.util.JdbcUtils; import com.mes.ygsl.YgslClient; import com.mes.ygsl.YgslConfig; import com.mes.ygsl.YgslParam; import javax.swing.*; import java.awt.*; import java.util.List; import java.util.Timer; import java.util.TimerTask; public class GunPanel extends JPanel { private YgslConfig config; private int gunIndex; private int currentCount = 0; private int taskCount = 0; private boolean isOnline = false; private boolean isConnected = false; private YgslClient gunClient; private Timer heartBeatTimer; private List tighteningIds; private JLabel nameLabel; private JLabel statusLabel; private JLabel scheduleLabel; private JLabel torqueLabel; private JLabel angleLabel; private OnTighteningDataListener dataListener; private OnTaskCompletedListener taskCompletedListener; private OnStatusChangeListener statusChangeListener; public interface OnTighteningDataListener { void onTighteningData(GunPanel panel, String tighteningStatus, String torque, String angle, String tighteningID, String jobID, String pos); } public interface OnTaskCompletedListener { void onTaskCompleted(GunPanel panel); } public interface OnStatusChangeListener { void onStatusChanged(GunPanel panel, boolean isOnline); } public GunPanel(YgslConfig config) { this.config = config; this.gunIndex = config.getGunIndex(); this.taskCount = config.getTaskCount(); this.tighteningIds = new java.util.ArrayList<>(); initUI(); } private void initUI() { setLayout(null); setPreferredSize(new Dimension(230, 140)); setOpaque(false); JLabel titleLabel = new JLabel(config.getGunName()); titleLabel.setHorizontalAlignment(SwingConstants.CENTER); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24)); titleLabel.setForeground(Color.BLACK); titleLabel.setBounds(0, 5, 160, 28); add(titleLabel); statusLabel = new JLabel("离线"); statusLabel.setHorizontalAlignment(SwingConstants.CENTER); statusLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); statusLabel.setBounds(165, 8, 60, 22); statusLabel.setForeground(Color.RED); add(statusLabel); JLabel scheduleTitleLabel = new JLabel("进度:"); scheduleTitleLabel.setHorizontalAlignment(SwingConstants.RIGHT); scheduleTitleLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18)); scheduleTitleLabel.setForeground(Color.BLACK); scheduleTitleLabel.setBounds(10, 40, 60, 25); add(scheduleTitleLabel); scheduleLabel = new JLabel("0/" + taskCount); scheduleLabel.setHorizontalAlignment(SwingConstants.LEFT); scheduleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18)); scheduleLabel.setForeground(Color.BLACK); scheduleLabel.setBounds(75, 40, 90, 25); add(scheduleLabel); JLabel torqueTitleLabel = new JLabel("扭矩:"); torqueTitleLabel.setHorizontalAlignment(SwingConstants.RIGHT); torqueTitleLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18)); torqueTitleLabel.setForeground(Color.BLACK); torqueTitleLabel.setBounds(10, 75, 60, 25); add(torqueTitleLabel); torqueLabel = new JLabel(""); torqueLabel.setHorizontalAlignment(SwingConstants.LEFT); torqueLabel.setFont(new Font("微软雅黑", Font.BOLD, 18)); torqueLabel.setForeground(Color.BLACK); torqueLabel.setBounds(75, 75, 100, 25); add(torqueLabel); JLabel angleTitleLabel = new JLabel("角度:"); angleTitleLabel.setHorizontalAlignment(SwingConstants.RIGHT); angleTitleLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18)); angleTitleLabel.setForeground(Color.BLACK); angleTitleLabel.setBounds(10, 110, 60, 25); add(angleTitleLabel); angleLabel = new JLabel(""); angleLabel.setHorizontalAlignment(SwingConstants.LEFT); angleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18)); angleLabel.setForeground(Color.BLACK); angleLabel.setBounds(75, 110, 100, 25); add(angleLabel); } public void connect() { if (gunClient != null) { return; } gunClient = new YgslClient(config.getIpAddress(), config.getPort(), gunIndex); gunClient.setGunPanel(this); try { gunClient.run(); isConnected = true; startHeartBeatTimer(); } catch (Exception e) { e.printStackTrace(); isConnected = false; scheduleReconnect(); } } public void disconnect() { stopHeartBeatTimer(); if (gunClient != null) { gunClient.close(); gunClient = null; } isConnected = false; isOnline = false; updateStatusUI(); } private void scheduleReconnect() { Timer reconnectTimer = new Timer(); reconnectTimer.schedule(new TimerTask() { @Override public void run() { if (!isConnected) { connect(); } } }, 3000); } private void startHeartBeatTimer() { stopHeartBeatTimer(); heartBeatTimer = new Timer(); heartBeatTimer.schedule(new TimerTask() { @Override public void run() { if (gunClient != null && isConnected) { if (isOnline) { YgslUtil.comHeart(gunClient); } else { scheduleReconnect(); } } updateStatusUI(); } }, 1000, 3000); } private void stopHeartBeatTimer() { if (heartBeatTimer != null) { heartBeatTimer.cancel(); heartBeatTimer = null; } } public void setOnline(boolean online) { this.isOnline = online; updateStatusUI(); if (statusChangeListener != null) { statusChangeListener.onStatusChanged(this, online); } } private void updateStatusUI() { SwingUtilities.invokeLater(() -> { if (isOnline) { statusLabel.setText("在线"); statusLabel.setForeground(Color.GREEN); } else { statusLabel.setText("离线"); statusLabel.setForeground(Color.RED); } }); } public void processTighteningData(String content) { if (MesClient.work_status != 1) { YgslUtil.lastTighteningResultDataAcknowledge(gunClient); return; } String tighteningStatus = com.mes.ygsl.YgslParam.getTighteningStatus(content); String torqueStatus = com.mes.ygsl.YgslParam.getTorqueStatus(content); String angleStatus = com.mes.ygsl.YgslParam.getAngleStatus(content); String torque = com.mes.ygsl.YgslParam.getTorque(content); String angle = com.mes.ygsl.YgslParam.getAngle(content); String tighteningID = com.mes.ygsl.YgslParam.getTighteningID(content); String jobID = com.mes.ygsl.YgslParam.getJobID(content); String torqueMin = YgslParam.getTorqueMinLimit(content); String torqueMax = YgslParam.getTorqueMaxLimit(content); String torqueFinal = YgslParam.getTorqueFinalTarget(content); String angleMin = YgslParam.getAngleMin(content); String angleMax = YgslParam.getAngleMax(content); String angleFinal = YgslParam.getFinalAngleTarget(content); if (tighteningID.isEmpty() || tighteningIds.contains(tighteningID)) { YgslUtil.lastTighteningResultDataAcknowledge(gunClient); return; } tighteningIds.add(tighteningID); String pos = String.valueOf(gunIndex); Boolean checkRet = JdbcUtils.checkTighteningById(tighteningID, pos, jobID); if (!checkRet) { if (tighteningStatus.equals("0")) { if (torqueStatus.equals("1")) { torqueLabel.setForeground(Color.BLACK); } else { torqueLabel.setForeground(Color.RED); } if (angleStatus.equals("1")) { angleLabel.setForeground(Color.BLACK); } else { angleLabel.setForeground(Color.RED); } } else { torqueLabel.setForeground(Color.BLACK); angleLabel.setForeground(Color.BLACK); if (tighteningStatus.equals("1")) { currentCount++; } } final int displayCount = tighteningStatus.equals("1") ? currentCount : currentCount + 1; SwingUtilities.invokeLater(() -> { torqueLabel.setText(torque); angleLabel.setText(angle); scheduleLabel.setText(displayCount + "/" + taskCount); }); JdbcUtils.insertTighteningData( MesClient.mes_gw,MesClient.mes_line_sn,MesClient.product_sn.getText(), tighteningStatus,torqueStatus,angleStatus,torqueMin,torqueMax,torqueFinal,torque, angleMin,angleMax,angleFinal,angle,tighteningID,jobID,"", pos,MesClient.user_menu.getText() ); if (currentCount >= taskCount) { disableTool(); if (taskCompletedListener != null) { taskCompletedListener.onTaskCompleted(this); } } } YgslUtil.lastTighteningResultDataAcknowledge(gunClient); if (dataListener != null) { dataListener.onTighteningData(this, tighteningStatus, torque, angle, tighteningID, jobID, pos); } } public void enableTool() { if (gunClient != null && isOnline) { YgslUtil.enableTool(gunClient); } } public void disableTool() { if (gunClient != null && isOnline) { YgslUtil.disableTool(gunClient); } } public void pSet() { System.out.println("GunPanel[" + gunIndex + "] pSet called, isOnline=" + isOnline + ", gunClient=" + (gunClient != null)); if (gunClient != null && isOnline) { YgslUtil.pSet(gunClient); } else { System.err.println("GunPanel[" + gunIndex + "] pSet skipped - not online!"); } } public void startJob() { System.out.println("GunPanel[" + gunIndex + "] startJob called, isOnline=" + isOnline + ", gunClient=" + (gunClient != null)); if (gunClient != null && isOnline) { YgslUtil.selectJob(gunClient); } else { System.err.println("GunPanel[" + gunIndex + "] startJob skipped - not online!"); } } public void reset() { currentCount = 0; tighteningIds.clear(); SwingUtilities.invokeLater(() -> { torqueLabel.setText(""); angleLabel.setText(""); scheduleLabel.setText("0/" + taskCount); torqueLabel.setForeground(Color.BLACK); angleLabel.setForeground(Color.BLACK); }); } public boolean isTaskCompleted() { return currentCount >= taskCount; } public int getCurrentCount() { return currentCount; } public int getTaskCount() { return taskCount; } public boolean isOnline() { return isOnline; } public YgslConfig getConfig() { return config; } public int getGunIndex() { return gunIndex; } public YgslClient getGunClient() { return gunClient; } public int getAutoSubmit() { return config.getAutoSubmit(); } public void setDataListener(OnTighteningDataListener listener) { this.dataListener = listener; } public void setTaskCompletedListener(OnTaskCompletedListener listener) { this.taskCompletedListener = listener; } public void setStatusChangeListener(OnStatusChangeListener listener) { this.statusChangeListener = listener; } public void destroy() { disconnect(); } public void updateConfig(YgslConfig newConfig) { this.config = newConfig; this.taskCount = newConfig.getTaskCount(); SwingUtilities.invokeLater(() -> { scheduleLabel.setText(currentCount + "/" + taskCount); }); } }