/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* 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 org.optaplanner.examples.coachshuttlegathering.swingui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.util.List;
import javax.swing.JPanel;
import org.apache.commons.lang3.StringUtils;
import org.optaplanner.examples.coachshuttlegathering.domain.Bus;
import org.optaplanner.examples.coachshuttlegathering.domain.BusStop;
import org.optaplanner.examples.coachshuttlegathering.domain.Coach;
import org.optaplanner.examples.coachshuttlegathering.domain.CoachShuttleGatheringSolution;
import org.optaplanner.examples.coachshuttlegathering.domain.StopOrHub;
import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation;
import org.optaplanner.examples.common.swingui.latitudelongitude.LatitudeLongitudeTranslator;
import org.optaplanner.swing.impl.TangoColorFactory;
public class CoachShuttleGatheringWorldPanel extends JPanel {
private static final int LOCATION_NAME_TEXT_SIZE = 12;
private final CoachShuttleGatheringPanel coachShuttleGatheringPanel;
private BufferedImage canvas = null;
private LatitudeLongitudeTranslator translator = null;
public CoachShuttleGatheringWorldPanel(CoachShuttleGatheringPanel coachShuttleGatheringPanel) {
this.coachShuttleGatheringPanel = coachShuttleGatheringPanel;
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
// TODO Not thread-safe during solving
CoachShuttleGatheringSolution solution = CoachShuttleGatheringWorldPanel.this.coachShuttleGatheringPanel.getSolution();
if (solution != null) {
resetPanel(solution);
}
}
});
}
public void resetPanel(CoachShuttleGatheringSolution solution) {
translator = new LatitudeLongitudeTranslator();
for (RoadLocation location : solution.getLocationList()) {
translator.addCoordinates(location.getLatitude(), location.getLongitude());
}
Dimension size = getSize();
double width = size.getWidth();
double height = size.getHeight();
translator.prepareFor(width, height);
Graphics2D g = createCanvas(width, height);
g.setColor(TangoColorFactory.ORANGE_3);
RoadLocation hubLocation = solution.getHub().getLocation();
translator.drawSquare(g, hubLocation.getLongitude(), hubLocation.getLatitude(), 5);
for (BusStop stop : solution.getStopList()) {
RoadLocation location = stop.getLocation();
g.setColor((stop.getPassengerQuantity() <= 0) ? TangoColorFactory.ALUMINIUM_4
: (stop.getTransportTimeToHub() == null) ? TangoColorFactory.ORANGE_2
: (stop.getTransportTimeRemainder() < 0) ? TangoColorFactory.SCARLET_2 : TangoColorFactory.ORANGE_2);
translator.drawSquare(g, location.getLongitude(), location.getLatitude(), 3,
stop.getTransportLabel());
}
List<Bus> busList = solution.getBusList();
g.setColor(TangoColorFactory.ALUMINIUM_2);
g.setFont(g.getFont().deriveFont((float) LOCATION_NAME_TEXT_SIZE));
for (Bus bus : busList) {
RoadLocation location = bus.getLocation();
g.setColor(bus instanceof Coach ? TangoColorFactory.ORANGE_1 : TangoColorFactory.ALUMINIUM_2);
translator.drawSquare(g, location.getLongitude(), location.getLatitude(), 3, StringUtils.abbreviate(bus.getName(), 20));
}
int colorIndex = 0;
for (Bus bus : busList) {
g.setColor(TangoColorFactory.SEQUENCE_2[colorIndex]);
BusStop lastStop = null;
for (BusStop stop = bus.getNextStop(); stop != null; stop = stop.getNextStop()) {
RoadLocation previousLocation = stop.getPreviousBusOrStop().getLocation();
RoadLocation location = stop.getLocation();
translator.drawRoute(g, previousLocation.getLongitude(), previousLocation.getLatitude(),
location.getLongitude(), location.getLatitude(),
false, false);
lastStop = stop;
}
if (lastStop != null || bus instanceof Coach) {
RoadLocation lastStopLocation = lastStop == null ? bus.getLocation() : lastStop.getLocation();
StopOrHub destination = bus.getDestination();
if (destination != null) {
RoadLocation destinationLocation = destination.getLocation();
translator.drawRoute(g, lastStopLocation.getLongitude(), lastStopLocation.getLatitude(),
destinationLocation.getLongitude(), destinationLocation.getLatitude(),
false, true);
}
}
colorIndex = (colorIndex + 1) % TangoColorFactory.SEQUENCE_2.length;
}
repaint();
}
public void updatePanel(CoachShuttleGatheringSolution solution) {
resetPanel(solution);
}
private Graphics2D createCanvas(double width, double height) {
int canvasWidth = (int) Math.ceil(width) + 1;
int canvasHeight = (int) Math.ceil(height) + 1;
canvas = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = canvas.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, canvasWidth, canvasHeight);
return g;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (canvas != null) {
g.drawImage(canvas, 0, 0, this);
}
}
}