org.drugis.addis.gui.builder.LyndOBrienView.java Source code

Java tutorial

Introduction

Here is the source code for org.drugis.addis.gui.builder.LyndOBrienView.java

Source

/*
 * 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, Jol Kuiper, Wouter
 * Reckman.
 * Copyright  2013 Gert van Valkenhoef, Jol 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.Point;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DecimalFormat;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;

import org.drugis.addis.entities.Arm;
import org.drugis.addis.entities.Study;
import org.drugis.addis.entities.analysis.MetaBenefitRiskAnalysis;
import org.drugis.addis.entities.analysis.StudyBenefitRiskAnalysis;
import org.drugis.addis.entities.treatment.TreatmentDefinition;
import org.drugis.addis.gui.AddisWindow;
import org.drugis.addis.gui.AuxComponentFactory;
import org.drugis.addis.gui.LyndOBrienChartFactory;
import org.drugis.addis.presentation.AbstractBenefitRiskPresentation;
import org.drugis.addis.presentation.LyndOBrienPresentation;
import org.drugis.addis.presentation.ModifiableHolder;
import org.drugis.common.gui.BuildViewWhenReadyComponent;
import org.drugis.common.gui.ViewBuilder;
import org.drugis.common.gui.task.TaskProgressBar;
import org.drugis.common.threading.TaskListener;
import org.drugis.common.threading.event.TaskEvent;
import org.drugis.common.threading.event.TaskEvent.EventType;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYAnnotation;
import org.jfree.chart.annotations.XYLineAnnotation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.Range;
import org.jfree.ui.RectangleEdge;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

public class LyndOBrienView implements ViewBuilder {
    LyndOBrienPresentation<?, ?> d_pm;
    AbstractBenefitRiskPresentation<?, ?> d_BRpm;
    private JPanel d_panel;
    private JLabel d_pvalueLabel;

    public LyndOBrienView(AbstractBenefitRiskPresentation<?, ?> pm, AddisWindow mainWindow) {
        d_pm = pm.getLyndOBrienPresentation();
        d_BRpm = pm;
        d_pvalueLabel = new JLabel();
    }

    public JPanel buildPanel() {
        FormLayout layout = new FormLayout("fill:0:grow",
                "p, 3dlu, p, 3dlu, p, 3dlu, " + "p, 3dlu, p, 3dlu, p, 3dlu, p");
        PanelBuilder builder = new PanelBuilder(layout);
        builder.setDefaultDialogBorder();
        CellConstraints cc = new CellConstraints();

        builder.addSeparator("Benefit-risk plane");
        JScrollPane scatter = new JScrollPane(createWaiter(new ScatterplotBuilder()));
        scatter.setViewportBorder(null);
        builder.add(scatter, cc.xy(1, 3));

        String alternativeName = "";
        String baselineName = "";
        Object baseline = d_BRpm.getBean().getBaseline();
        Object alternative = d_BRpm.getBean().getNonBaselineAlternatives().get(0);
        if (d_BRpm.getBean() instanceof StudyBenefitRiskAnalysis) {
            Study s = ((StudyBenefitRiskAnalysis) d_BRpm.getBean()).getStudy();
            Arm baseArm = (Arm) baseline;
            Arm altArm = (Arm) alternative;
            baselineName = s.getTreatment(baseArm).getLabel();
            alternativeName = s.getTreatment(altArm).getLabel();
        } else if (d_BRpm.getBean() instanceof MetaBenefitRiskAnalysis) {
            baselineName = ((TreatmentDefinition) baseline).getLabel();
            alternativeName = ((TreatmentDefinition) alternative).getLabel();
        }

        builder.add(AuxComponentFactory
                .createTextPane("Results of Monte Carlo simulations based on the difference-distributions of"
                        + " the alternatives and criteria. Results in the NW quadrant indicate that " + baselineName
                        + " is better and" + " results in the SE quadrant indicate that " + alternativeName
                        + " is better."),
                cc.xy(1, 7));
        builder.addSeparator("Benefit-Risk Aceptability curve", cc.xy(1, 9));

        JScrollPane pvalue = new JScrollPane(createWaiter(new PvalueplotBuilder()));
        pvalue.setViewportBorder(null);
        builder.add(pvalue, cc.xy(1, 11));

        builder.add(AuxComponentFactory.createTextPane("Probability for a given acceptability threshold "
                + "\u03BC that " + alternativeName + " is superior to " + baselineName + ". Indicates the"
                + " proportion of datapoints in the Benefit-Risk" + " plane that lie below the line y = \u03BC x"),
                cc.xy(1, 13));

        d_panel = builder.getPanel();

        return d_panel;
    }

    private class ScatterplotBuilder implements ViewBuilder, TaskListener {

        public JComponent buildPanel() {
            FormLayout layout = new FormLayout("pref", "p, 3dlu, p, 3dlu, p");
            PanelBuilder builder = new PanelBuilder(layout);
            CellConstraints cc = new CellConstraints();

            JProgressBar bar = new TaskProgressBar(d_pm.getProgressModel());
            builder.add(bar, cc.xy(1, 1));

            final draggableMuChartPanel component = new draggableMuChartPanel(
                    LyndOBrienChartFactory.buildScatterPlot(d_pm.getModel()));

            d_pm.getModel().getTask().addTaskListener(this);
            component.addListener(new PropertyChangeListener() {
                public void propertyChange(PropertyChangeEvent evt) {
                    Double mu = component.getMu();
                    setMuAndPValueLabel(mu);

                }
            });

            d_pm.getModel().getTask().addTaskListener(component);

            builder.add(component, cc.xy(1, 3));
            setMuAndPValueLabel(1.0);
            builder.add(d_pvalueLabel, cc.xy(1, 5));

            return builder.getPanel();
        }

        public void taskEvent(TaskEvent event) {
            if (event.getType() == EventType.TASK_PROGRESS || event.getType() == EventType.TASK_FINISHED) {
                Double mu = 1.0;
                setMuAndPValueLabel(mu);
            }
        }

        private void setMuAndPValueLabel(Double mu) {
            DecimalFormat df = new DecimalFormat("0.00");
            d_pvalueLabel.setText(
                    "\u03BC = " + df.format(mu) + ", P-value: " + df.format(d_pm.getModel().getPValue(mu)));
        }
    }

    private class PvalueplotBuilder implements ViewBuilder {
        public JComponent buildPanel() {
            return new ChartPanel(LyndOBrienChartFactory.buildRiskAcceptabilityCurve(d_pm.getModel()));
        }

    }

    @SuppressWarnings("serial")
    private class draggableMuChartPanel extends ChartPanel implements TaskListener {

        private XYAnnotation d_prevAnnotation = null;
        private ModifiableHolder<Double> d_mu;

        public draggableMuChartPanel(JFreeChart chart) {
            super(chart);
            d_mu = new ModifiableHolder<Double>(1.0);
            drawMuLine(chart.getXYPlot(), d_mu.getValue());
        }

        public void addListener(PropertyChangeListener l) {
            d_mu.addValueChangeListener(l);
        }

        Double getMu() {
            return d_mu.getValue();
        }

        private Point2D.Double convertToChartCoordinates(Point point) {
            ChartRenderingInfo info = getChartRenderingInfo();
            Rectangle2D dataArea = info.getPlotInfo().getDataArea();
            Point2D p = translateScreenToJava2D(new Point(point.x, point.y));
            XYPlot plot = getChart().getXYPlot();
            RectangleEdge domainAxisEdge = plot.getDomainAxisEdge();
            RectangleEdge rangeAxisEdge = plot.getRangeAxisEdge();
            ValueAxis domainAxis = plot.getDomainAxis();
            ValueAxis rangeAxis = plot.getRangeAxis();
            return new Point2D.Double(domainAxis.java2DToValue(p.getX(), dataArea, domainAxisEdge),
                    rangeAxis.java2DToValue(p.getY(), dataArea, rangeAxisEdge));
        }

        public void mouseDragged(MouseEvent e) {
            Point point = e.getPoint();
            Point2D.Double chartXY = convertToChartCoordinates(point);

            // if the mouse is in the SW or NE quadrant, change mu so that it is drawn through the mouse position
            if ((chartXY.x > 0 && chartXY.y > 0) || (chartXY.x < 0 && chartXY.y < 0)) {
                double mu = chartXY.y / chartXY.x;
                drawMuLine(getChart().getXYPlot(), mu);
            }
        }

        private void drawMuLine(XYPlot plot, double mu) {
            Point2D.Double start;
            Point2D.Double end;
            d_mu.setValue(mu);
            Range d = plot.getDomainAxis().getRange();
            Range r = plot.getRangeAxis().getRange();
            double lowerX = d.getLowerBound();
            double upperX = d.getUpperBound();
            double lowerY = r.getLowerBound();
            double upperY = r.getUpperBound();

            end = new Point2D.Double(Math.min(upperY / mu, upperX), Math.min(mu * upperX, upperY));
            start = new Point2D.Double(Math.max(lowerY / mu, lowerX), Math.max(mu * lowerX, lowerY));

            if (d_prevAnnotation != null) {
                plot.removeAnnotation(d_prevAnnotation);
            }
            d_prevAnnotation = new XYLineAnnotation(start.x, start.y, end.x, end.y);
            plot.addAnnotation(d_prevAnnotation);
        }

        public void taskEvent(TaskEvent event) {
            if (event.getType() == EventType.TASK_PROGRESS) {
                drawMuLine(getChart().getXYPlot(), d_mu.getValue());
            }

        }
    };

    protected BuildViewWhenReadyComponent createWaiter(ViewBuilder builder) {
        return new BuildViewWhenReadyComponent(builder, d_BRpm.getMeasurementsReadyModel(),
                SMAAView.WAITING_MESSAGE);
    }

}