Nerissa0319 2021-09-29 16:49 采纳率: 54.5%
浏览 204
已结题

如果将本地的GUI变成网络程序

我想要创建一个网页应用,实现的功能如下:

  • 在界面的上半部分, 用户可以点击按钮选择数据集,然后应用直接生成该数据所形成的图表(时间序列数据),并且随机将图表的一部分框起来
  • 在界面的下半部分,用户可以仿照上面框起来的图形进行画图
  • 画图完成后,用户点击“survey”按钮,可以回答一些预设好的问题
  • 回答完问题后,用户点击“save”按钮,程序可以将界面截图、原数据坐标,用户画的图的坐标以及用户对于问卷的回答。

我现在有一个本地的GUI,可以完成以上功能,但是如果我想要其他人也能用,就只能扛着电脑到处跑,所以老板希望我能在网页上实现同样的功能,使得所有拥有网址的人可以直接点进网页进行以上的操作。我本身是数学系的,上面的那个本地的GUI也是一边查一边学一边弄出来的,现在要弄成网页版完全不知道有嗷怎么做,希望得到大家的帮助,小女子不胜感激!

以下是本地GUI的截图

img

img

img

img

img

img

以下是我的代码


public class Fram { 

    private JFrame frame;
    
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Fram window = new Fram();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        
    }

    /**
     * Create the application.
     * @throws Exception 
     */
    public Fram() throws Exception {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     * @throws Exception 
     */
    String folder;
    String fileName;
    ArrayList<String[]> datas;
    ChartPanel chartPanel;
    JPanel chartJPanel;
    int filesum = 0;
    int current = 0;
    boolean isloadShapelet = false;
    Point point = new Point();
    JLabel[] labels;
    //JScrollPane scrollPane = new JScrollPane();
    //JButton tab = new JButton("Tab");
    JPanel leftDownPanel;
    String fileChoosen;
    int seqNum = -1;
    
    
    String userAge = null;
    String WorkField = null;
    String WorkField1 = null;
    int levelOfDifficulty = -1;
    String SubOpinion = null;
    String SaveFileName;
    int saveCount = 0;
    int surveyCount = 0;
    int drawCount = 0;
    int ratioS;
    int ratioS2;
    
    private void initialize() throws Exception {
        frame = new JFrame();
        //frame.setBounds(100, 100, 935, 600);
        frame.setBounds(100, 100, 600, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        
        JPanel leftUpPanel = new JPanel();
        leftUpPanel.setBounds(10, 10, 582, 303);
        frame.getContentPane().add(leftUpPanel);
        leftUpPanel.setLayout(null);
        leftUpPanel.setBackground(Color.WHITE);
      
        JLabel lblNewLabel = new JLabel("Dataset");
        lblNewLabel.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 25));
        lblNewLabel.setBounds(0, 0, 115, 26);
        leftUpPanel.add(lblNewLabel);
        
        JButton loadDateSet = new JButton("Load dataset");
        loadDateSet.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 12));
        loadDateSet.setBounds(120, 3, 130, 26);
        leftUpPanel.add(loadDateSet);
        
//        JButton droplist = new JButton("Droplist");
//        droplist.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 12));
//        droplist.setBounds(235, 3, 90, 26);
//        leftUpPanel.add(droplist);
        
        JButton saveFile = new JButton("Save"); 
        saveFile.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 12)); 
        saveFile.setBounds(255, 3, 120, 26); 
        leftUpPanel.add(saveFile);
//        final JLabel label = new JLabel();    
        
        JButton survey = new JButton("Survey"); 
        survey.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 12)); 
        survey.setBounds(380, 3, 120, 26); 
        leftUpPanel.add(survey);
       
        chartJPanel = new JPanel();
        chartJPanel.setBounds(5, 25, 600, 300);
        frame.getContentPane().add(chartJPanel);
        
        JPanel rectangle = new JPanel();
        
        
        
        loadDateSet.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                if(drawCount > saveCount) {
                    JOptionPane.showMessageDialog(frame,"Please Complete drawing and survey first");
                }
                else {
                //Creating a File object for directory
                File directoryPath = new File("datas");
                //List of all files and directories
                File filesList[] = directoryPath.listFiles();
                String listOfPaths[] = Arrays.stream(filesList).map(File::getName)
                       .toArray(String[]::new);
                String[] FolderOptions = listOfPaths;
                String getFolder = (String) JOptionPane.showInputDialog(
                            frame,
                            "Choose folder",
                            "Choose folder",
                            JOptionPane.QUESTION_MESSAGE,
                            null,
                            FolderOptions,
                            FolderOptions[0]);
                
                folder = getFolder;
                File newPath = new File("datas/"+getFolder);
                File newFileList[] = newPath.listFiles();
                String dataToChoose[] = Arrays.stream(newFileList).map(File::getName)
                        .toArray(String[]::new);
                fileName = (String) JOptionPane.showInputDialog(
                        frame,
                        "Choose a dataset",
                        "Choose a dataset",
                        JOptionPane.QUESTION_MESSAGE,
                        null,
                        dataToChoose,
                        dataToChoose[0]);
                fileChoosen = fileName;
                fileName = folder+"/"+fileChoosen;
                
                if(fileName!=null) {
                    if(!fileName.isEmpty()) {
                        datas = GetData.getDatas(fileName,"leftUp");
                        int parseInt = -1;
                        while(parseInt < 0 || parseInt>=GetData.num) {
                            String showInputDialog = JOptionPane.showInputDialog(frame, "There are "+GetData.num+" Sequences" + " (from 0 to" + (GetData.num-1) +"). Please key in sequence number:");
                            parseInt = Integer.valueOf(showInputDialog);
                            if(parseInt < 0 || parseInt>=GetData.num) {
                                JOptionPane.showMessageDialog(frame, "Sequence Number Out of Bound");
                            }
                        }
                        seqNum = parseInt;
                        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss");  
                        LocalDateTime now = LocalDateTime.now(); 
                        SaveFileName = fileChoosen+"-"+seqNum+"-"+dtf.format(now);
                    
                        
                        
                        String[] series = datas.get(parseInt);
                        
                        try {
                             
                            int randStart = (int)(Math.random() * (400 - 60)) + 60;
                            rectangle.setBounds(randStart, 35, 75, 260);
                            rectangle.setBackground( new Color(255, 234, 0, 70));  
                            rectangle.setOpaque(true);
                            rectangle.setBorder(BorderFactory.createLineBorder(Color.black,1));
                            
                            leftUpPanel.add(rectangle);
                            rectangle.setVisible(true);
                            double ratio = (double)(randStart-47)/(double)527;
                            double ratio2 = (double)(randStart+75-47)/(double)527;
                            ratioS = (int)(series.length*ratio);
                            ratioS2 = (int)(series.length*ratio2);
                            
                            for(int i = ratioS; i <= (ratioS2); i++) {
                                FileWriter fw2 = new FileWriter(SaveFileName + "-shapeXY.txt", true);
                                fw2.write((series[i])+"\n");
                                fw2.close();
                            }
                            
                            chartPanel = new Charts().createChart(series);
                            chartPanel.setBackground(null);
                            leftUpPanel.remove(chartJPanel);
                            chartJPanel = new JPanel();
                            chartJPanel.setBounds(5, 25, 580, 300);
                            chartPanel.setBounds(0, 0, 580, 300);
                            chartJPanel.setLayout(null);
                            chartJPanel.setBackground(Color.WHITE);
                            chartJPanel.add(chartPanel);
                            leftUpPanel.add(chartJPanel);
                            frame.repaint();
                            JOptionPane.showMessageDialog(frame, "Please draw according to the shape in the yellow rectantle.");
                                } catch (Exception e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                                }
                            }
                        }
                    drawCount = drawCount + 1;
                    }
                }
                    
                });
        
        //Survey Button
        //Get user's age, working field, level of difficulty and their subjective opinion
        survey.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                if((GetData.num==0)||(seqNum<0 || seqNum>GetData.num)) {
                    JOptionPane.showMessageDialog(frame, "Please complete drawing first.");
                }else {
                    JFrame jf = new JFrame("Survey");
                    jf.setBounds(100,100,550,550);
                    JPanel panel = new JPanel();  
                    panel.setBounds(105,105,530,530);
                    jf.getContentPane().add(panel);
                    panel.setLayout(null);
                    panel.setBackground(new Color(245,245,245));

                    JLabel lblAge = new JLabel("Your Age") ;
                    JLabel lblField = new JLabel("Your Working Field");
                
                    JLabel lblLevel = new JLabel("Level of Difficulty (5 is for extremely difficult)");
                    JLabel lblOpinion = new JLabel("Your Opinion");
                    JButton btnSubmit = new JButton("Submit");
                    btnSubmit.setBounds(400,450,100,30);
                    panel.add(btnSubmit);
                    JTextField t2;
                    JTextArea t4;  
                   
                    t2 = new JTextField("Please ENTER your working field",10);
                   
                    t4 = new JTextArea("Please ENTER your feelings about drawing the highlighted pattern");
                    
                    t4.setLineWrap(true);
                    
                    t2.setEnabled(true);
                    
                    t4.setEnabled(true);
                    lblAge.setBounds(30,30,200,20);
                    panel.add(lblAge);
                    lblField.setBounds(30,55,200,20);
                    panel.add(lblField);
                    lblLevel.setBounds(30,80,300,20);
                    panel.add(lblLevel);
                    lblOpinion.setBounds(30,105,200,20);
                    panel.add(lblOpinion);

                    String[] choicesLevel = {null,"1","2","3","4","5"};

                    final JComboBox<String> cbLevel = new JComboBox<String>(choicesLevel);
                    
                    cbLevel.setMaximumSize(cbLevel.getPreferredSize()); // added code
                    cbLevel.setAlignmentX(Component.LEFT_ALIGNMENT);// added code
                    
                    
                    String[] choicesAge = { null,"x < 20", "20 <= x < 25", "25 <= x < 30",
                            "30 <= x < 35","35 <= x < 40", "x >= 40"};

                    final JComboBox<String> cbAge = new JComboBox<String>(choicesAge);
                    
                    
                    cbAge.setMaximumSize(cbAge.getPreferredSize()); // added code
                    cbAge.setAlignmentX(Component.LEFT_ALIGNMENT);// added code
                    //cb.setVisible(true); // Not needed
                    
                   
                    cbAge.setBounds(300,30,200,20);
                    panel.add(cbAge);
                    
                    
                    t2.setBounds(300,55,200,20);
            
                    panel.add(t2);
                  
                    cbLevel.setBounds(300,80,200,20);
                    panel.add(cbLevel);
                    
                  
                    t4.setBounds(300,105,200,300);
                    t4.setLineWrap(true);
                    
                   
                    panel.add(t4);
                    // 添加条目选中状态改变的监听器
                    cbAge.addItemListener(new ItemListener() {
                        @Override
                        public void itemStateChanged(ItemEvent e) {
                            // 只处理选中的状态
                            if (e.getStateChange() == ItemEvent.SELECTED) {
                                userAge = cbAge.getSelectedItem().toString();
                            }
                        }
                    });
    
                    cbLevel.addItemListener(new ItemListener() {
                        @Override
                        public void itemStateChanged(ItemEvent e) {
                            // 只处理选中的状态
                            if (e.getStateChange() == ItemEvent.SELECTED) {
                                levelOfDifficulty = Integer.valueOf(cbLevel.getSelectedItem().toString());
                            }
                        }
                    });
                  
                
                    
                    panel.setAlignmentX(Component.LEFT_ALIGNMENT);
                    
                    jf.setContentPane(panel);
                    jf.setVisible(true);

                    btnSubmit.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            String tempString = t2.getText();
                            if(surveyCount < 0 || ((!tempString.equals(WorkField))&& (
                                    !tempString.equals("Please ENTER your working field")))){
                                WorkField = t2.getText();
                            }
                                    
                            SubOpinion = t4.getText();
                            surveyCount += 1;
                            jf.dispose();
                        }
                    });
                    
                    
                    
                    
                        
            }
                 
            
            }
        }
        );
        

        saveFile.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e)
                {    
                    if((GetData.num==0)||(seqNum<0 || seqNum>GetData.num)) {
                        JOptionPane.showMessageDialog(frame, "Please complete drawing first.");
                    }else if(userAge == null || levelOfDifficulty <1 || levelOfDifficulty > 5) {
                        JOptionPane.showMessageDialog(frame, "Please complete the survey first.");
                    }else if(WorkField == null||WorkField.equals("Please ENTER your working field")) {
                        JOptionPane.showMessageDialog(frame, "You haven't input your working field.");
                    }else if(SubOpinion == null||SubOpinion.equals("Please ENTER your feelings about drawing the highlighted pattern")){
                        JOptionPane.showMessageDialog(frame, "You haven't input your opinion about drawing the pattern.");
                    }else {
                        if (e.getSource() == saveFile) {
                        
                            try {
                                Point point = frame.getLocation();
                                int x = (int)point.getX();
                                int y = (int)point.getY();
                                Thread.sleep(1000);
                                Toolkit tk = Toolkit.getDefaultToolkit(); 
                                Dimension d = tk.getScreenSize();
                                Rectangle rec = new Rectangle(x,y,600,600);  
                                Robot ro = new Robot();
                                BufferedImage img = ro.createScreenCapture(rec);
                                 
                                
                                File f = new File(SaveFileName+".jpg");//set appropriate path
                                
                                ImageIO.write(img, "jpg", f);
                            } catch (Exception ex) {
                                System.out.println(ex.getMessage());
                            }
                            
                            try {
                                FileWriter fw = new FileWriter(SaveFileName+".txt");
                                fw.write("Age of User: "+userAge+"\n");
                                fw.write("Field of work: "+WorkField+"\n");
                                fw.write("Level of difficulty: "+levelOfDifficulty+"\n");
                                fw.write("User's subjective opinion: "+SubOpinion+"\n");
                                fw.close();
                                
                                
                                levelOfDifficulty = -1;
                                SubOpinion = null;
                                fileName = null;
                                
                                datas = GetData.getDatas("coffee/"+fileName,"leftUp");
                                
                            }catch(Exception e3) {
                                System.out.println(e3);}
                           
                            saveCount += 1;
                        }
                }}});
        
        frame.addWindowListener(new WindowAdapter() {
              public void windowClosing(WindowEvent e) {
                 
                 if(saveCount == 0 || saveCount != drawCount 
                         || levelOfDifficulty != -1 || SubOpinion != null) {
                     String[] options = new String[2];
                     options[0] = new String("Exit Anyway");
                     options[1] = new String("Go Back");
                     int unSavedConfirm = JOptionPane.showOptionDialog(frame.getContentPane(),"Warning! There is something unsaved!","Title", 0,JOptionPane.INFORMATION_MESSAGE,null,options,null);
                     if(unSavedConfirm == 0){
                        File fw1 = new File(SaveFileName+"-drawxy.txt");
                         fw1.delete();
                         File fw2 = new File(SaveFileName +"-shapeXY.txt");
                         fw2.delete();
                         File fw3 = new File(SaveFileName+".jpg");
                         fw3.delete();
                         File fw4 = new File(SaveFileName+".txt");
                         fw4.delete();
                        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    }
                 }
                else{
                    int confirmed = JOptionPane.showConfirmDialog(frame, 
                    "Are you sure you want to exit?", "Exit Program Message Box",
                    JOptionPane.YES_NO_OPTION);

                    if (confirmed == JOptionPane.YES_OPTION) {
                        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    }
              }
          }
        });

            
        leftDownPanel = new JPanel();
        leftDownPanel.setBounds(10, 323, 582, 230);
        frame.getContentPane().add(leftDownPanel);
        leftDownPanel.setLayout(null);
        leftDownPanel.setBackground(Color.WHITE);
        
        leftDownPanel.addMouseListener(new MouseListener() {
            
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseClicked(MouseEvent e) {}
        });
        leftDownPanel.addMouseMotionListener(new MouseMotionListener() {
            
            @Override
            public void mouseMoved(MouseEvent e) {
                //if(e.getX()>260 && e.getY()>30) {
                if(e.getX()>10 && e.getY()>30) {
                    x1 = e.getX();
                    y1 = e.getY();
                }
                
            }
            
            @Override
            public void mouseDragged(MouseEvent e) {
            
                //if(e.getX()>260 && e.getY()>30) {
                    if(e.getX()>10 && e.getY()>10) {
                    Graphics graphics = leftDownPanel.getGraphics();
                    graphics.setColor(Color.RED);
                    graphics.drawLine(x1, y1, e.getX(), e.getY());
                    x1 = e.getX();
                    y1 = e.getY();
                    doubles.add(2.3-y1*0.01);
                    size++;
                    try {
                        FileWriter fw1 = new FileWriter(SaveFileName+"-drawxy.txt",true);
                        fw1.write(x1*0.01+"\t"+(2.3-y1*0.01)+"\n");
                           fw1.close();
                  
                    }catch(Exception e3) {
                        System.out.println(e3);
                        }
                    
                    
                }
                
                    
            }
            
        });    
        
        JLabel draw = new JLabel("Draw");
        draw.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 25));
        draw.setBounds(0, 0, 121, 26);
        leftDownPanel.add(draw);
        
    }


        int x1;
        int y1;
        int size = 0;
        ArrayList<Double> doubles = new ArrayList<>();
        String[] strings = new String[size];
        JPanel jPanel = new JPanel();
        ArrayList<String[]> datas2;
        File[] listFiles;
        
    
    JPanel jPanel2 = new JPanel();
    boolean flag = false;
    public void setLeftChart(String[] series) {
        try {
            ChartPanel    createChart = new Charts().createChart(series);
            JFreeChart chart = createChart.getChart();
            
            CategoryPlot categoryPlot = chart.getCategoryPlot();
            categoryPlot.setOutlineVisible(false);
            ValueAxis rangeAxis = categoryPlot.getRangeAxis();
            
            CategoryAxis domainAxis = categoryPlot.getDomainAxis();
            
            domainAxis.setVisible(false);
            domainAxis.setTickMarksVisible(false);
//            rangeAxis.setAxisLineVisible(false);
            rangeAxis.setVisible(false);
//            Plot plot = chart.getPlot();
            
            createChart.setBackground(null);
            if(flag) {
                leftDownPanel.remove(jPanel2);
            }
            jPanel2 = new JPanel();
            jPanel2.setBounds(5, 25, 260, 200);
//            jPanel2.setBounds(5, 25, 10, 200);
            createChart.setBounds(0, 0, 287, 200);
            jPanel2.setLayout(null);
            jPanel2.setBackground(Color.WHITE);
            jPanel2.add(createChart);
            leftDownPanel.add(jPanel2);
            jPanel2.repaint();
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    
    
    int index = -1;
    boolean indexChange = false;
    JFrame jFrame = new JFrame();

    int time = -1;
    MouseListener mouseListener = new MouseListener();
    JLabel jLabel = new JLabel();
    String[] series = new String[0];
    class MouseListener implements MouseInputListener{
        MouseListener(){
            jFrame.setUndecorated(true);
            jFrame.setBackground(new Color(0,0,0,0));
            jFrame.setLayout(null);
            //jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            //jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        }
        
    
        @Override
        public void mouseReleased(MouseEvent e) {
            int x = jFrame.getX();
            int y = jFrame.getY();
            int x1 = leftDownPanel.getX()+frame.getX();
            int y1 = leftDownPanel.getY()+frame.getY();
            
            if(x>x1 && y>y1){
                String[] series1 = datas2.get(index);
                int length = series.length + series1.length;
                String[] strings = new String[length];
                for(int i=0;i<series.length;i++) {
                    strings[i] = series[i];
                }
                for(int j=series.length;j<length;j++) {
                    strings[j] = series1[j-series.length];
                }
                series = strings;
                setLeftChart(series);
            }
            jFrame.setBounds(10, 10, 10, 10);
            jFrame.setVisible(false);
        }
        
        @Override
        public void mousePressed(MouseEvent e) {
            if(index!=e.getComponent().getY()/200) {
                index = e.getComponent().getY()/200;
                indexChange = true;
            }else{
                indexChange = false;
            }
        }

        @Override
        public void mouseExited(MouseEvent e) {
            frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            
        }
        @Override
        public void mouseEntered(MouseEvent e) {
            frame.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
        }
        
        @Override
        public void mouseClicked(MouseEvent e) {
            // TODO Auto-generated method stub
            
        }
        @Override
        public void mouseDragged(MouseEvent e) {
            time++;
            
            if(time>0 && indexChange) {
                jFrame.remove(jLabel);
                jLabel = new JLabel();
                
            }
            indexChange = false;
            jLabel.setIcon(labels[index].getIcon());
            jLabel.setBounds(0,0,labels[index].getWidth(),labels[index].getHeight());
            Point location = frame.getLocation();
            jFrame.setBounds((int)location.getX()+410+e.getX(),(int)location.getY()+50+index*200+e.getY()+jPanel.getY(),labels[index].getWidth(),labels[index].getHeight());
            
            jFrame.getContentPane().add(jLabel);
            
            jFrame.repaint();
            jFrame.setVisible(true);
            
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            // TODO Auto-generated method stub
        }
    
    }
    

}



  • 写回答

7条回答 默认 最新

  • ak01_10 2021-09-29 21:01
    关注

    你要实现网页的效果,需要设计出界面,这个哪怕专业的人也要花一天开发。然后在公司网站的服务器端做出修改,支持对网页的跳转和数据保存。
    GUI和网站的网页,这是两套完全不一样的程序。
    你要是对网页设计一窍不通的话,就不是一个星期能搞出来的。如果急的话,只能请人帮忙设计网页了。
    如果只是单纯希望远方的客户能用到你的功能,没有硬性需要网页的话,倒是有个简单的方法——将本地的java程序打包成可执行文件,共享给客户下载使用。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 10月12日
  • 已采纳回答 10月4日
  • 创建了问题 9月29日

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)