shjung 2 gadi atpakaļ
vecāks
revīzija
4f614c9015

+ 1 - 0
conf/wthr-comm-server.pid

@@ -0,0 +1 @@
+39692

+ 5 - 0
pom.xml

@@ -179,6 +179,11 @@
             <version>4.5.12</version>
         </dependency>
         <!-- FOR WEB UI: END -->
+        <dependency>
+            <groupId>com.intellij</groupId>
+            <artifactId>forms_rt</artifactId>
+            <version>7.0.3</version>
+        </dependency>
 
     </dependencies>
 

+ 82 - 14
src/main/java/com/its/wthr/WthrCommServerApplication.java

@@ -1,11 +1,15 @@
 package com.its.wthr;
 
 import com.its.app.AppUtils;
+import com.its.app.utils.OS;
+import com.its.app.utils.SysUtils;
 import com.its.wthr.config.ServerConfig;
 import com.its.wthr.process.DbmsJobProcess;
 import com.its.wthr.service.AtmpService;
 import com.its.wthr.service.FrcsService;
 import com.its.wthr.service.UnitSystService;
+import com.its.wthr.ui.JTextAreaOutputStream;
+import com.its.wthr.ui.MainUI;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
@@ -15,14 +19,23 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.context.ApplicationPidFileWriter;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.core.io.ClassPathResource;
 import org.springframework.scheduling.annotation.EnableAsync;
 
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.URL;
 import java.text.SimpleDateFormat;
-import java.util.Date;
 
 @Slf4j
 @EnableAsync
@@ -30,17 +43,32 @@ import java.util.Date;
 @SpringBootApplication
 @ComponentScan(basePackages = {"com.its.wthr.config", "com.its.wthr.mapper", "com.its"})
 public class WthrCommServerApplication implements CommandLineRunner, ApplicationListener<ContextClosedEvent>, InitializingBean, DisposableBean {
+//public class WthrCommServerApplication implements CommandLineRunner, ApplicationListener<ContextClosedEvent>, InitializingBean, DisposableBean {
 
     private static final String applicationName = "wthr-comm-server";
 
     public static void main(String[] args) {
-
-        SpringApplication application = new SpringApplicationBuilder()
-                .sources(WthrCommServerApplication.class)
-                .listeners(new ApplicationPidFileWriter("./conf/" + applicationName + ".pid"))
-                .build();
-        application.setBannerMode(Banner.Mode.OFF);
-        application.run(args);
+        File file1 = new File("./conf/" + applicationName + ".pid");
+        if (file1.exists()) {
+            System.out.println(System.getProperty("Program Already Running....."));
+            log.error("Program Already Running.....");
+        }
+
+        if (OS.isWindows()) {
+            ApplicationContext context = new SpringApplicationBuilder(WthrCommServerApplication.class)
+                    //.web(WebApplicationType.NONE)
+                    .listeners(new ApplicationPidFileWriter("./conf/" + applicationName + ".pid"))
+                    .headless(false)
+                    .bannerMode(Banner.Mode.OFF)
+                    .run(args);
+        } else {
+            SpringApplication application = new SpringApplicationBuilder()
+                    .sources(WthrCommServerApplication.class)
+                    .listeners(new ApplicationPidFileWriter("./conf/" + applicationName + ".pid"))
+                    .build();
+            application.setBannerMode(Banner.Mode.OFF);
+            application.run(args);
+        }
     }
 
     @Override
@@ -75,23 +103,63 @@ public class WthrCommServerApplication implements CommandLineRunner, Application
 
         // schedule enable
         serverConfig.setStartSchedule(true);
+
+        if (OS.isWindows()) {
+            SwingUtilities.invokeLater(() -> {
+                String sysTime = SysUtils.getSysTimeStr();
+                //JFrame.setDefaultLookAndFeelDecorated(true);
+                JFrame frame = new JFrame("기상정보 연계 서버 - [" + sysTime + "]");
+                MainUI UI = new MainUI(frame);
+                try {
+                    ClassPathResource file = new ClassPathResource("static/image/application.png");
+                    URL imgURL = file.getURL();
+                    frame.setIconImage(new ImageIcon(imgURL).getImage());
+                } catch (IOException e) {
+                    log.error("Not found application icon image");
+                }
+                frame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
+                frame.setContentPane(UI.getRootPanel());
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.addWindowListener(new WindowAdapter() {
+                    @Override
+                    public void windowClosing(WindowEvent e) {
+                        if (JOptionPane.showConfirmDialog(UI.getRootPanel(), "시스템을 종료 하시겠습니까?", "시스템 종료", 0) == 0) {
+                            System.exit(0);
+                        } else {
+                            frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+                        }
+                    }
+                });
+                frame.pack();
+                frame.setBounds(100, 100, 900, 700);
+                frame.setLocationRelativeTo(null);
+                frame.setVisible(true);
+
+                JTextArea logArea = UI.getTaLog();
+                logArea.setText(null);
+                JTextAreaOutputStream out = new JTextAreaOutputStream(logArea);
+                System.setOut(new PrintStream(out));
+
+                UI.LoadControllerInfo();
+            });
+        }
     }
 
-    @Override
-    public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
+    public void terminateApplication() {
         SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         UnitSystService unitSystService = (UnitSystService) AppUtils.getBean(UnitSystService.class);
         unitSystService.updateUnitSyst(false);
-
-        log.error("Application Terminated: {}, {}", sdfDate.format(new Date()), contextClosedEvent.toString());
+    }
+    @Override
+    public void onApplicationEvent(ContextClosedEvent event) {
+        log.error("Application Terminated: {}", event.getTimestamp());
+        terminateApplication();
     }
     @Override
     public void afterPropertiesSet() throws Exception {
-        //System.err.println("InitializingBean 인터페이스 구현 메서드입니다. 'Bean'이 생성될 때 마다 호출되는 메서드 입니다.");
     }
     @Override
     public void destroy() throws Exception {
-        //System.err.println("DisposableBean 인터페이스 구현 메서드입니다. 'Bean'이 소멸될 때 마다 호출되는 메서드입니다");
     }
 
 }

+ 5 - 0
src/main/java/com/its/wthr/service/AtmpService.java

@@ -93,6 +93,7 @@ public class AtmpService extends AbstractXmlService {
                     errCnt++;
                     AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestResult(0);
                     AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestValue(e1.toString());
+                    AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setValue(e1.toString());
                     log.error("AtmpService.doJob: getAtmpInfo, {}: {}, {}", obj.getATMP_STTN_NMBR(), obj.getATMP_STTN_NM(), e1.toString());
                 }
             }
@@ -137,6 +138,7 @@ public class AtmpService extends AbstractXmlService {
                     errCnt++;
                     AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestResult(0);
                     AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestValue(e.toString());
+                    AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setValue(e.toString());
                     log.error("AtmpService.doJob-retry:, {}: {}, Exception: {}", obj.getATMP_STTN_NMBR(), obj.getATMP_STTN_NM(), e1.toString());
                 }
 
@@ -162,15 +164,18 @@ public class AtmpService extends AbstractXmlService {
                     stts.setATMP_STTN_NMBR(obj.getATMP_STTN_NMBR());
                     AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestResult(1);
                     AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestValue(stts.toString());
+                    AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setValue(stts.getValue());
                 }
                 else {
                     AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestResult(0);
                     AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestValue("");
+                    AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setValue("");
                 }
             }
             catch(Exception e) {
                 AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestResult(0);
                 AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setRequestValue(e.toString());
+                AppRepository.getInstance().getAtmpPltnMap().get(obj.getATMP_STTN_NMBR()).setValue(e.toString());
                 log.error("AtmpService.requestJob: {}: {}, Exception: {}", obj.getATMP_STTN_NMBR(), obj.getATMP_STTN_NM(), e.toString());
             }
         }

+ 6 - 0
src/main/java/com/its/wthr/service/FrcsService.java

@@ -102,17 +102,20 @@ public class FrcsService extends AbstractXmlService {
 
                         AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestResult(1);
                         AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestValue(frcsZoneSttsList.get(0).toString());
+                        AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setValue(frcsZoneSttsList.get(0).getValue());
                     }
                     else {
                         errCnt++;
                         AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestResult(0);
                         AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestValue("");
+                        AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setValue("");
                     }
                 }
                 catch(Exception e1) {
                     errCnt++;
                     AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestResult(0);
                     AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestValue(e1.toString());
+                    AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setValue(e1.toString());
                     log.error("FrcsService.doJob: {}: {}, Exception: {}", obj.getVILG_FRCS_ZONE_CD(), obj.getVILG_FRCS_ZONE_NM(), e1.toString());
                 }
             }
@@ -147,16 +150,19 @@ public class FrcsService extends AbstractXmlService {
 
                         AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestResult(1);
                         AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestValue(frcsZoneSttsList.get(0).toString());
+                        AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setValue(frcsZoneSttsList.get(0).getValue());
                     }
                     else {
                         errCnt++;
                         AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestResult(0);
                         AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestValue("");
+                        AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setValue("");
                     }
                 } catch (Exception e1) {
                     errCnt++;
                     AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestResult(0);
                     AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setRequestValue(e.toString());
+                    AppRepository.getInstance().getFrcsZoneMap().get(obj.getVILG_FRCS_ZONE_CD()).setValue(e.toString());
                     log.error("FrcsService.doJob-retry: {}: {}, Exception: {}", obj.getVILG_FRCS_ZONE_CD(), obj.getVILG_FRCS_ZONE_NM(), e1.toString());
                 }
             }

+ 30 - 0
src/main/java/com/its/wthr/ui/AtmpTableCellRenderer.java

@@ -0,0 +1,30 @@
+package com.its.wthr.ui;
+
+import javax.swing.*;
+import javax.swing.table.DefaultTableCellRenderer;
+import java.awt.*;
+
+public class AtmpTableCellRenderer extends DefaultTableCellRenderer {
+
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+
+        Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+        String commStts = table.getModel().getValueAt(row, 3).toString();
+        if (commStts.equals("성공")) {
+            cell.setBackground(new Color(255, 255, 255, 255));
+        } else {
+            cell.setBackground(new Color(182, 97, 97, 176));
+        }
+
+        if (column != 2 && column != 5) {
+            setHorizontalAlignment(SwingConstants.CENTER);
+        } else {
+            setHorizontalAlignment(SwingConstants.LEFT);
+        }
+        if (column == 0) {
+            cell.setBackground(Color.LIGHT_GRAY);
+        }
+
+        return cell;
+    }
+}

+ 134 - 0
src/main/java/com/its/wthr/ui/AtmpTableModel.java

@@ -0,0 +1,134 @@
+package com.its.wthr.ui;
+
+import com.its.wthr.vo.AtmpPltnVo;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.swing.table.AbstractTableModel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@Slf4j
+public class AtmpTableModel extends AbstractTableModel {
+    private static final long serialVersionUID = 1331132425472559704L;
+
+    private List<AtmpPltnVo> ctlrList = Collections.synchronizedList(new ArrayList<AtmpPltnVo>());
+    private final String[] columnNames = {
+            "#",
+            "번호",
+            "측정소명칭",
+            "상태",
+            "마지막 요청시각",
+            "대기환경 실시간 현황"
+    };
+
+    public AtmpTableModel(List<AtmpPltnVo> ctlrList) {
+        this.ctlrList = ctlrList;
+
+        int indexCount = 1;
+        for (AtmpPltnVo obj : ctlrList) {
+            obj.setIndex(indexCount++);
+        }
+        if (ctlrList.size() == 0) {
+            log.error("AtmpTableModel Data zero: {}", 0);
+        }
+    }
+
+    @Override
+    public int getColumnCount() {
+        return columnNames.length;
+    }
+
+    @Override
+    public int getRowCount() {
+        int size = 0;
+        synchronized (this.ctlrList) {
+            size = this.ctlrList.size();
+        }
+        return size;
+    }
+
+    @Override
+    public String getColumnName(int columnIndex) {
+        if (columnIndex < columnNames.length) {
+            return columnNames[columnIndex];
+        }
+        return super.getColumnName(columnIndex);
+    }
+
+    @Override
+    public Class<?> getColumnClass(int columnIndex) {
+        if (ctlrList.isEmpty()) {
+            return Object.class;
+        }
+        return getValueAt(0, columnIndex).getClass();
+    }
+
+    public AtmpPltnVo getControllerInfo(int row) {
+        AtmpPltnVo info = this.ctlrList.get(row);
+        return info;
+    }
+
+    @Override
+    public Object getValueAt(int rowIndex, int columnIndex) {
+        Object returnValue = null;
+        synchronized (this.ctlrList) {
+            AtmpPltnVo info = this.ctlrList.get(rowIndex);
+            if (info == null) {
+                return "";
+            }
+
+            switch (columnIndex) {
+                case 0:
+                    returnValue = info.getIndex();
+                    break;
+                case 1:
+                    returnValue = info.getATMP_STTN_NMBR();
+                    break;
+                case 2:
+                    returnValue = info.getATMP_STTN_NM();
+                    break;
+                case 3:
+                    returnValue = info.getRequestResult() == 0 ? "실패" : "성공";
+                    break;
+                case 4:
+                    returnValue = info.getRequestTime();
+                    break;
+                case 5:
+                    returnValue = info.getValue();
+                    break;
+            }
+        }
+        return returnValue;
+    }
+
+    @Override
+    public void setValueAt(Object value, int rowIndex, int columnIndex) {
+        synchronized (this.ctlrList) {
+            AtmpPltnVo obj = ctlrList.get(rowIndex);
+            if (columnIndex == 0) {
+                obj.setIndex((int) value);
+            }
+        }
+    }
+    public void setValueAt(AtmpPltnVo obj, int rowIdx, int colIdx) {
+        synchronized (this.ctlrList) {
+        }
+        fireTableCellUpdated(rowIdx, colIdx);
+        fireTableDataChanged();
+    }
+
+    public void Add(AtmpPltnVo info) {
+        int index = 0;
+        synchronized (this.ctlrList) {
+            index = this.ctlrList.size();
+            this.ctlrList.add(info);
+        }
+        fireTableRowsInserted(index, index);
+    }
+
+    public void setValue(AtmpPltnVo obj, int viewRow, int modelRow) {
+        fireTableDataChanged();
+    }
+
+}

+ 30 - 0
src/main/java/com/its/wthr/ui/FrcsTableCellRenderer.java

@@ -0,0 +1,30 @@
+package com.its.wthr.ui;
+
+import javax.swing.*;
+import javax.swing.table.DefaultTableCellRenderer;
+import java.awt.*;
+
+public class FrcsTableCellRenderer extends DefaultTableCellRenderer {
+
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+
+        Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+        String commStts = table.getModel().getValueAt(row, 3).toString();
+        if (commStts.equals("성공")) {
+            cell.setBackground(new Color(255, 255, 255, 255));
+        } else {
+            cell.setBackground(new Color(182, 97, 97, 176));
+        }
+
+        if (column != 2 && column != 5) {
+            setHorizontalAlignment(SwingConstants.CENTER);
+        } else {
+            setHorizontalAlignment(SwingConstants.LEFT);
+        }
+        if (column == 0) {
+            cell.setBackground(Color.LIGHT_GRAY);
+        }
+
+        return cell;
+    }
+}

+ 134 - 0
src/main/java/com/its/wthr/ui/FrcsTableModel.java

@@ -0,0 +1,134 @@
+package com.its.wthr.ui;
+
+import com.its.wthr.vo.AtmpPltnVo;
+import com.its.wthr.vo.FrcsZoneVo;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.swing.table.AbstractTableModel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@Slf4j
+public class FrcsTableModel extends AbstractTableModel {
+    private static final long serialVersionUID = 1331132425472559704L;
+
+    private List<FrcsZoneVo> ctlrList = Collections.synchronizedList(new ArrayList<FrcsZoneVo>());
+    private final String[] columnNames = {
+            "#",
+            "구역코드",
+            "예보구역",
+            "상태",
+            "마지막 요청시각",
+            "동네예보 실시간 현황"
+    };
+
+    public FrcsTableModel(List<FrcsZoneVo> ctlrList) {
+        this.ctlrList = ctlrList;
+
+        int indexCount = 1;
+        for (FrcsZoneVo obj : ctlrList) {
+            obj.setIndex(indexCount++);
+        }
+        if (ctlrList.size() == 0) {
+            log.error("FrcsTableModel Data zero: {}", 0);
+        }
+    }
+
+    @Override
+    public int getColumnCount() {
+        return columnNames.length;
+    }
+
+    @Override
+    public int getRowCount() {
+        int size = 0;
+        synchronized (this.ctlrList) {
+            size = this.ctlrList.size();
+        }
+        return size;
+    }
+
+    @Override
+    public String getColumnName(int columnIndex) {
+        if (columnIndex < columnNames.length) {
+            return columnNames[columnIndex];
+        }
+        return super.getColumnName(columnIndex);
+    }
+
+    @Override
+    public Class<?> getColumnClass(int columnIndex) {
+        if (ctlrList.isEmpty()) {
+            return Object.class;
+        }
+        return getValueAt(0, columnIndex).getClass();
+    }
+
+    public FrcsZoneVo getControllerInfo(int row) {
+        FrcsZoneVo info = this.ctlrList.get(row);
+        return info;
+    }
+
+    @Override
+    public Object getValueAt(int rowIndex, int columnIndex) {
+        Object returnValue = null;
+        synchronized (this.ctlrList) {
+            FrcsZoneVo info = this.ctlrList.get(rowIndex);
+            if (info == null) {
+                return "";
+            }
+            switch (columnIndex) {
+                case 0:
+                    returnValue = info.getIndex();
+                    break;
+                case 1:
+                    returnValue = info.getVILG_FRCS_ZONE_CD();
+                    break;
+                case 2:
+                    returnValue = info.getVILG_FRCS_ZONE_NM();
+                    break;
+                case 3:
+                    returnValue = info.getRequestResult() == 0 ? "실패" : "성공";
+                    break;
+                case 4:
+                    returnValue = info.getRequestTime();
+                    break;
+                case 5:
+                    returnValue = info.getValue();
+                    break;
+            }
+        }
+        return returnValue;
+    }
+
+    @Override
+    public void setValueAt(Object value, int rowIndex, int columnIndex) {
+        synchronized (this.ctlrList) {
+            FrcsZoneVo obj = ctlrList.get(rowIndex);
+            if (columnIndex == 0) {
+                obj.setIndex((int) value);
+            }
+        }
+    }
+    public void setValueAt(AtmpPltnVo obj, int rowIdx, int colIdx) {
+        synchronized (this.ctlrList) {
+        }
+        fireTableCellUpdated(rowIdx, colIdx);
+        fireTableDataChanged();
+    }
+
+    public void Add(FrcsZoneVo info) {
+        int index = 0;
+        synchronized (this.ctlrList) {
+            index = this.ctlrList.size();
+            this.ctlrList.add(info);
+        }
+        fireTableRowsInserted(index, index);
+    }
+
+    public void setValue(FrcsZoneVo obj, int viewRow, int modelRow) {
+        fireTableDataChanged();
+    }
+
+}

+ 90 - 0
src/main/java/com/its/wthr/ui/JTextAreaOutputStream.java

@@ -0,0 +1,90 @@
+package com.its.wthr.ui;
+
+import javax.swing.*;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class JTextAreaOutputStream extends OutputStream {
+
+    private final JTextArea logArea;
+    public static boolean isLoggingPause = false;
+    private final StringBuilder sb = new StringBuilder();
+
+    public JTextAreaOutputStream(JTextArea logArea) {
+        if (logArea == null)
+            throw new IllegalArgumentException ("Destination is null...");
+        this.logArea = logArea;
+    }
+//
+//    public synchronized void logWrite(String text) {
+//        Runnable  runnable = new Runnable() {
+//            public void run() {
+//                logArea.append(text);
+//                if (logArea.getDocument().getLength() >
+//                        50000) {
+//                    try {
+//                        logArea.getDocument().remove(0, 5000);
+//                    } catch (BadLocationException e) {
+//                        //log.error("Can't clean log", e);
+//                    }
+//                }
+//                logArea.setCaretPosition(logArea.getDocument().getLength());
+//            }
+//        };
+//        SwingUtilities.invokeLater(runnable);
+//    }
+
+    @Override
+    public void write(byte[] buffer, int offset, int length) throws IOException
+    {
+        if (isLoggingPause) {
+            return;
+        }
+
+        final String text = new String(buffer, offset, length, "UTF-8");
+        //logWrite(text);
+        SwingUtilities.invokeLater(new Runnable ()
+        {
+            @Override
+            public void run()
+            {
+                synchronized (logArea) {
+                    if (logArea.getLineCount() > 2000) {
+                        logArea.setText(null);
+                    }
+                    logArea.append(text);
+                    logArea.setCaretPosition(logArea.getDocument().getLength());
+                }
+            }
+        });
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+//        if (b == '\r')
+//            return;
+
+        if (b == '\n') {
+            final String text = sb.toString() + "\n";
+            SwingUtilities.invokeLater(new Runnable ()
+            {
+                @Override
+                public void run()
+                {
+                    synchronized (logArea) {
+                        if (logArea.getLineCount() > 2000) {
+                            logArea.setText(null);
+                        }
+                        logArea.append(text);
+                        logArea.setCaretPosition(logArea.getDocument().getLength());
+                        sb.setLength(0);
+                    }
+                }
+            });
+        } else {
+            sb.append((char) b);
+        }
+
+        //write (new byte [] {(byte)b}, 0, 1);
+    }
+}

+ 270 - 0
src/main/java/com/its/wthr/ui/MainUI.form

@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.its.wthr.ui.MainUI">
+  <grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="927" height="563"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <grid id="d0095" binding="pnlCtlr" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="10" left="4" bottom="0" right="4"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <tabbedpane id="bb81f" binding="tabInfo">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
+                <preferred-size width="200" height="200"/>
+              </grid>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <grid id="deba2" binding="tabAtmp" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
+                <constraints>
+                  <tabbedpane title="대기환경 "/>
+                </constraints>
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <scrollpane id="8694">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties/>
+                    <border type="none"/>
+                    <children>
+                      <component id="e6226" class="javax.swing.JTable" binding="listAtmp">
+                        <constraints/>
+                        <properties/>
+                      </component>
+                    </children>
+                  </scrollpane>
+                </children>
+              </grid>
+              <grid id="e611a" binding="tabFrcs" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
+                <constraints>
+                  <tabbedpane title="동네예보 "/>
+                </constraints>
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <scrollpane id="ee5ca">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties/>
+                    <border type="none"/>
+                    <children>
+                      <component id="1b73a" class="javax.swing.JTable" binding="listFrcs">
+                        <constraints/>
+                        <properties/>
+                      </component>
+                    </children>
+                  </scrollpane>
+                </children>
+              </grid>
+            </children>
+          </tabbedpane>
+        </children>
+      </grid>
+      <grid id="1a658" binding="pnlLog" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="4" bottom="0" right="4"/>
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
+            <minimum-size width="-1" height="200"/>
+            <preferred-size width="-1" height="200"/>
+            <maximum-size width="-1" height="200"/>
+          </grid>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <grid id="dbb05" binding="pnlLogTitle" layout-manager="GridLayoutManager" row-count="1" column-count="6" same-size-horizontally="false" same-size-vertically="false" hgap="1" vgap="1">
+            <margin top="0" left="0" bottom="0" right="2"/>
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="9ac90" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <font name="Malgun Gothic" size="12" style="0"/>
+                  <horizontalAlignment value="2"/>
+                  <icon value="static/image/logging.png"/>
+                  <text value="시스템 로그"/>
+                </properties>
+              </component>
+              <hspacer id="656fd">
+                <constraints>
+                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+              </hspacer>
+              <component id="df2a0" class="javax.swing.JButton" binding="btnLogDirOpen">
+                <constraints>
+                  <grid row="0" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <font name="Malgun Gothic" size="12" style="0"/>
+                  <horizontalTextPosition value="0"/>
+                  <text value="로그 폴더"/>
+                </properties>
+              </component>
+              <component id="69a98" class="javax.swing.JButton" binding="btnLogPause">
+                <constraints>
+                  <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <font name="Malgun Gothic" size="12" style="0"/>
+                  <horizontalTextPosition value="0"/>
+                  <text value="지우기"/>
+                </properties>
+              </component>
+              <component id="1e9e7" class="javax.swing.JCheckBox" binding="chkLogPause">
+                <constraints>
+                  <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <font name="Malgun Gothic" size="12" style="0"/>
+                  <horizontalAlignment value="0"/>
+                  <horizontalTextPosition value="11"/>
+                  <text value="멈춤"/>
+                </properties>
+              </component>
+              <component id="ba97c" class="javax.swing.JButton" binding="btnLogCopy">
+                <constraints>
+                  <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <font name="Malgun Gothic" size="12" style="0"/>
+                  <text value="복사"/>
+                </properties>
+              </component>
+            </children>
+          </grid>
+          <scrollpane id="a6866">
+            <constraints>
+              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <font name="D2Coding" size="12" style="0"/>
+            </properties>
+            <border type="none"/>
+            <children>
+              <component id="8ce8a" class="javax.swing.JTextArea" binding="taLog">
+                <constraints/>
+                <properties>
+                  <background color="-16777216"/>
+                  <caretColor color="-1"/>
+                  <editable value="false"/>
+                  <font name="D2Coding" size="14" style="0"/>
+                  <foreground color="-1"/>
+                  <margin top="4" left="4" bottom="4" right="4"/>
+                  <text value="[10:50:08.561] [ INFO] ************************************************************************************&#10;[10:50:08.561] [ INFO] **                   Center Communication Server Information                      **&#10;[10:50:08.561] [ INFO] **     bindAddress: 0.0.0.0&#10;[10:50:08.561] [ INFO] **      listenPort: 9901&#10;[10:50:08.561] [ INFO] **         backlog: 1024&#10;[10:50:08.561] [ INFO] **   acceptThreads: 16&#10;[10:50:08.561] [ INFO] **   workerThreads: 16&#10;[10:50:08.561] [ INFO] ************************************************************************************&#10;"/>
+                </properties>
+              </component>
+            </children>
+          </scrollpane>
+        </children>
+      </grid>
+      <grid id="e0774" binding="pnlStatusBar" layout-manager="GridLayoutManager" row-count="1" column-count="7" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="4" bottom="4" right="4"/>
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <hspacer id="653ec">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+            </constraints>
+          </hspacer>
+          <component id="20f9" class="javax.swing.JLabel" binding="lblSystime">
+            <constraints>
+              <grid row="0" column="6" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <font name="Malgun Gothic" size="12" style="1"/>
+              <horizontalAlignment value="0"/>
+              <horizontalTextPosition value="0"/>
+              <text value=" 2022-08-04 13:24:33 "/>
+            </properties>
+          </component>
+          <component id="a516b" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <icon value="static/image/on.png"/>
+              <text value=" "/>
+            </properties>
+          </component>
+          <component id="94189" class="javax.swing.JLabel" binding="lblCpuRate">
+            <constraints>
+              <grid row="0" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
+                <minimum-size width="40" height="-1"/>
+                <preferred-size width="40" height="-1"/>
+                <maximum-size width="40" height="-1"/>
+              </grid>
+            </constraints>
+            <properties>
+              <font name="Malgun Gothic" size="12" style="1"/>
+              <horizontalAlignment value="2"/>
+              <horizontalTextPosition value="0"/>
+              <text value="    "/>
+            </properties>
+          </component>
+          <component id="19dbe" class="javax.swing.JLabel" binding="lblMemoryUsage">
+            <constraints>
+              <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
+                <minimum-size width="40" height="-1"/>
+                <preferred-size width="40" height="-1"/>
+                <maximum-size width="40" height="-1"/>
+              </grid>
+            </constraints>
+            <properties>
+              <font name="Malgun Gothic" size="12" style="1"/>
+              <horizontalAlignment value="2"/>
+              <horizontalTextPosition value="0"/>
+              <text value="    "/>
+            </properties>
+          </component>
+          <component id="f6d5e" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <font name="Malgun Gothic" size="12" style="0"/>
+              <horizontalAlignment value="0"/>
+              <horizontalTextPosition value="0"/>
+              <text value="  CPU 사용율(%):"/>
+            </properties>
+          </component>
+          <component id="d8ff5" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <font name="Malgun Gothic" size="12" style="0"/>
+              <horizontalAlignment value="0"/>
+              <horizontalTextPosition value="0"/>
+              <text value="  메모리 사용율(%):"/>
+            </properties>
+          </component>
+        </children>
+      </grid>
+    </children>
+  </grid>
+</form>

+ 472 - 0
src/main/java/com/its/wthr/ui/MainUI.java

@@ -0,0 +1,472 @@
+package com.its.wthr.ui;
+
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.uiDesigner.core.Spacer;
+import com.its.app.utils.SysUtils;
+import com.its.wthr.repository.AppRepository;
+import com.its.wthr.vo.AtmpPltnVo;
+import com.its.wthr.vo.FrcsZoneVo;
+import com.sun.management.OperatingSystemMXBean;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.swing.Timer;
+import javax.swing.*;
+import javax.swing.border.MatteBorder;
+import javax.swing.plaf.FontUIResource;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumnModel;
+import javax.swing.text.StyleContext;
+import java.awt.*;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+import java.util.*;
+
+@Slf4j
+@Getter
+public class MainUI {
+    private static MainUI _instance = null;
+
+    private JFrame jFrame = null;
+    private final OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
+    private Timer timer;
+    private Long tick = Long.valueOf(0);
+    private AtmpPltnVo selObj = null;
+
+    private AtmpTableModel atmpTableModel = null;
+    private FrcsTableModel frcsTableModel = null;
+    private TableCellRenderer atmpCellRenderer = new AtmpTableCellRenderer();
+    private TableCellRenderer frcsCellRenderer = new FrcsTableCellRenderer();
+
+    private JPanel rootPanel;
+    private JPanel pnlCtlr;
+    private JPanel pnlLog;
+    private JPanel pnlLogTitle;
+    private JButton btnLogDirOpen;
+    private JButton btnLogPause;
+    private JCheckBox chkLogPause;
+    private JLabel lblSystime;
+    private JPanel pnlStatusBar;
+    private JTextArea taLog;
+    private JButton btnLogCopy;
+    private JLabel lblCpuRate;
+    private JLabel lblMemoryUsage;
+    private JTabbedPane tabInfo;
+    private JPanel tabAtmp;
+    private JPanel tabFrcs;
+    private JTable listAtmp;
+    private JTable listFrcs;
+
+    public static MainUI getInstance() {
+        return _instance;
+    }
+
+    public void displaySystime() {
+        lblSystime.setText(" " + SysUtils.getSysTimeStr() + "  ");
+    }
+
+    public void displayResource() {
+        //OperatingSystemMXBean osBean = (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
+        long memoryUsage = Math.round(((double) (osBean.getTotalPhysicalMemorySize() - osBean.getFreePhysicalMemorySize())) / (double) osBean.getTotalPhysicalMemorySize() * 100.0);
+        lblMemoryUsage.setText(String.valueOf(memoryUsage));
+        double cpuLoad = osBean.getSystemCpuLoad();
+        if (cpuLoad >= 0.0 && cpuLoad <= 1.0) {
+            lblCpuRate.setText(String.valueOf(Math.round(cpuLoad * 100.0)));
+        } else {
+            lblCpuRate.setText("---");
+        }
+//        if (osBean instanceof com.sun.management.OperatingSystemMXBean) {
+//            com.sun.management.OperatingSystemMXBean nativeOsBean = (com.sun.management.OperatingSystemMXBean)osBean;
+//            log.error("CPU LOAD: {}", Math.ceil(nativeOsBean.getSystemCpuLoad() * 100.0));
+//        }
+//        else {
+//            log.error("You're not using Oracle Java nor using the native library. You won't be able to read some native data");
+//        }
+    }
+
+    public MainUI(JFrame jFrame) {
+        System.setProperty("awt.useSystemAAFontSettings", "false"); // AntiAliasing false
+
+        this.jFrame = jFrame;
+        if (_instance == null) {
+            _instance = this;
+        }
+
+        try {
+            Font font = Font.createFont(Font.TRUETYPE_FONT, new File("fonts/D2Coding.ttc"));
+            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+            ge.registerFont(font);
+        } catch (FontFormatException e) {
+        } catch (IOException e) {
+        }
+
+        Font d2font = new Font("D2Coding", Font.PLAIN, 14);
+        if (d2font != null) {
+            taLog.setFont(d2font);
+        }
+
+        displaySystime();
+        displayResource();
+        timer = new Timer(1000, new ActionListener() {
+            public void actionPerformed(ActionEvent evt) {
+                displaySystime();
+                tick++;
+                if (tick % 5 == 0) {
+                    displayResource();
+                }
+            }
+        });
+        timer.start();
+
+        chkLogPause.setFocusable(false);
+        btnLogPause.setFocusable(false);
+        btnLogDirOpen.setFocusable(false);
+        btnLogCopy.setFocusable(false);
+
+        btnLogPause.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                taLog.setText(null);
+            }
+        });
+        btnLogDirOpen.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                Runtime rt = Runtime.getRuntime();
+                try {
+                    rt.exec("explorer.exe logs");
+                } catch (IOException ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        });
+        chkLogPause.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                JTextAreaOutputStream.isLoggingPause = chkLogPause.isSelected();
+            }
+        });
+        btnLogCopy.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                StringSelection stringSelection = new StringSelection(taLog.getText());
+                Clipboard clpBrd = Toolkit.getDefaultToolkit().getSystemClipboard();
+                clpBrd.setContents(stringSelection, null);
+            }
+        });
+
+    }
+
+    /**
+     * 목록 헤더 생성
+     */
+    private void initTblListUI(List<AtmpPltnVo> atmpList, List<FrcsZoneVo> frcsList) {
+
+        this.atmpTableModel = new AtmpTableModel(atmpList);
+
+        listAtmp.setModel(this.atmpTableModel);
+
+        listAtmp.getTableHeader().setOpaque(false);
+        listAtmp.getTableHeader().setBackground(Color.LIGHT_GRAY);
+        listAtmp.setRowMargin(1);
+        listAtmp.setRowHeight(listAtmp.getRowHeight() + 5);
+
+        listAtmp.setBackground(Color.WHITE);
+        listAtmp.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+        TableColumnModel getColumnModel = listAtmp.getColumnModel();
+        getColumnModel.getColumn(0).setPreferredWidth(30);  //  "S",
+        getColumnModel.getColumn(1).setPreferredWidth(100);  //  "번호",
+        getColumnModel.getColumn(2).setPreferredWidth(80);  //  "측정소명칭",
+        getColumnModel.getColumn(3).setPreferredWidth(50); //  "상태",
+        getColumnModel.getColumn(4).setPreferredWidth(130); //  "마지막 요청시각",
+        getColumnModel.getColumn(5).setPreferredWidth(400);  //  "대기환경 실시간 현황",
+
+        getColumnModel.getColumn(0).setMaxWidth(30);
+        getColumnModel.getColumn(0).setMinWidth(30);
+        getColumnModel.getColumn(0).setResizable(false);
+
+        getColumnModel.getColumn(1).setMaxWidth(100);
+        getColumnModel.getColumn(1).setMinWidth(100);
+        getColumnModel.getColumn(1).setResizable(false);
+
+        getColumnModel.getColumn(2).setMaxWidth(80);
+        getColumnModel.getColumn(2).setMinWidth(80);
+        getColumnModel.getColumn(2).setResizable(false);
+
+        getColumnModel.getColumn(3).setMaxWidth(50);
+        getColumnModel.getColumn(3).setMinWidth(50);
+        getColumnModel.getColumn(3).setResizable(false);
+
+        getColumnModel.getColumn(4).setMaxWidth(130);
+        getColumnModel.getColumn(4).setMinWidth(130);
+        getColumnModel.getColumn(4).setResizable(false);
+
+        Color color = UIManager.getColor("Table.gridColor");
+        MatteBorder border = new MatteBorder(1, 1, 0, 0, color);
+        listAtmp.setBorder(border);
+
+        DefaultTableCellRenderer centerAlign = new DefaultTableCellRenderer();
+        centerAlign.setHorizontalAlignment(JLabel.CENTER);
+        for (int ii = 0; ii < getColumnModel.getColumnCount(); ii++) {
+            getColumnModel.getColumn(ii).setCellRenderer(atmpCellRenderer);
+        }
+
+
+        this.frcsTableModel = new FrcsTableModel(frcsList);
+        listFrcs.setModel(this.frcsTableModel);
+
+        listFrcs.getTableHeader().setOpaque(false);
+        listFrcs.getTableHeader().setBackground(Color.LIGHT_GRAY);
+        listAtmp.setRowMargin(1);
+        listFrcs.setRowHeight(listFrcs.getRowHeight() + 5);
+
+        listFrcs.setBackground(Color.WHITE);
+        listFrcs.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+        TableColumnModel getColumnModel_ = listFrcs.getColumnModel();
+        getColumnModel_.getColumn(0).setPreferredWidth(30);  //  "S",
+        getColumnModel_.getColumn(1).setPreferredWidth(100);  //  "구역코드",
+
+        getColumnModel_.getColumn(2).setPreferredWidth(80);  //  "예보구역명칭",
+        getColumnModel_.getColumn(3).setPreferredWidth(50); //  "상태",
+        getColumnModel_.getColumn(4).setPreferredWidth(130); //  "마지막 요청시각",
+        getColumnModel_.getColumn(5).setPreferredWidth(400);  //  "동네예보 실시간 현황",
+
+        getColumnModel_.getColumn(0).setMaxWidth(30);
+        getColumnModel_.getColumn(0).setMinWidth(30);
+        getColumnModel_.getColumn(0).setResizable(false);
+
+        getColumnModel_.getColumn(1).setMaxWidth(100);
+        getColumnModel_.getColumn(1).setMinWidth(100);
+        getColumnModel_.getColumn(1).setResizable(false);
+
+        getColumnModel_.getColumn(2).setMaxWidth(80);
+        getColumnModel_.getColumn(2).setMinWidth(80);
+        getColumnModel_.getColumn(2).setResizable(false);
+
+        getColumnModel_.getColumn(3).setMaxWidth(50);
+        getColumnModel_.getColumn(3).setMinWidth(50);
+        getColumnModel_.getColumn(3).setResizable(false);
+
+        getColumnModel_.getColumn(4).setMaxWidth(130);
+        getColumnModel_.getColumn(4).setMinWidth(130);
+        getColumnModel_.getColumn(4).setResizable(false);
+
+        listFrcs.setBorder(border);
+
+        for (int ii = 0; ii < getColumnModel_.getColumnCount(); ii++) {
+            getColumnModel_.getColumn(ii).setCellRenderer(frcsCellRenderer);
+        }
+
+    }
+
+    public void LoadControllerInfo() {
+        SortedMap<Integer, AtmpPltnVo> atmpMap = new TreeMap<>();
+        for (Map.Entry<String, AtmpPltnVo> e : AppRepository.getInstance().getAtmpPltnMap().entrySet()) {
+            AtmpPltnVo obj = e.getValue();
+            atmpMap.put(Integer.valueOf(obj.getATMP_STTN_NMBR()), obj);
+        }
+
+        SortedMap<String, FrcsZoneVo> frcsMap = new TreeMap<>();
+        for (Map.Entry<String, FrcsZoneVo> e : AppRepository.getInstance().getFrcsZoneMap().entrySet()) {
+            FrcsZoneVo obj = e.getValue();
+            frcsMap.put(obj.getVILG_FRCS_ZONE_CD(), obj);
+        }
+
+        List<AtmpPltnVo> atmpList = new ArrayList<AtmpPltnVo>(atmpMap.values());
+        List<FrcsZoneVo> frcsList = new ArrayList<FrcsZoneVo>(frcsMap.values());
+
+        initTblListUI(atmpList, frcsList);
+    }
+
+    public void updateCtlrStts(AtmpPltnVo obj) {
+        if (this.atmpTableModel == null) {
+            return;
+        }
+        for (int ii = 0; ii < this.atmpTableModel.getRowCount(); ii++) {
+//            if (obj.getPIS_NMBR().equals(ctlrSttsTableModel.getValueAt(ii, 1).toString())) {
+//                int modelRow = tblCtlrList.convertRowIndexToModel(ii);
+//                this.ctlrSttsTableModel.setValue(obj, ii, modelRow);
+//                break;
+//            }
+        }
+        AtmpTableModel tableModel = (AtmpTableModel) listAtmp.getModel();
+        if (tableModel != null) {
+            tableModel.fireTableDataChanged();
+        }
+    }
+
+    {
+// GUI initializer generated by IntelliJ IDEA GUI Designer
+// >>> IMPORTANT!! <<<
+// DO NOT EDIT OR ADD ANY CODE HERE!
+        $$$setupUI$$$();
+    }
+
+    /**
+     * Method generated by IntelliJ IDEA GUI Designer
+     * >>> IMPORTANT!! <<<
+     * DO NOT edit this method OR call it in your code!
+     *
+     * @noinspection ALL
+     */
+    private void $$$setupUI$$$() {
+        rootPanel = new JPanel();
+        rootPanel.setLayout(new GridLayoutManager(3, 1, new Insets(0, 0, 0, 0), -1, -1));
+        pnlCtlr = new JPanel();
+        pnlCtlr.setLayout(new GridLayoutManager(1, 1, new Insets(10, 4, 0, 4), -1, -1));
+        rootPanel.add(pnlCtlr, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
+        tabInfo = new JTabbedPane();
+        pnlCtlr.add(tabInfo, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, new Dimension(200, 200), null, 0, false));
+        tabAtmp = new JPanel();
+        tabAtmp.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
+        tabInfo.addTab("대기환경 ", tabAtmp);
+        final JScrollPane scrollPane1 = new JScrollPane();
+        tabAtmp.add(scrollPane1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
+        listAtmp = new JTable();
+        scrollPane1.setViewportView(listAtmp);
+        tabFrcs = new JPanel();
+        tabFrcs.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
+        tabInfo.addTab("동네예보 ", tabFrcs);
+        final JScrollPane scrollPane2 = new JScrollPane();
+        tabFrcs.add(scrollPane2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
+        listFrcs = new JTable();
+        scrollPane2.setViewportView(listFrcs);
+        pnlLog = new JPanel();
+        pnlLog.setLayout(new GridLayoutManager(2, 1, new Insets(0, 4, 0, 4), -1, -1));
+        rootPanel.add(pnlLog, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, new Dimension(-1, 200), new Dimension(-1, 200), new Dimension(-1, 200), 0, false));
+        pnlLogTitle = new JPanel();
+        pnlLogTitle.setLayout(new GridLayoutManager(1, 6, new Insets(0, 0, 0, 2), 1, 1));
+        pnlLog.add(pnlLogTitle, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
+        final JLabel label1 = new JLabel();
+        Font label1Font = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, label1.getFont());
+        if (label1Font != null) label1.setFont(label1Font);
+        label1.setHorizontalAlignment(2);
+        label1.setIcon(new ImageIcon(getClass().getResource("/static/image/logging.png")));
+        label1.setText("시스템 로그");
+        pnlLogTitle.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+        final Spacer spacer1 = new Spacer();
+        pnlLogTitle.add(spacer1, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
+        btnLogDirOpen = new JButton();
+        Font btnLogDirOpenFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnLogDirOpen.getFont());
+        if (btnLogDirOpenFont != null) btnLogDirOpen.setFont(btnLogDirOpenFont);
+        btnLogDirOpen.setHorizontalTextPosition(0);
+        btnLogDirOpen.setText("로그 폴더");
+        pnlLogTitle.add(btnLogDirOpen, new GridConstraints(0, 5, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+        btnLogPause = new JButton();
+        Font btnLogPauseFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnLogPause.getFont());
+        if (btnLogPauseFont != null) btnLogPause.setFont(btnLogPauseFont);
+        btnLogPause.setHorizontalTextPosition(0);
+        btnLogPause.setText("지우기");
+        pnlLogTitle.add(btnLogPause, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+        chkLogPause = new JCheckBox();
+        Font chkLogPauseFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, chkLogPause.getFont());
+        if (chkLogPauseFont != null) chkLogPause.setFont(chkLogPauseFont);
+        chkLogPause.setHorizontalAlignment(0);
+        chkLogPause.setHorizontalTextPosition(11);
+        chkLogPause.setText("멈춤");
+        pnlLogTitle.add(chkLogPause, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+        btnLogCopy = new JButton();
+        Font btnLogCopyFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnLogCopy.getFont());
+        if (btnLogCopyFont != null) btnLogCopy.setFont(btnLogCopyFont);
+        btnLogCopy.setText("복사");
+        pnlLogTitle.add(btnLogCopy, new GridConstraints(0, 4, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+        final JScrollPane scrollPane3 = new JScrollPane();
+        Font scrollPane3Font = this.$$$getFont$$$("D2Coding", Font.PLAIN, 12, scrollPane3.getFont());
+        if (scrollPane3Font != null) scrollPane3.setFont(scrollPane3Font);
+        pnlLog.add(scrollPane3, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
+        taLog = new JTextArea();
+        taLog.setBackground(new Color(-16777216));
+        taLog.setCaretColor(new Color(-1));
+        taLog.setEditable(false);
+        Font taLogFont = this.$$$getFont$$$("D2Coding", Font.PLAIN, 14, taLog.getFont());
+        if (taLogFont != null) taLog.setFont(taLogFont);
+        taLog.setForeground(new Color(-1));
+        taLog.setMargin(new Insets(4, 4, 4, 4));
+        taLog.setText("[10:50:08.561] [ INFO] ************************************************************************************\n[10:50:08.561] [ INFO] **                   Center Communication Server Information                      **\n[10:50:08.561] [ INFO] **     bindAddress: 0.0.0.0\n[10:50:08.561] [ INFO] **      listenPort: 9901\n[10:50:08.561] [ INFO] **         backlog: 1024\n[10:50:08.561] [ INFO] **   acceptThreads: 16\n[10:50:08.561] [ INFO] **   workerThreads: 16\n[10:50:08.561] [ INFO] ************************************************************************************\n");
+        scrollPane3.setViewportView(taLog);
+        pnlStatusBar = new JPanel();
+        pnlStatusBar.setLayout(new GridLayoutManager(1, 7, new Insets(0, 4, 4, 4), -1, -1));
+        rootPanel.add(pnlStatusBar, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
+        final Spacer spacer2 = new Spacer();
+        pnlStatusBar.add(spacer2, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
+        lblSystime = new JLabel();
+        Font lblSystimeFont = this.$$$getFont$$$("Malgun Gothic", Font.BOLD, 12, lblSystime.getFont());
+        if (lblSystimeFont != null) lblSystime.setFont(lblSystimeFont);
+        lblSystime.setHorizontalAlignment(0);
+        lblSystime.setHorizontalTextPosition(0);
+        lblSystime.setText(" 2022-08-04 13:24:33 ");
+        pnlStatusBar.add(lblSystime, new GridConstraints(0, 6, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+        final JLabel label2 = new JLabel();
+        label2.setIcon(new ImageIcon(getClass().getResource("/static/image/on.png")));
+        label2.setText(" ");
+        pnlStatusBar.add(label2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+        lblCpuRate = new JLabel();
+        Font lblCpuRateFont = this.$$$getFont$$$("Malgun Gothic", Font.BOLD, 12, lblCpuRate.getFont());
+        if (lblCpuRateFont != null) lblCpuRate.setFont(lblCpuRateFont);
+        lblCpuRate.setHorizontalAlignment(2);
+        lblCpuRate.setHorizontalTextPosition(0);
+        lblCpuRate.setText("    ");
+        pnlStatusBar.add(lblCpuRate, new GridConstraints(0, 5, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(40, -1), new Dimension(40, -1), new Dimension(40, -1), 0, false));
+        lblMemoryUsage = new JLabel();
+        Font lblMemoryUsageFont = this.$$$getFont$$$("Malgun Gothic", Font.BOLD, 12, lblMemoryUsage.getFont());
+        if (lblMemoryUsageFont != null) lblMemoryUsage.setFont(lblMemoryUsageFont);
+        lblMemoryUsage.setHorizontalAlignment(2);
+        lblMemoryUsage.setHorizontalTextPosition(0);
+        lblMemoryUsage.setText("    ");
+        pnlStatusBar.add(lblMemoryUsage, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(40, -1), new Dimension(40, -1), new Dimension(40, -1), 0, false));
+        final JLabel label3 = new JLabel();
+        Font label3Font = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, label3.getFont());
+        if (label3Font != null) label3.setFont(label3Font);
+        label3.setHorizontalAlignment(0);
+        label3.setHorizontalTextPosition(0);
+        label3.setText("  CPU 사용율(%):");
+        pnlStatusBar.add(label3, new GridConstraints(0, 4, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+        final JLabel label4 = new JLabel();
+        Font label4Font = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, label4.getFont());
+        if (label4Font != null) label4.setFont(label4Font);
+        label4.setHorizontalAlignment(0);
+        label4.setHorizontalTextPosition(0);
+        label4.setText("  메모리 사용율(%):");
+        pnlStatusBar.add(label4, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+    }
+
+    /**
+     * @noinspection ALL
+     */
+    private Font $$$getFont$$$(String fontName, int style, int size, Font currentFont) {
+        if (currentFont == null) return null;
+        String resultName;
+        if (fontName == null) {
+            resultName = currentFont.getName();
+        } else {
+            Font testFont = new Font(fontName, Font.PLAIN, 10);
+            if (testFont.canDisplay('a') && testFont.canDisplay('1')) {
+                resultName = fontName;
+            } else {
+                resultName = currentFont.getName();
+            }
+        }
+        Font font = new Font(resultName, style >= 0 ? style : currentFont.getStyle(), size >= 0 ? size : currentFont.getSize());
+        boolean isMac = System.getProperty("os.name", "").toLowerCase(Locale.ENGLISH).startsWith("mac");
+        Font fontWithFallback = isMac ? new Font(font.getFamily(), font.getStyle(), font.getSize()) : new StyleContext().getFont(font.getFamily(), font.getStyle(), font.getSize());
+        return fontWithFallback instanceof FontUIResource ? fontWithFallback : new FontUIResource(fontWithFallback);
+    }
+
+    /**
+     * @noinspection ALL
+     */
+    public JComponent $$$getRootComponent$$$() {
+        return rootPanel;
+    }
+
+}

+ 93 - 0
src/main/java/com/its/wthr/ui/MonitoringTask.java

@@ -0,0 +1,93 @@
+package com.its.wthr.ui;
+
+import javax.swing.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class MonitoringTask {
+	
+	private static final int TASK_LENGTH = 1000;
+	private AtomicBoolean isStarted =  new AtomicBoolean(false);
+	private AtomicBoolean isRunning = new AtomicBoolean(false);
+	private AtomicBoolean isDone = new AtomicBoolean(false);
+	private int lengthOfTask;
+	private int current = 0;	
+	private String statMessage;
+
+	public MonitoringTask() {
+		lengthOfTask = TASK_LENGTH;
+	}
+
+	public void go() {
+		isRunning.set(true);
+		if (!isStarted.get()) {
+			isDone.set(false);
+			isStarted.set(true);
+			statMessage = null;
+			current = 0;
+			final SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
+				@Override
+				protected Void doInBackground() throws Exception {
+					// Fake a long task, making a random amount of progress every second.
+					while (!isDone.get()) {
+						if (isRunning.get()) {
+							try {
+								Thread.sleep(1000); // sleep for a second
+								current += Math.random() * 100; // make some progress
+								if (current >= lengthOfTask) {
+									onDown();
+									current = lengthOfTask;
+								}
+								statMessage = "Completed " + current + " out of " + lengthOfTask + ".";
+							} catch (InterruptedException e) {
+								e.printStackTrace();
+							}
+						}
+					}
+					return null;
+				}
+			};
+			worker.execute();
+		}
+	}
+
+	public void pause() {
+		this.isRunning.set(false);
+	}
+
+	/**
+	 * Called from SwingTimerDemo to find out how much work needs to be done.
+	 */
+	public int getLengthOfTask() {
+		return lengthOfTask;
+	}
+
+	/**
+	 * Called from SwingTimerDemo to find out how much has been done.
+	 */
+	public int getCurrent() {
+		return current;
+	}
+
+	public void onDown() {
+		isDone.set(true);
+		isStarted.set(false);
+		isRunning.set(false);
+		statMessage = null;
+	}
+
+	/**
+	 * Called from SwingTimerDemo to find out if the task has completed.
+	 */
+	public boolean isDone() {
+		return isDone.get();
+	}
+
+	/**
+	 * Returns the most recent status message, or null if there is no current
+	 * status message.
+	 */
+	public String getMessage() {
+		return statMessage;
+	}
+
+}

+ 31 - 0
src/main/java/com/its/wthr/ui/SttsTableCellRenderer.java

@@ -0,0 +1,31 @@
+package com.its.wthr.ui;
+
+import javax.swing.*;
+import javax.swing.table.DefaultTableCellRenderer;
+import java.awt.*;
+
+public class SttsTableCellRenderer extends DefaultTableCellRenderer {
+
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+
+        Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+        String commStts = table.getModel().getValueAt(row, 3).toString();
+        if (commStts.equals("성공")) {
+            cell.setBackground(new Color(255, 255, 255, 255));
+            String door = table.getModel().getValueAt(row, 7).toString();
+            String fan = table.getModel().getValueAt(row, 8).toString();
+            String heater = table.getModel().getValueAt(row, 9).toString();
+            String video = table.getModel().getValueAt(row, 11).toString();
+        } else {
+            cell.setBackground(new Color(182, 97, 97, 176));
+        }
+
+        if (column != 2 && column != 5) {
+            setHorizontalAlignment(SwingConstants.CENTER);
+        } else {
+            setHorizontalAlignment(SwingConstants.LEFT);
+        }
+
+        return cell;
+    }
+}

+ 4 - 0
src/main/java/com/its/wthr/vo/AtmpPltnSttsVo.java

@@ -30,4 +30,8 @@ public class AtmpPltnSttsVo {
     private String PM10_1HH_GRAD;
     private String PM25_1HH_GRAD;
     private String UPDT_DT;
+
+    public String getValue() {
+        return "CO_VAL=" + this.getCO_VAL() + ", SO2_VAL=" + this.getSO2_VAL() + ", NO2_VAL=" + this.getNO2_VAL() + ", O3_VAL=" + this.getO3_VAL() + ", PM10_VAL=" + this.getPM10_VAL() + ", PM10_24HH_VAL=" + this.getPM10_24HH_VAL() + ", PM25_VAL=" + this.getPM25_VAL() + ", PM25_24HH_VAL=" + this.getPM25_24HH_VAL() + ", INTG_ATMP_VAL=" + this.getINTG_ATMP_VAL();
+    }
 }

+ 3 - 0
src/main/java/com/its/wthr/vo/AtmpPltnVo.java

@@ -8,6 +8,7 @@ import lombok.ToString;
 @Setter
 @ToString
 public class AtmpPltnVo {
+    private int    index;
     private String ATMP_STTN_NMBR;  //	N	NUMBER(10)	    N			측정소 번호
     private String ATMP_STTN_NM;    //	N	VARCHAR2(30)	N			측정소 명
     private String DEL_YN;
@@ -15,4 +16,6 @@ public class AtmpPltnVo {
     private String requestTime;
     private int    requestResult;
     private String requestValue;
+    private String value;
+
 }

+ 5 - 0
src/main/java/com/its/wthr/vo/FrcsZoneSttsVo.java

@@ -30,4 +30,9 @@ public class FrcsZoneSttsVo {
     private String HMDT;
     private String ESTM_PRCP_AMUT_6HH;
     private String ESTM_SNOW_AMUT_6HH;
+
+    public String getValue() {
+        return "PRST_TMPR=" + this.getPRST_TMPR() + ", HGHS_TMPR=" + this.getHGHS_TMPR() + ", LWST_TMPR=" + this.getLWST_TMPR() + ", ATMP_STTS=" + this.getATMP_STTS() + ", WTCD_KOR_NM=" + this.getWTCD_KOR_NM() + ", PRCP_STTS=" + this.getPRCP_STTS() + ", WTCD_ENGL_NM=" + this.getWTCD_ENGL_NM() + ", PRCP_PR=" + this.getPRCP_PR() + ", HMDT=" + this.getHMDT();
+    }
+
 }

+ 2 - 0
src/main/java/com/its/wthr/vo/FrcsZoneVo.java

@@ -8,6 +8,7 @@ import lombok.ToString;
 @Setter
 @ToString
 public class FrcsZoneVo {
+    private int    index;
     private String VILG_FRCS_ZONE_CD;   //	N	NUMBER(14)	    N			동네 예보 구역 코드
     private String VILG_FRCS_ZONE_NM;   //	N	VARCHAR2(40)	Y			동네 예보 구역 명
     private String GRIDX;
@@ -17,5 +18,6 @@ public class FrcsZoneVo {
     private String requestTime;
     private int    requestResult;
     private String requestValue;
+    private String value;
 
 }

BIN
src/main/resources/static/image/application.png


BIN
src/main/resources/static/image/connect.png


BIN
src/main/resources/static/image/controller.png


BIN
src/main/resources/static/image/logging.png


BIN
src/main/resources/static/image/off.png


BIN
src/main/resources/static/image/on.png


BIN
src/main/resources/static/image/select.png