com.github.rinde.logistics.pdptw.mas.comm.AuctionPanel.java Source code

Java tutorial

Introduction

Here is the source code for com.github.rinde.logistics.pdptw.mas.comm.AuctionPanel.java

Source

/*
 * Copyright (C) 2013-2016 Rinde van Lon, iMinds-DistriNet, KU Leuven
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.rinde.logistics.pdptw.mas.comm;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.annotation.Nullable;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;

import com.github.rinde.logistics.pdptw.mas.comm.AuctionCommModel.AuctionEvent;
import com.github.rinde.logistics.pdptw.mas.comm.AuctionCommModel.EventType;
import com.github.rinde.rinsim.core.model.DependencyProvider;
import com.github.rinde.rinsim.core.model.Model.AbstractModel;
import com.github.rinde.rinsim.core.model.ModelBuilder.AbstractModelBuilder;
import com.github.rinde.rinsim.core.model.pdp.Parcel;
import com.github.rinde.rinsim.event.Event;
import com.github.rinde.rinsim.event.Listener;
import com.github.rinde.rinsim.ui.renderers.PanelRenderer;
import com.google.auto.value.AutoValue;
import com.google.common.base.Optional;

/**
 *
 * @author Rinde van Lon
 */
public class AuctionPanel extends AbstractModel<Parcel> implements PanelRenderer {
    static final String SPACE = " ";
    static final String TIME_SEPARATOR = ":";

    static final int COLUMN_PARCEL_W = 150;
    static final int COLUMN_TIME_W = 60;
    static final int COLUMN_WINNER_W = 200;
    static final int PREFERRED_PANEL_SIZE = 300;
    static final int NUM_GRID_COLUMNS = 4;

    static final PeriodFormatter FORMATTER = new PeriodFormatterBuilder().appendDays().appendSeparator(SPACE)
            .minimumPrintedDigits(2).printZeroAlways().appendHours().appendLiteral(TIME_SEPARATOR).appendMinutes()
            .appendLiteral(TIME_SEPARATOR).appendSeconds().toFormatter();
    final AuctionCommModel<?> model;
    Optional<Tree> tree;

    Map<Parcel, TreeItem> parcelItems;

    Optional<Button> collapseButton;
    Optional<Button> scrollButton;
    Optional<Label> statusLabel;

    AuctionPanel(AuctionCommModel<?> m) {
        model = m;
        tree = Optional.absent();

        parcelItems = new LinkedHashMap<>();

        model.getEventAPI().addListener(new Listener() {
            @Override
            public void handleEvent(final Event e) {
                final AuctionEvent ae = (AuctionEvent) e;

                tree.get().getDisplay().asyncExec(new Runnable() {
                    @Override
                    public void run() {
                        if (!parcelItems.containsKey(ae.getParcel())) {
                            final TreeItem item = new TreeItem(tree.get(), 0);
                            item.setText(ae.getParcel().toString());
                            parcelItems.put(ae.getParcel(), item);
                        }

                        final TreeItem parent = parcelItems.get(ae.getParcel());
                        final boolean finish = e.getEventType() == EventType.FINISH_AUCTION;

                        final TreeItem item = new TreeItem(parent, 0);
                        parent.setExpanded(true);
                        item.setText(new String[] { ae.getEventType().toString(),
                                FORMATTER.print(new Period(0, ae.getTime())),
                                finish ? ae.getWinner().get().toString() + SPACE + ae.getNumBids() : "" });

                        if (collapseButton.get().getSelection()) {
                            parent.setExpanded(!finish);
                        }
                        if (scrollButton.get().getSelection()) {
                            final TreeItem target = parent.getExpanded() ? item : parent;
                            tree.get().showItem(target);
                            tree.get().select(target);
                        }

                        final int reauctions = model.getNumAuctions() - model.getNumParcels();
                        final int perc = (int) ((reauctions - model.getNumUnsuccesfulAuctions()
                                - model.getNumFailedAuctions()) / (double) reauctions * 100d);

                        statusLabel.get()
                                .setText("# parcels: " + model.getNumParcels() + " # ongoing auctions: "
                                        + model.getNumberOfOngoingAuctions() + " reauctions: " + reauctions
                                        + " (success: " + perc + "%)");

                        statusLabel.get().setToolTipText("unsuccessful: " + model.getNumUnsuccesfulAuctions()
                                + " failed: " + model.getNumFailedAuctions());

                        statusLabel.get().pack(true);
                        statusLabel.get().getParent().redraw();
                        statusLabel.get().getParent().layout();
                    }
                });

            }
        }, EventType.values());
    }

    @Override
    public void initializePanel(Composite parent) {
        final GridLayout layout = new GridLayout(4, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        parent.setLayout(layout);

        statusLabel = Optional.of(new Label(parent, SWT.NONE));
        statusLabel.get().setText("# ongoing auctions: 0");

        final GridData statusLabelLayouData = new GridData();
        statusLabelLayouData.horizontalSpan = NUM_GRID_COLUMNS;
        statusLabelLayouData.grabExcessHorizontalSpace = true;
        statusLabel.get().setLayoutData(statusLabelLayouData);

        tree = Optional.of(new Tree(parent, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL));
        tree.get().setHeaderVisible(true);
        tree.get().setLinesVisible(true);

        final GridData treeLayoutData = new GridData();
        treeLayoutData.horizontalSpan = NUM_GRID_COLUMNS;
        treeLayoutData.grabExcessVerticalSpace = true;
        treeLayoutData.grabExcessHorizontalSpace = true;
        treeLayoutData.verticalAlignment = SWT.FILL;
        treeLayoutData.horizontalAlignment = SWT.FILL;
        tree.get().setLayoutData(treeLayoutData);

        final TreeColumn tc = new TreeColumn(tree.get(), 0);
        tc.setText("Parcel");
        tc.setWidth(COLUMN_PARCEL_W);
        final TreeColumn tc4 = new TreeColumn(tree.get(), 0);
        tc4.setText("Time");
        tc4.setWidth(COLUMN_TIME_W);

        final TreeColumn tc3 = new TreeColumn(tree.get(), 0);
        tc3.setText("Winner");
        tc3.setWidth(COLUMN_WINNER_W);

        collapseButton = Optional.of(new Button(parent, SWT.CHECK));
        collapseButton.get().setText("Auto expand/collapse");
        collapseButton.get().setToolTipText("Automatically expands parcels that are being auctioned, collapses "
                + "parcels for which the auction is over.");
        collapseButton.get().setSelection(true);
        scrollButton = Optional.of(new Button(parent, SWT.CHECK));
        scrollButton.get().setText("Auto scroll");
        scrollButton.get()
                .setToolTipText("Automatically scrolls the view such that the newly added event " + "is visible.");
        scrollButton.get().setSelection(true);

        final Button b = new Button(parent, SWT.PUSH);
        b.setText("Expand all");
        b.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(@Nullable SelectionEvent e) {
                final TreeItem[] items = tree.get().getItems();
                for (final TreeItem item : items) {
                    item.setExpanded(true);
                }
            }

            @Override
            public void widgetDefaultSelected(@Nullable SelectionEvent e) {
            }
        });
        final Button c = new Button(parent, SWT.PUSH);
        c.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(@Nullable SelectionEvent e) {
                final TreeItem[] items = tree.get().getItems();
                for (final TreeItem item : items) {
                    item.setExpanded(false);
                }
            }

            @Override
            public void widgetDefaultSelected(@Nullable SelectionEvent e) {
            }
        });
        c.setText("Collapse all");

    }

    @Override
    public int preferredSize() {
        return PREFERRED_PANEL_SIZE;
    }

    @Override
    public int getPreferredPosition() {
        return SWT.LEFT;
    }

    @Override
    public String getName() {
        return "AuctionPanel";
    }

    @Override
    public void render() {

    }

    @Override
    public boolean register(final Parcel element) {
        return true;
    }

    @Override
    public boolean unregister(Parcel element) {
        return false;
    }

    public static Builder builder() {
        return new AutoValue_AuctionPanel_Builder();
    }

    @AutoValue
    public abstract static class Builder extends AbstractModelBuilder<AuctionPanel, Parcel> {

        Builder() {
            setDependencies(AuctionCommModel.class);
        }

        @Override
        public AuctionPanel build(DependencyProvider dependencyProvider) {
            return new AuctionPanel(dependencyProvider.get(AuctionCommModel.class));
        }
    }
}