/* * This file is part of ReqTracker. * * Copyright (C) 2015 Taleh Didover, Florian Gerdes, Dmitry Gorelenkov, * Rajab Hassan Kaoneka, Katsiaryna Krauchanka, Tobias Polzer, * Gayathery Sathya, Lukas Tajak * * ReqTracker is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ReqTracker 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with ReqTracker. If not, see <http://www.gnu.org/licenses/>. */ package de.fau.osr.gui.View; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Image; import java.awt.event.ActionEvent; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import javax.swing.AbstractAction; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.WindowConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.jdesktop.swingx.JXMultiSplitPane; import org.jdesktop.swingx.MultiSplitLayout; import org.jdesktop.swingx.MultiSplitLayout.Split; import org.jdesktop.swingx.MultiSplitLayout.Leaf; import org.jdesktop.swingx.MultiSplitLayout.Divider; import de.fau.osr.gui.Controller.GuiController; import de.fau.osr.gui.View.ElementHandler.Code_ElementHandler; import de.fau.osr.gui.View.ElementHandler.Commit_ElementHandler; import de.fau.osr.gui.View.ElementHandler.Configuration_ElementHandler; import de.fau.osr.gui.View.ElementHandler.ElementHandler; import de.fau.osr.gui.View.ElementHandler.Impact_ElementHandler; import de.fau.osr.gui.View.ElementHandler.Linkage_ElementHandler; import de.fau.osr.gui.View.ElementHandler.MenuHandler; import de.fau.osr.gui.View.ElementHandler.PathDE_ElementHandler; import de.fau.osr.gui.View.ElementHandler.Requirement_Detail_ElementHandler; import de.fau.osr.gui.View.ElementHandler.Requirement_ElementHandler; import de.fau.osr.gui.util.filtering.FilterByExactString; public class GuiViewElementHandler extends JFrame { private static final long serialVersionUID = 1L; private GuiController guiController; private MenuHandler Menu_Handler = new MenuHandler(); private Requirement_ElementHandler Requirement_Handler = new Requirement_ElementHandler(); private Commit_ElementHandler Commit_Handler = new Commit_ElementHandler(); private PathDE_ElementHandler PathDE_Handler = new PathDE_ElementHandler(); private Impact_ElementHandler Impact_Handler = new Impact_ElementHandler(); private Code_ElementHandler Code_Handler = new Code_ElementHandler(Impact_Handler.getScrollPane()); private Requirement_ElementHandler Requirement_HandlerRequirementTab = new Requirement_ElementHandler(); private Requirement_Detail_ElementHandler Requirement_Detail_Handler = new Requirement_Detail_ElementHandler(); private Requirement_ElementHandler Requirement_Handler_ManagementTab = new Requirement_ElementHandler(); private Commit_ElementHandler Commit_Handler_ManagementTab = new Commit_ElementHandler(); private Linkage_ElementHandler Linkage_Handler = new Linkage_ElementHandler(); private Configuration_ElementHandler configuration_ElementHandler = new Configuration_ElementHandler(); private TraceabilityMatrixByImpactViewHandlerPanel traceabilityMatrixByImpactViewHandlerPanel = new TraceabilityMatrixByImpactViewHandlerPanel(); private int currentTab = 0, previousTab = 0; private JPanel mainNavigationPanel; private JPanel requirementModificationPanel; private JPanel LinkageManagmentPanel; private JPanel homePanel; private JPanel traceabilityMatrixPanel; private JTabbedPane tabpane; public GuiViewElementHandler(GuiController guiController) { this.guiController = guiController; initializeButtonActions(); setTitle("ReqTracker"); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setExtendedState(JFrame.MAXIMIZED_BOTH); setBackground(Color.WHITE); setJMenuBar(Menu_Handler.getMenuBar()); setIcon(); createTabs(); positionMainPanelElements(); positionRequirementPanelElements(); positionRequirementManagementPanelElements(); positionTraceabilityMatrixPanelElements(); positionHomePanelElements(); pack(); setVisible(true); } public void doInitialization(){ initializeButtonActions(); requirementPanelAction(); requirementManagementAction(); } public Requirement_ElementHandler getRequirement_ElementHandler() { return Requirement_Handler; } public Commit_ElementHandler getCommit_ElementHandler() { return Commit_Handler; } public Impact_ElementHandler getImpact_ElementHandler() { return Impact_Handler; } public Code_ElementHandler getCode_ElementHandler() { return Code_Handler; } public Linkage_ElementHandler getLinkage_ElementHandler() { return Linkage_Handler; } public Requirement_ElementHandler getRequirement_ElementHandlerRequirementTab() { return Requirement_HandlerRequirementTab; } public Requirement_Detail_ElementHandler getRequirement_Detail_ElementHandler() { return Requirement_Detail_Handler; } public Requirement_ElementHandler getRequirement_Handler_ManagementTab() { return Requirement_Handler_ManagementTab; } public Commit_ElementHandler getCommit_Handler_ManagementTab() { return Commit_Handler_ManagementTab; } public PathDE_ElementHandler getPathDE_ElementHandler() { return PathDE_Handler; } public Collection<ElementHandler> getElementHandlers(){ ArrayList<ElementHandler> elementHandlers = new ArrayList<ElementHandler>(); elementHandlers.add(Requirement_Handler); elementHandlers.add(Commit_Handler); elementHandlers.add(PathDE_Handler); elementHandlers.add(Impact_Handler); elementHandlers.add(Code_Handler); elementHandlers.add(Linkage_Handler); return elementHandlers; } private void setIcon(){ java.util.List<Image> icons = new ArrayList<Image>(); icons.add(new ImageIcon(GuiViewElementHandler.class.getResource("/icons/ReqTrackerLogo.png")).getImage()); icons.add(new ImageIcon(GuiViewElementHandler.class.getResource("/icons/ReqTrackerLogoFull.png")).getImage()); setIconImages(icons); } private void createTabs(){ mainNavigationPanel = new JPanel(); mainNavigationPanel.setLayout(new BorderLayout()); requirementModificationPanel = new JPanel(); requirementModificationPanel.setLayout(new BorderLayout()); LinkageManagmentPanel = new JPanel(); LinkageManagmentPanel.setLayout(new BorderLayout()); homePanel = new JPanel(); homePanel.setLayout(new BorderLayout()); traceabilityMatrixPanel = new JPanel(); traceabilityMatrixPanel.setLayout(new BorderLayout()); tabpane = new JTabbedPane (JTabbedPane.TOP,JTabbedPane.SCROLL_TAB_LAYOUT); tabpane.addTab("Home", homePanel); tabpane.addTab("Navigation", mainNavigationPanel); tabpane.addTab("Requirements", requirementModificationPanel); tabpane.addTab("Linkage Management", LinkageManagmentPanel); tabpane.addTab("Traceability Matrix", traceabilityMatrixPanel); this.add(tabpane); } /** * This method creates a pane split into resizeable columns, containing its * arguments. The original column widths are weighted according to the * getWeight functions of each element handler. * @param elemHandlers * @return a freshly created split pane containing the elements */ private JXMultiSplitPane createMultiColums(ElementHandler... elemHandlers) { /* * allocate one column for each real column and each divider * -> elemHandlers.length columns * -> elemHandlers.length - 1 dividers */ MultiSplitLayout.Node[] columns = new MultiSplitLayout.Node[elemHandlers.length*2 - 1]; /* * The sum of the weights in a MultiSplitLayout has to be <= 1.0, * divide each arbitrary weight by the sum of all weights to get there. */ double totalWeight = 0; for(ElementHandler elemHandler : elemHandlers) totalWeight += elemHandler.getWeight(); for(int i=0; i<elemHandlers.length; ++i) { MultiSplitLayout.Leaf leaf = new MultiSplitLayout.Leaf(Integer.toString(i)); columns[2*i] = leaf; leaf.setWeight(elemHandlers[i].getWeight() / totalWeight); } for(int i=0; i<columns.length; ++i) if(columns[i] == null) columns[i] = new MultiSplitLayout.Divider(); MultiSplitLayout.Node layoutRoot = new MultiSplitLayout.RowSplit(columns); MultiSplitLayout layout = new MultiSplitLayout(layoutRoot); layout.setLayoutByWeight(true); JXMultiSplitPane pane = new JXMultiSplitPane(layout); for(int i=0; i<elemHandlers.length; ++i) pane.add(Integer.toString(i), elemHandlers[i].toComponent()); return pane; } private void positionMainPanelElements() { /* *layoutStructure* explained: 2D-Array: 1st dimension ==> Columns, 2nd dimension ==> Rows { {Component01, Component02, ... }, # Column {Component11, Component12, ... }, # Column } ComponentXY: X-->Column-No, Y-->Row-No */ // Based on this layout sturcture GUI will be created by using MultiSplinPane /* Component[][] layoutStructure = { {RequirementID_textField, RequirementID_button, RequirementID_label, RequirementSearch_textField, RequirementID_scrollPane}, // {Commit_textField, Commit_button, Commit_label, Commit_scrollPane}, {Commit_textField, Commit_label, Commit_scrollPane}, // {Linkage_button, Files_button, FilesSort_combobox, Files_label, Files_scrollPane}, {Linkage_button, Files_button, Files_label, Files_scrollPane}, {Requirements2Lines_label, Requirements2Lines_scrollPane}, {Code_label, Code_scrollPane} }; MultiSplitPane pane = new MultiSplitPane(JSplitPane.HORIZONTAL_SPLIT); for ( Component[] i: layoutStructure) { MultiSplitPane column = new MultiSplitPane(JSplitPane.VERTICAL_SPLIT, false); for (Component j: i) column.addComponent(j); pane.addComponent(column); } */ ElementHandler[] elemHandlers = { Requirement_Handler, Commit_Handler, PathDE_Handler, Impact_Handler, Code_Handler, }; JXMultiSplitPane pane = createMultiColums(elemHandlers); //setLayout(new BorderLayout()); mainNavigationPanel.add(pane, BorderLayout.CENTER); /* GroupLayout layout = new GroupLayout(getContentPane()); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); layout.setHorizontalGroup( layout.createParallelGroup() .addGroup(layout.createSequentialGroup() //here follow the columns of the UI .addGroup(Requirement_Handler.toHorizontalGroup(layout)) .addGroup(Commit_Handler.toHorizontalGroup(layout)) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(Linkage_Handler.getButton()) .addGroup(CommitFile_Handler.toHorizontalGroup(layout)) ) .addGroup(Impact_Handler.toHorizontalGroup(layout)) .addGroup(Code_Handler.toHorizontalGroup(layout)) ) ); layout.setVerticalGroup( layout.createParallelGroup() .addGroup(layout.createSequentialGroup() //two rows, one to create linkage, the other one for the rest .addGroup(Linkage_Handler.toHorizontalGroup(layout)) .addGroup(layout.createParallelGroup() .addGroup(Requirement_Handler.toVerticalGroup(layout)) .addGroup(Commit_Handler.toVerticalGroup(layout)) .addGroup(CommitFile_Handler.toVerticalGroup(layout)) .addGroup(Impact_Handler.toVerticalGroup(layout)) .addGroup(Code_Handler.toVerticalGroup(layout)) ) ) ); Requirement_Handler.linkSize(layout); setLayout(layout); */ } private void positionRequirementPanelElements() { Requirement_HandlerRequirementTab = new Requirement_ElementHandler(); Requirement_Detail_Handler = new Requirement_Detail_ElementHandler(); JXMultiSplitPane pane = createMultiColums(Requirement_HandlerRequirementTab, Requirement_Detail_Handler); requirementModificationPanel.add(pane, BorderLayout.CENTER); } private void requirementPanelAction(){ guiController.setRequirementIDFiltering(new FilterByExactString()); Requirement_HandlerRequirementTab.setButtonAction(()->{ guiController.requirementsFromDBForRequirementTab(); }); } private void positionRequirementManagementPanelElements() { JXMultiSplitPane pane = createMultiColums(Requirement_Handler_ManagementTab, Commit_Handler_ManagementTab, Linkage_Handler); LinkageManagmentPanel.add(pane, BorderLayout.CENTER); } private void requirementManagementAction(){ Requirement_Handler_ManagementTab.setButtonAction(()->{ guiController.requirementsFromDBForManagementTab(); }); Commit_Handler_ManagementTab.setButtonAction(()->{ guiController.commitsFromDBForManagementTab(); }); } private void positionHomePanelElements() { configuration_ElementHandler.setController(guiController,tabpane); tabpane.setEnabledAt(1, false); tabpane.setEnabledAt(2, false); tabpane.setEnabledAt(3, false); tabpane.setEnabledAt(4, false); setOnClickAction(); homePanel.add(configuration_ElementHandler, BorderLayout.CENTER); } private void positionTraceabilityMatrixPanelElements() { traceabilityMatrixByImpactViewHandlerPanel.setInternalGenerationVisibility(true); traceabilityMatrixByImpactViewHandlerPanel.setExportEnable(false); traceabilityMatrixPanel.add(traceabilityMatrixByImpactViewHandlerPanel, BorderLayout.CENTER); } public void setOnClickAction(){ tabpane.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { previousTab = currentTab; currentTab = tabpane.getSelectedIndex(); if(tabpane.getTitleAt(currentTab).equals("Navigation") && tabpane.getTitleAt(previousTab).equals("Linkage Management")){ if(Linkage_Handler.isDataLayerChanged()){ guiController.refresh(); Linkage_Handler.setDataLayerChanged(false); } } } }); } void initializeButtonActions() { PathDE_Handler.setButtonAction(()->guiController.filesFromDB()); Requirement_Handler.setButtonAction(()->{ guiController.requirementsFromDB(); }); // Commit_Handler.setButtonAction(()->guiController.commitsFromDB()); Linkage_Handler.setButtonAction(()->guiController.requirementsAndCommitsFromDB()); Menu_Handler.setConfigureAction(() -> { try { guiController.reConfigure(); } catch (IOException e) { e.printStackTrace(); } }); traceabilityMatrixByImpactViewHandlerPanel.setImpactAction(() -> { guiController.showTraceabilityMatrixByImpactInTabbedView(traceabilityMatrixByImpactViewHandlerPanel); PopupManager popUpManager = new PopupManager(); popUpManager.showInformationDialog("Traceability matrix Generation is complete"); }); Menu_Handler.setImpactAction(() -> { guiController.getTraceabilityMatrixByImpact(); }); /*DONOTREMOVE Menu_Handler.setByOtherDataAction(()->{ guiController.getTraceabilityMatrix(); }); */ guiController.setRequirementIDFiltering(new FilterByExactString()); Requirement_Handler.setSearchTextFieldAction((RequirementSearch_textField)->{ guiController.setRequirementIDFiltering(new FilterByExactString(RequirementSearch_textField.getText())); }); for(Requirement_ElementHandler column : new Requirement_ElementHandler[] {Requirement_Handler, Requirement_HandlerRequirementTab, Requirement_Handler_ManagementTab}) { column.setRefreshAction(new AbstractAction("Refresh Linkage") { @Override public void actionPerformed(ActionEvent arg0) { guiController.refresh(); } }); } } }