content: package gui.table;
  
  import com.sleepycat.je.DatabaseException;
  import gui.BasicFrame;
  import gui.table.searchable.DecoratorFactory;
  import gui.table.searchable.MatchingTextHighlighter;
  import gui.table.searchable.XMatchingTextHighlighter;
  import gui.util.ProgressBarUtil;
  import lombok.Getter;
  import lombok.Setter;
  import org.jdesktop.swingx.JXCollapsiblePane;
  import org.jdesktop.swingx.JXFindBar;
  import org.jdesktop.swingx.JXTable;
  import org.jdesktop.swingx.action.AbstractActionExt;
  import org.jdesktop.swingx.search.AbstractSearchable;
  import org.jdesktop.swingx.search.SearchFactory;
  import org.jfree.chart.util.GanttParam;
  import org.jfree.chart.util.IDetailPanel;
  import profile.IProfile;
  import store.StoreManager;
  
  import javax.swing.*;
  import javax.swing.border.EmptyBorder;
  import javax.swing.border.EtchedBorder;
  import javax.swing.border.TitledBorder;
  import javax.swing.table.DefaultTableModel;
  import java.awt.*;
  import java.awt.event.ActionEvent;
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.util.concurrent.atomic.AtomicInteger;
  
  public class RawDataTable extends JPanel implements IDetailPanel {
      private BasicFrame jFrame;
      private StoreManager storeManager;
  
      @Getter @Setter private IProfile iProfile;
  
      @Getter @Setter private String waitClassValue = "";
      @Getter @Setter private GanttParam ganttParamIn;
  
      private JPanel mainPanel;
  
      private JToolBar buttonPanel;
      private JPanel rawDataPanel;
      private JButton loadData;
  
      private JXTable table;
      private JXFindBar findBar;
  
      private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
  
      public RawDataTable(BasicFrame jFrame, StoreManager storeManager) {
          this.jFrame = jFrame;
          this.storeManager = storeManager;
  
          this.setLayout(new GridLayout(1, 1, 3, 3));
  
          mainPanel = new JPanel();
          mainPanel.setLayout(new BorderLayout());
  
          buttonPanel = new JToolBar("RawPanelButton");
          buttonPanel.setFloatable(false);
          buttonPanel.setBorder(new EtchedBorder());
  
          rawDataPanel = new JPanel();
          rawDataPanel.setLayout(new GridLayout(1, 1, 3, 3));
  
          loadData = new JButton();
          loadData.setText("Get ASH raw data");
          loadData.setPreferredSize(new Dimension(100, 30));
          loadData.setActionCommand("rdata");
  
          loadData.addActionListener(e -> {
              long begin =  (long) ganttParamIn.getBeginTime();
              long end =  (long) ganttParamIn.getEndTime();
              loadRawData(begin, end);
          });
  
          mainPanel.add(buttonPanel, BorderLayout.NORTH);
          mainPanel.add(rawDataPanel, BorderLayout.CENTER);
  
          this.add(this.mainPanel);
      }
  
      public void LoadDataToDetail(GanttParam ganttParamIn) {
          this.ganttParamIn = ganttParamIn;
  
          // Layout of buttons
          buttonPanel.removeAll();
  
          buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
          buttonPanel.add(loadData);
          buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
          buttonPanel.add(new JLabel(dateFormat.format(ganttParamIn.getBeginTime())+
                          " <<" + getPeriod(ganttParamIn.getBeginTime(), ganttParamIn.getEndTime()) + ">> "+
                          dateFormat.format(ganttParamIn.getEndTime())
                  )
          );
  
          rawDataPanel.removeAll();
          jFrame.repaint();
      }
  
      private void loadRawData(long begin, long end) {
          rawDataPanel.removeAll();
  
          JPanel panelLoading = createProgressBar("Loading, please wait...");
          rawDataPanel.add(panelLoading);
  
          Thread t = new Thread() {
              @Override
              public void run() {
                  // delay
                  try {
                      Thread.sleep(5L);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  jFrame.repaint();
  
                  /*----------------------*/
                  try {
                      DefaultTableModel tableModel = new DefaultTableModel(getColumnHeaders(), 0);
  
                      /********************************************/
                      loadDataToTableModel(tableModel, begin, end, iProfile.getWaitClassColName(), waitClassValue);
                      /********************************************/
  
                      table = new JXTable(tableModel);
  
                      final JXCollapsiblePane collapsible = connectCollapsibleFindBarWithTable();
  
                      table.setColumnControlVisible(true);
                      table.setHorizontalScrollEnabled(true);
                      table.packAll();
  
                      MatchingTextHighlighter matchingTextMarker = new XMatchingTextHighlighter();
                      matchingTextMarker.setPainter(DecoratorFactory.createPlainPainter());
                      ((AbstractSearchable) table.getSearchable()).setMatchHighlighter(matchingTextMarker);
  
                      JPanel p = new JPanel(new BorderLayout());
  
                      JScrollPane tableRawDataPane = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                              ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
                      tableRawDataPane.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
  
                      tableRawDataPane.setViewportView(table);
                      tableRawDataPane.setVerticalScrollBar(tableRawDataPane.getVerticalScrollBar());
  
                      p.add(collapsible, BorderLayout.NORTH);
                      p.add(tableRawDataPane);
                      p.setBorder(BorderFactory.createCompoundBorder(new TitledBorder(
                              "Selected Items: "), new EmptyBorder(4, 4, 4, 4)));
  
                      /*----------------------*/
                      rawDataPanel.removeAll();
                      rawDataPanel.add(p);
  
                      jFrame.repaint();
  
                  } catch (DatabaseException e) {
                      e.printStackTrace();
                  }
              }
          };
          t.start();
      }
  
      private JXCollapsiblePane connectCollapsibleFindBarWithTable() {
          final JXCollapsiblePane collapsible = new JXCollapsiblePane();
          findBar = SearchFactory.getInstance().createFindBar();
          table.putClientProperty(AbstractSearchable.MATCH_HIGHLIGHTER,Boolean.TRUE);
          findBar.setSearchable(table.getSearchable());
          collapsible.add(findBar);
          collapsible.setCollapsed(false);
  
          Action openFindBar = new AbstractActionExt() {public void actionPerformed(ActionEvent e) { collapsible.setCollapsed(false);KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(findBar); }};
          Action closeFindBar = new AbstractActionExt() {public void actionPerformed(ActionEvent e) { collapsible.setCollapsed(true);table.requestFocusInWindow(); }};
  
          table.getActionMap().put("find", openFindBar);
          findBar.getActionMap().put("close", closeFindBar);
  
          return collapsible;
      }
  
      private String getPeriod(double begin, double end){
          return "";
      }
  
      private JPanel createProgressBar(String msg) {
          JProgressBar progress = ProgressBarUtil.createJProgressBar(msg);
          progress.setPreferredSize(new Dimension(250, 30));
          JPanel panel = new JPanel();
          panel.add(progress);
          return panel;
      }
  
  
      private String[] getColumnHeaders(){
          String moduleName = "ash" + "_" + iProfile.getProfileName();
  
          AtomicInteger at = new AtomicInteger(0);
          String[] out = new String[this.storeManager.getConfigurationManager().getCurrentConfiguration().getSqlColProfileList().size()];
  
          this.storeManager.getConfigurationManager()
                  .getCurrentConfiguration()
                  .getSqlColProfileList()
                  .stream()
                  .sorted((o1, o2) -> o1.getColId() - o2.getColId())
                  .forEach(e->out[at.getAndIncrement()]= e.getColName());
  
          return out;
      }
  
      private void loadDataToTableModel(DefaultTableModel tableModel, long begin, long end,
                                        String waitClassColName, String waitClassValue){
          String moduleName = "ash" + "_" + iProfile.getProfileName();
  
          this.storeManager.getDatabaseDAO()
                  .getMatrixDataForJTable(begin, end, waitClassColName, waitClassValue,
                          this.storeManager.getConfigurationManager().getCurrentConfiguration().getSqlColProfileList())
                  .forEach(e -> {
                      for(int row = 0; row < e.length; row++){
                          if (e[row][0] != null) {
                              tableModel.addRow(e[row]);
                          }
                      }
                  });
      }
  }
  