/* * This file is part of ADDIS (Aggregate Data Drug Information System). * ADDIS is distributed from http://drugis.org/. * Copyright © 2009 Gert van Valkenhoef, Tommi Tervonen. * Copyright © 2010 Gert van Valkenhoef, Tommi Tervonen, Tijs Zwinkels, * Maarten Jacobs, Hanno Koeslag, Florin Schimbinschi, Ahmad Kamal, Daniel * Reid. * Copyright © 2011 Gert van Valkenhoef, Ahmad Kamal, Daniel Reid, Florin * Schimbinschi. * Copyright © 2012 Gert van Valkenhoef, Daniel Reid, Joël Kuiper, Wouter * Reckman. * Copyright © 2013 Gert van Valkenhoef, Joël Kuiper. * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package org.drugis.addis.gui.builder; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.table.DefaultTableCellRenderer; import org.drugis.addis.entities.Entity; import org.drugis.addis.entities.OutcomeMeasure; import org.drugis.addis.entities.Variable; import org.drugis.addis.entities.VariableType; import org.drugis.addis.entities.analysis.BenefitRiskAnalysis; import org.drugis.addis.entities.analysis.BenefitRiskAnalysis.AnalysisType; import org.drugis.addis.entities.analysis.StudyBenefitRiskAnalysis; import org.drugis.addis.entities.relativeeffect.Distribution; import org.drugis.addis.forestplot.ForestPlot; import org.drugis.addis.gui.AddisWindow; import org.drugis.addis.gui.AuxComponentFactory; import org.drugis.addis.gui.ValueTreeGraph; import org.drugis.addis.gui.components.AddisTabbedPane; import org.drugis.addis.gui.components.ListPanel; import org.drugis.addis.gui.renderer.BRATDifferenceRenderer; import org.drugis.addis.gui.renderer.BRATForestCellRenderer; import org.drugis.addis.gui.renderer.DistributionQuantileCellRenderer; import org.drugis.addis.presentation.AbstractBenefitRiskPresentation; import org.drugis.addis.presentation.AbstractBenefitRiskPresentation.DecisionContextField; import org.drugis.addis.presentation.BRATTableModel; import org.drugis.addis.presentation.BRATTableModel.BRATDifference; import org.drugis.addis.presentation.BRATTableModel.BRATForest; import org.drugis.addis.presentation.StudyBenefitRiskPresentation; import org.drugis.common.gui.LayoutUtil; import org.drugis.common.gui.ViewBuilder; import org.drugis.common.gui.table.EnhancedTable; import org.drugis.common.gui.table.TablePanel; import com.jgoodies.forms.builder.ButtonBarBuilder2; import com.jgoodies.forms.builder.PanelBuilder; import com.jgoodies.forms.layout.CellConstraints; import com.jgoodies.forms.layout.FormLayout; public abstract class AbstractBenefitRiskView<Alternative extends Entity, PresentationType extends AbstractBenefitRiskPresentation<Alternative, ?>> implements ViewBuilder { protected PresentationType d_pm; protected AddisWindow d_mainWindow; protected ViewBuilder d_view; public AbstractBenefitRiskView(PresentationType model, AddisWindow main) { d_pm = model; d_mainWindow = main; if (getAnalysis().getAnalysisType() == AnalysisType.SMAA) { d_view = new SMAAView(d_pm, d_mainWindow); } else { d_view = new LyndOBrienView(d_pm, d_mainWindow); } } public JComponent buildPanel() { JTabbedPane tabbedPane = new AddisTabbedPane(); tabbedPane.addTab("Overview", buildOverviewPanel()); tabbedPane.addTab("Measurements", buildMeasurementsPanel()); tabbedPane.addTab("BRAT Framework", buildBratPanel()); tabbedPane.addTab("Analysis", buildAnalysisPanel()); tabbedPane.setOpaque(true); return tabbedPane; } protected JPanel buildBratPanel() { FormLayout layout = new FormLayout("fill:0:grow", "p, 3dlu, p, 3dlu, p"); PanelBuilder builder = new PanelBuilder(layout); builder.setDefaultDialogBorder(); CellConstraints cc = new CellConstraints(); builder.addSeparator("Value Tree", cc.xy(1, 1)); final ValueTreeGraph valueTree = new ValueTreeGraph(d_pm.getBean().getCriteria()); builder.add(valueTree, cc.xy(1, 3)); JButton saveBtn = new JButton("Save Image"); saveBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { valueTree.saveImage(d_mainWindow); } }); ButtonBarBuilder2 bbuilder = new ButtonBarBuilder2(); bbuilder.addButton(saveBtn); builder.add(bbuilder.getPanel(), cc.xy(1, 5)); int row = 5; for (Alternative alternative : getNonBaselineAlternatives()) { row = LayoutUtil.addRow(layout, row); builder.addSeparator("Benefit-Risk summary: " + alternative.getLabel() + " vs " + getBaseline().getLabel(), cc.xy(1, row)); row = LayoutUtil.addRow(layout, row); builder.add(new TablePanel(createSummaryTable(d_pm.createBRATTableModel(alternative))), cc.xy(1, row)); row = LayoutUtil.addRow(layout, row); builder.add(createSummaryLabel(d_pm.createBRATTableModel(alternative)), cc.xy(1, row)); } return builder.getPanel(); } private ArrayList<Alternative> getNonBaselineAlternatives() { ArrayList<Alternative> alternatives = new ArrayList<Alternative>(d_pm.getBean().getAlternatives()); alternatives.remove(getBaseline()); return alternatives; } private Alternative getBaseline() { return d_pm.getBean().getBaseline(); } private JComponent createSummaryLabel(BRATTableModel<Alternative, ? extends BenefitRiskAnalysis<Alternative>> model) { String baselineName = model.getBaseline().getLabel(); String subjectName = model.getSubject().getLabel(); String str = "<p>Key Benefit-Risk Summary table with embedded relative effect forest plot. " + "The color in the \"difference\" column indicates whether the point estimate favors " + baselineName + " (red) or " + subjectName + " (green). " + "The symbol in the forest plot indicates whether the logarithmic (square) or linear (diamond) scale is used.</p>"; return AuxComponentFactory.createTextPane(str); } private JTable createSummaryTable(BRATTableModel<Alternative, ? extends BenefitRiskAnalysis<Alternative>> model) { JTable table = EnhancedTable.createBare(model); table.setDefaultRenderer(Variable.class, new DefaultTableCellRenderer()); table.setDefaultRenderer(VariableType.class, new DefaultTableCellRenderer()); table.setDefaultRenderer(Distribution.class, new DistributionQuantileCellRenderer(true)); table.setDefaultRenderer(BRATDifference.class, new BRATDifferenceRenderer()); table.setDefaultRenderer(BRATForest.class, new BRATForestCellRenderer<PresentationType>()); table.setRowHeight((int) Math.max(ForestPlot.ROWHEIGHT + 2, new JLabel("<html>a<br/>b</html>").getPreferredSize().getHeight())); // Set minimum widths table.getTableHeader().getColumnModel().getColumn(BRATTableModel.COLUMN_FOREST).setMinWidth(ForestPlot.BARWIDTH + BRATForestCellRenderer.PADDING * 2); for (int i = 0; i < table.getColumnCount(); ++i) { if (table.getColumnClass(i) == Distribution.class || table.getColumnClass(i) == BRATDifference.class) { int minWidth = 0; for (int j = 0; j < table.getRowCount(); ++j) { minWidth = Math.max(getColumnMinWidth(table, j, i), minWidth); } table.getTableHeader().getColumnModel().getColumn(i).setMinWidth(minWidth); } } return table; } private int getColumnMinWidth(JTable table, int row, int column) { return table.getCellRenderer(row, column).getTableCellRendererComponent(table, table.getValueAt(row, column), false, false, row, column).getMinimumSize().width; } protected abstract JPanel buildOverviewPanel(); protected JPanel buildOverviewPart() { CellConstraints cc = new CellConstraints(); FormLayout layout = new FormLayout("right:pref, 3dlu, fill:0:grow", "p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p"); PanelBuilder builder = new PanelBuilder(layout); builder.setOpaque(true); builder.addLabel("ID:", cc.xy(1, 1)); JLabel tmp = new JLabel((String) d_pm.getModel(BenefitRiskAnalysis.PROPERTY_NAME).getValue()); builder.add(tmp , cc.xy(3, 1)); builder.addLabel("Analysis type:", cc.xy(1, 3)); builder.add(AuxComponentFactory.createAutoWrapLabel(d_pm.getModel(BenefitRiskAnalysis.PROPERTY_ANALYSIS_TYPE)), cc.xy(3, 3)); builder.addLabel("Indication:", cc.xy(1, 5)); builder.add(AuxComponentFactory.createAutoWrapLabel(d_pm.getModel(BenefitRiskAnalysis.PROPERTY_INDICATION)), cc.xy(3, 5)); int row = 5; if (d_pm instanceof StudyBenefitRiskPresentation) { row += 2; LayoutUtil.addRow(layout); builder.addLabel("Study:", cc.xy(1, row)); builder.add(AuxComponentFactory.createAutoWrapLabel(d_pm.getModel(StudyBenefitRiskAnalysis.PROPERTY_STUDY)), cc.xy(3, row)); } row += 2; builder.addLabel("Criteria:", cc.xy(1, row)); ListPanel criteriaList = new ListPanel(getAnalysis(), BenefitRiskAnalysis.PROPERTY_CRITERIA, OutcomeMeasure.class); builder.add(criteriaList,cc.xy(3, row)); row += 2; builder.addLabel("Alternatives:", cc.xy(1, row)); ListPanel alternativesList = new ListPanel(getAnalysis().getAlternatives()); builder.add(alternativesList,cc.xy(3, row)); row += 2; builder.addLabel("Baseline:", cc.xy(1, row)); JLabel baselineLabel = new JLabel(getBaseline().getLabel()); builder.add(baselineLabel,cc.xy(3, row)); if (d_pm.getBean().getDecisionContext() != null) { row = LayoutUtil.addRow(layout, row); builder.addSeparator("Decision context", cc.xyw(1, row, 3)); for (DecisionContextField field : AbstractBenefitRiskPresentation.createDecisionContextFields(d_pm.getBean().getDecisionContext())) { row = LayoutUtil.addRow(layout, row); builder.addLabel(field.getName() + ": ", cc.xy(1, row)); builder.add(AuxComponentFactory.createAutoWrapLabel(field.getModel()), cc.xy(3, row)); } } return builder.getPanel(); } protected BenefitRiskAnalysis<?> getAnalysis() { return (BenefitRiskAnalysis<?>)d_pm.getBean(); } protected JComponent buildAnalysisPanel() { return d_view.buildPanel(); } protected abstract JPanel buildMeasurementsPanel(); }