/* *------------------- * The GanttDetails.java is part of ASH Viewer *------------------- * * ASH Viewer is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ASH Viewer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ASH Viewer. If not, see <http://www.gnu.org/licenses/>. * * Copyright (c) 2009, Alex Kardapolov, All rights reserved. * */ package org.ash.detail; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.MouseEvent; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.ScrollPaneConstants; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.ash.database.ASHDatabase; import org.ash.gui.GanttSplitPane; import org.ash.gui.SqlPlan; import org.ash.util.Options; import org.ash.util.ProgressBarUtil; import org.ash.util.Utils; import org.syntax.jedit.JEditTextArea; import org.syntax.jedit.tokenmarker.PLSQLTokenMarker; import com.egantt.model.drawing.ContextResources; import com.egantt.model.drawing.DrawingState; import com.egantt.swing.cell.CellState; import com.egantt.swing.component.ComponentResources; import com.egantt.swing.component.context.BasicComponentContext; import com.egantt.swing.component.tooltip.ToolTipState; import com.egantt.swing.table.list.BasicJTableList; import ext.egantt.drawing.painter.context.BasicPainterContext; import ext.egantt.swing.GanttTable; /** * The Class SqlsAndSessionsGantt. */ public class GanttDetails extends JPanel{ /** The main. */ private JPanel main; /** The root. */ private JFrame root; /** The database. */ private ASHDatabase database; /** The TEXT_PAINTER. */ final String TEXT_PAINTER = "MyTextPainter"; /** Gantt graph data for Sqls */ private GanttSqls ganttSqls; /** Gantt graph data for Sessions */ private GanttSessions ganttSessions; /** The waitClass or CPU used */ private String waitClass = "none"; /** SQL text */ private JEditTextArea jtextAreaSqlText = new JEditTextArea(); /** * Constructor Gantt JPanel * * @param rootFrame0 the root frame0 * @param model0 the model0 * @param database0 the database0 */ public GanttDetails(JFrame rootFrame0, ASHDatabase database0, String waitClass0){ super(); setLayout(new GridLayout(1, 1, 3, 3)); this.database = database0; this.root = rootFrame0; this.waitClass = waitClass0; // Initialize sqls and sessions this.ganttSqls = new GanttSqls(database0); this.ganttSessions = new GanttSessions(database0); this.jtextAreaSqlText.setTokenMarker(new PLSQLTokenMarker()); this.jtextAreaSqlText.setEditable(false); this.main = new JPanel(); this.main.setLayout(new GridLayout(1, 1, 3, 3)); this.add(this.main); } /** * Load data to JPanels. * * @param beginTime the begin time * @param endTime the end time */ public synchronized void loadDataToJPanels(final double beginTime, final double endTime){ this.main.removeAll(); this.root.repaint(); JPanel panel = createProgressBar("Loading, please wait..."); this.main.add(panel); Thread t = new Thread() { @Override public void run() { // delay try { Thread.sleep(50L); } catch(InterruptedException e) { e.printStackTrace(); } loadDataToJPanelsPrivate(beginTime, endTime); } }; t.start(); } /** * Get topSqlsSqlText * * @return the topSqlsSqlText */ public int getTopSqlsSqlText() { return ganttSqls.getTopSqlsSqlText(); } /** * Set topSqlsSqlText * * @param topSqlsSqlText the topSqlsSqlText to set */ public void setTopSqlsSqlText(int topSqlsSqlText) { ganttSqls.setTopSqlsSqlText(topSqlsSqlText); } /** * Is select sql plan * * @param isSelect */ public void setSelectSqlPlan(boolean isSelect) { ganttSqls.setSelectSqlPlan(isSelect); } /** * Load data to panels. * * @param beginTime the begin time * @param endTime the end time */ private void loadDataToJPanelsPrivate(double beginTime, double endTime){ JSplitPane splitPane = new GanttSplitPane(JSplitPane.HORIZONTAL_SPLIT); this.database.getSqlsTempDetail().clear(); this.database.getSessionsTempDetail().clear(); this.database.calculateSqlsSessionsData(beginTime, endTime, this.waitClass); List eventListSqls = this.database.getSqlsTempDetail().getEventList(); List eventListSessions = this.database.getSessionsTempDetail().getEventList(); // Load data to JTable model try { String sqlIdHash = ""; if (Options.getInstance().getVersionDb().equalsIgnoreCase("9i")){ sqlIdHash = "Hash Value"; } else { sqlIdHash = "SQL ID"; } String[][] columnNamesSqls = { {"Activity %", sqlIdHash, "SQL Type"}}; String[][] columnNamesSessions = { {"Activity %", "Session ID", "User Name", "Program"}}; /** Array SqlIdText for SQL Text tab*/ Map<Integer,String> arraySqlIdText50SQLTextTab = new HashMap<Integer, String>(); /** Create gantt table */ final GanttTable tableGanttSql = new GanttTable( ganttSqls.getDataToSqlsGantt(arraySqlIdText50SQLTextTab), columnNamesSqls, getBasicJTableList(),eventListSqls); final GanttTable tableGanttSessions = new GanttTable( ganttSessions.getDataToSessionsGantt(), columnNamesSessions, getBasicJTableList(),eventListSessions); /** Set tooltip and percent*/ setTooltipAndPercent(tableGanttSql); setTooltipAndPercent(tableGanttSessions); /** Left tabbed pane (Top SQL + SQL text)*/ JTabbedPane tabsTopSQLText = new JTabbedPane(); SqlPlan sqlPlan = new SqlPlan(root, database); /** Top SQL pane*/ JScrollPane leftPane = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); leftPane.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE); jtextAreaSqlText.setMinimumSize(new Dimension(this.main.getWidth()/2,this.main.getHeight()-50)); jtextAreaSqlText.setPreferredSize(new Dimension(this.main.getWidth()/2,this.main.getHeight()-50)); /** Top sessions pane*/ JScrollPane rightPane = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); rightPane.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE); leftPane.setViewportView(tableGanttSql.getJTable()); rightPane.setViewportView(tableGanttSessions.getJTable()); leftPane.setVerticalScrollBar(leftPane.getVerticalScrollBar()); rightPane.setVerticalScrollBar(rightPane.getVerticalScrollBar()); /** Cell selection enabled for copying values */ tableGanttSql.getJTable().setCellSelectionEnabled(true); tableGanttSessions.getJTable().setCellSelectionEnabled(true); /** Add component to left tabs*/ tabsTopSQLText.add(leftPane,Options.getInstance().getResource("tabTopSQL.text")); tabsTopSQLText.add(jtextAreaSqlText,Options.getInstance().getResource("tabSQLText.text")); tabsTopSQLText.add(sqlPlan, Options.getInstance().getResource("tabSQLPlan.text")); tabsTopSQLText.setEnabledAt(1, false); tabsTopSQLText.setEnabledAt(2, false); /** Add selection listener for table model*/ SelectionListener listener = new SelectionListener(tableGanttSql .getJTable(), tabsTopSQLText, jtextAreaSqlText, arraySqlIdText50SQLTextTab, sqlPlan, database); tableGanttSql.getJTable().getSelectionModel().addListSelectionListener(listener); /** Layout components*/ splitPane.setLeftComponent(tabsTopSQLText); splitPane.setRightComponent(rightPane); splitPane.setDividerLocation(this.getWidth()/2); splitPane.setOneTouchExpandable(true); this.main.removeAll(); this.main.add(splitPane); this.validate(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Selection listener for Top SQL JTable */ private class SelectionListener implements ListSelectionListener { JTable table; JTabbedPane tabbedpane; JEditTextArea sqlTextArea; Map<Integer, String> arraySqlIdText50SQLTextTab; SqlPlan sqlPlan; ASHDatabase database; SelectionListener(JTable table, JTabbedPane tabbedpane, JEditTextArea sqlTextArea, Map<Integer, String> arraySqlIdText50SQLTextTab, SqlPlan sqlPlan, ASHDatabase database) { this.table = table; this.tabbedpane = tabbedpane; this.sqlTextArea = sqlTextArea; this.arraySqlIdText50SQLTextTab = arraySqlIdText50SQLTextTab; this.sqlPlan = sqlPlan; this.database = database; } /* (non-Javadoc) * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent) */ public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) { JPanel panelSqlText = createProgressBar("Loading, please wait..."); JPanel panelSqlPlan = createProgressBar("Loading, please wait..."); tabbedpane.setComponentAt(1, panelSqlText); tabbedpane.setComponentAt(2, panelSqlPlan); tabbedpane.setEnabledAt(1, true); tabbedpane.setEnabledAt(2, true); Thread t = new Thread() { @Override public void run() { // delay try { Thread.sleep(50L); } catch (InterruptedException e) { e.printStackTrace(); } loadSqlTextAndPlan(); } }; t.start(); } } /** * Load sql text and plan to tabs */ private void loadSqlTextAndPlan(){ final String sqlId = arraySqlIdText50SQLTextTab.get(table .getSelectedRow()); final String sqlText = database.getSqlText(sqlId); final String sqlType = database.getSqlType(sqlId); // Load formatted sql text if (sqlText != null && sqlText != "") { tabbedpane.setEnabledAt(1, true); try { sqlTextArea.setText(Utils.formatSqlAll(sqlText) .toString()); sqlTextArea.setCaretPosition(0); sqlTextArea.updateUI(); } catch (Exception e1) { sqlTextArea .setText("Error in syntax highlighting of sql!"); } } else { tabbedpane.setEnabledAt(1, false); sqlTextArea.setText(""); } // Load sql plan's for sql_id if (sqlType.equalsIgnoreCase("SELECT") || sqlType.equalsIgnoreCase("INSERT") || sqlType.equalsIgnoreCase("UPDATE") || sqlType.equalsIgnoreCase("DELETE") || sqlType.equalsIgnoreCase("MERGE") || sqlType.equalsIgnoreCase("UNKNOWN") || (sqlType == "" && sqlType != null)) { tabbedpane.setEnabledAt(2, true); try { sqlPlan.loadSqlPlan(sqlId, true); } catch (Exception e1) { System.out.println("SQL Exception occured: " + e1.getMessage()+e1.getStackTrace()); e1.printStackTrace(); } } else { tabbedpane.setEnabledAt(2, false); } tabbedpane.setComponentAt(1, sqlTextArea); tabbedpane.setComponentAt(2, sqlPlan); } } /** * Get BasicJTableList * * @return BasicJTableList */ private BasicJTableList getBasicJTableList(){ BasicJTableList tableListSqls = new BasicJTableList(); { BasicComponentContext componentContext = new BasicComponentContext(); ToolTipState state = new ToolTipState() { public String getToolTipText(MouseEvent event, CellState cellState) { DrawingState drawing = cellState.getDrawing(); Object key = drawing != null ? drawing.getValueAt(event.getPoint()): null; if (key == null) return ""; return key.toString(); } }; componentContext.put(ComponentResources.TOOLTIP_STATE, state); tableListSqls.setRendererComponentContext(componentContext); } return tableListSqls; } /** * Set tooltip and percent for GanttTable * * @param gantttable */ private void setTooltipAndPercent(GanttTable gantttable){ ///Tooltip { BasicPainterContext graphics = new BasicPainterContext(); graphics.setPaint(Color.WHITE); graphics.put(TEXT_PAINTER, new Font(null, Font.PLAIN, 8)); gantttable.getDrawingContext().put(TEXT_PAINTER, ContextResources.GRAPHICS_CONTEXT, graphics); } // Percent { BasicPainterContext graphics = new BasicPainterContext(); graphics.setPaint(Color.BLACK); graphics.put(TEXT_PAINTER, new Font(null, Font.BOLD, 10)); gantttable.getDrawingContext().put(TEXT_PAINTER, ContextResources.GRAPHICS_CONTEXT, graphics); } } /** * Creates the progress bar. * * @param msg the msg * * @return the jpanel */ 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; } }