Feature/hourlyforecast #4
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
#VisualForecast 1000 Properties file. Functional provider must be set for successful boot!
|
||||
#Thu Mar 07 16:27:03 PST 2024
|
||||
#Fri Mar 08 16:38:56 PST 2024
|
||||
towns-by-code=
|
||||
towns-by-name-and-province=Vancouver,BC;Kamloops,BC;Kelowna,BC
|
||||
towns-by-name-and-province=Duncan,BC;Halifax,NS;Courtenay,BC;Comox,BC
|
||||
|
||||
Binary file not shown.
@@ -29,6 +29,7 @@ import com.flaremicro.visualforecast.api.ForecastProvider;
|
||||
import com.flaremicro.visualforecast.displays.BootupDisplay;
|
||||
import com.flaremicro.visualforecast.displays.DayForecastDisplay;
|
||||
import com.flaremicro.visualforecast.displays.Display;
|
||||
import com.flaremicro.visualforecast.displays.HourlyForecastDisplay;
|
||||
import com.flaremicro.visualforecast.forecast.ForecastDetails;
|
||||
import com.flaremicro.visualforecast.graphics.DrawingUtil;
|
||||
import com.flaremicro.visualforecast.graphics.FontManager;
|
||||
@@ -54,6 +55,8 @@ public class RenderPanel extends JPanel implements Tickable, ComponentListener {
|
||||
private Rectangle exclusiveRedrawBound = null;
|
||||
private Rectangle crawlBound = null;
|
||||
|
||||
private Rectangle currentBound = new Rectangle(0, 0, 0, 0);
|
||||
|
||||
private String currentTown = "";
|
||||
private String currentForecast = "";
|
||||
|
||||
@@ -109,28 +112,6 @@ public class RenderPanel extends JPanel implements Tickable, ComponentListener {
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
Graphics2D g2d = prepareFrameBuffer();
|
||||
|
||||
|
||||
if(g.getClipBounds().equals(this.crawlBound))
|
||||
{
|
||||
g2d.setColor(BG_BLUE);
|
||||
g2d.fillRect(0, H - INFOBAR_HEIGHT, W, INFOBAR_HEIGHT);
|
||||
|
||||
g2d.setColor(Color.DARK_GRAY);
|
||||
g2d.drawLine(0, H - INFOBAR_HEIGHT + STROKE_OFFSET, W, H - INFOBAR_HEIGHT + STROKE_OFFSET);
|
||||
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.drawLine(0, H - INFOBAR_HEIGHT + STROKE_WIDTH + STROKE_OFFSET, W, H - INFOBAR_HEIGHT + STROKE_WIDTH + STROKE_OFFSET);
|
||||
if (this.currentCrawlString != null)
|
||||
{
|
||||
g2d.setFont(font.deriveFont(26F));
|
||||
DrawingUtil.drawOutlinedString(g2d, this.crawlPosition, H - INFOBAR_HEIGHT + 30, this.currentCrawlString, Color.WHITE, Color.BLACK, 2);
|
||||
}
|
||||
g2d.dispose();
|
||||
g.drawImage(frameBuffer, 0, 0, getWidth(), getHeight(), this);
|
||||
return;
|
||||
}
|
||||
|
||||
drawMainRegion(g2d);
|
||||
|
||||
if (currentFlavour != null)
|
||||
@@ -152,7 +133,7 @@ public class RenderPanel extends JPanel implements Tickable, ComponentListener {
|
||||
g2d.setColor(BG_PURPLE);
|
||||
g2d.fillRect(0, 0, W, TOPBAR_HEIGHT);
|
||||
|
||||
g2d.setPaint(new GradientPaint(0, HEADERBAR_Y, BG_OORANGE, 0, HEADERBAR_Y + (HEADERBAR_HEIGHT + 10), BG_PURPLE));
|
||||
g2d.setPaint(new GradientPaint(0, HEADERBAR_Y, BG_ORANGE, 0, HEADERBAR_Y + (HEADERBAR_HEIGHT + 10), BG_PURPLE));
|
||||
g2d.shear(HEADERBAR_SHEAR, 0);
|
||||
g2d.fillRect(-HEADERBAR_OFFSET, HEADERBAR_Y, HEADERBAR_WIDTH, HEADERBAR_HEIGHT);
|
||||
|
||||
@@ -160,7 +141,7 @@ public class RenderPanel extends JPanel implements Tickable, ComponentListener {
|
||||
g2d.fillRect(W - TIMEBAR_WIDTH + TIMEBAR_OFFSET, TIMEBAR_Y, TIMEBAR_WIDTH, TIMEBAR_HEIGHT);
|
||||
g2d.shear(-HEADERBAR_SHEAR, 0);
|
||||
|
||||
g2d.setPaint(new GradientPaint(0, TOPBAR_HEIGHT, BG_PURPLE, 0, MAINBAR_HEIGHT, BG_OORANGE));
|
||||
g2d.setPaint(new GradientPaint(0, TOPBAR_HEIGHT, BG_PURPLE, 0, MAINBAR_HEIGHT, BG_ORANGE));
|
||||
g2d.fillRect(0, TOPBAR_HEIGHT, W, MAINBAR_HEIGHT);
|
||||
|
||||
g2d.fillRect(0, TOPBAR_HEIGHT, W, MAINBAR_HEIGHT);
|
||||
@@ -202,7 +183,7 @@ public class RenderPanel extends JPanel implements Tickable, ComponentListener {
|
||||
//Clock and icon animations, should use repaint regions later
|
||||
if (getWidth() > 0 && getHeight() > 0)
|
||||
{
|
||||
repaint(this.redrawBound);
|
||||
requestRepaint(this.redrawBound);
|
||||
}
|
||||
}
|
||||
if (this.currentFlavour != null)
|
||||
@@ -218,10 +199,37 @@ public class RenderPanel extends JPanel implements Tickable, ComponentListener {
|
||||
this.currentCrawlStringWidth = g.getFontMetrics(font.deriveFont(26F)).stringWidth(currentCrawlString);
|
||||
g.dispose();
|
||||
}
|
||||
else if (this.currentCrawlString != null)
|
||||
}
|
||||
|
||||
public void requestFullRepaint() {
|
||||
currentBound = this.getBounds();
|
||||
}
|
||||
|
||||
|
||||
public void requestRepaint(Rectangle bound) {
|
||||
if(currentBound.width == 0)
|
||||
currentBound = new Rectangle(bound);
|
||||
else currentBound.add(bound);
|
||||
}
|
||||
|
||||
public void requestBoundedRepaint() {
|
||||
requestRepaint(this.redrawBound);
|
||||
}
|
||||
|
||||
public void requestExclusiveBoundedRepaint() {
|
||||
requestRepaint(exclusiveRedrawBound);
|
||||
}
|
||||
|
||||
public void performPaintIfNeeded() {
|
||||
if (this.currentCrawlString != null)
|
||||
{
|
||||
this.crawlPosition-=2;
|
||||
repaint(0, this.crawlBound.x, this.crawlBound.y, this.crawlBound.width, this.crawlBound.height);
|
||||
this.crawlPosition -= 2;
|
||||
requestRepaint(crawlBound);
|
||||
}
|
||||
if(this.currentBound.width != 0)
|
||||
{
|
||||
repaint(currentBound);
|
||||
currentBound.width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +301,7 @@ public class RenderPanel extends JPanel implements Tickable, ComponentListener {
|
||||
}
|
||||
|
||||
public void nextDisplay() {
|
||||
this.currentFlavour = new DayForecastDisplay();
|
||||
this.currentFlavour = new HourlyForecastDisplay();
|
||||
this.currentFlavour.initDisplay(this, forecastProvider, ticks, iconAnimationTicks);
|
||||
this.loseRedrawRegion();
|
||||
this.requestFullRepaint();
|
||||
@@ -307,18 +315,6 @@ public class RenderPanel extends JPanel implements Tickable, ComponentListener {
|
||||
this.currentForecast = currentForecast;
|
||||
}
|
||||
|
||||
public void requestFullRepaint() {
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void requestBoundedRepaint() {
|
||||
repaint(redrawBound);
|
||||
}
|
||||
|
||||
public void requestExclusiveBoundedRepaint() {
|
||||
repaint(exclusiveRedrawBound);
|
||||
}
|
||||
|
||||
private void loadCrawlStrings() {
|
||||
File crawl = new File("./crawl.txt");
|
||||
ArrayList<String> strings = new ArrayList<String>();
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.flaremicro.visualforecast;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.WindowEvent;
|
||||
@@ -9,6 +11,7 @@ import java.awt.event.WindowListener;
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import com.flaremicro.visualforecast.api.ForecastProvider;
|
||||
import com.flaremicro.visualforecast.api.ForecastProviderManager;
|
||||
@@ -23,6 +26,8 @@ public class VisualForecastFrame extends JFrame implements WindowListener, KeyLi
|
||||
private ForecastProviderManager forecastProviderManager;
|
||||
private Executor executor;
|
||||
private PropertyManager propertyManager = new PropertyManager();
|
||||
private Timer timer;
|
||||
private Timer timer2;
|
||||
private boolean isFullscreen = false;
|
||||
|
||||
/**
|
||||
@@ -37,7 +42,7 @@ public class VisualForecastFrame extends JFrame implements WindowListener, KeyLi
|
||||
frame.setVisible(true);
|
||||
frame.init();
|
||||
//GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[1].setFullScreenWindow(frame);
|
||||
frame.createBufferStrategy(2);
|
||||
//frame.createBufferStrategy(2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -50,6 +55,10 @@ public class VisualForecastFrame extends JFrame implements WindowListener, KeyLi
|
||||
public void end() {
|
||||
if (executor != null)
|
||||
executor.end();
|
||||
if (timer != null)
|
||||
{
|
||||
timer.stop();
|
||||
}
|
||||
if (forecastProviderManager != null)
|
||||
forecastProviderManager.end();
|
||||
propertyManager.store();
|
||||
@@ -58,6 +67,14 @@ public class VisualForecastFrame extends JFrame implements WindowListener, KeyLi
|
||||
public void init() {
|
||||
executor = new Executor(this.renderPane, 30);
|
||||
executor.begin();
|
||||
timer = new Timer(33, new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
renderPane.performPaintIfNeeded();
|
||||
}
|
||||
});
|
||||
timer.start();
|
||||
|
||||
|
||||
new Thread() {
|
||||
public void run() {
|
||||
@@ -67,6 +84,7 @@ public class VisualForecastFrame extends JFrame implements WindowListener, KeyLi
|
||||
propertyManager.store();
|
||||
ForecastProvider provider = forecastProviderManager.loadProvider(new File(forecastProvider));
|
||||
renderPane.setForecastProvider(provider);
|
||||
|
||||
}
|
||||
}.start();
|
||||
|
||||
@@ -79,9 +97,9 @@ public class VisualForecastFrame extends JFrame implements WindowListener, KeyLi
|
||||
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
setBounds(100, 100, 640 * 2, 480 * 2);
|
||||
renderPane = new RenderPanel(propertyManager);
|
||||
renderPane.setBorder(null);
|
||||
renderPane.setLayout(new BorderLayout(0, 0));
|
||||
setContentPane(renderPane);
|
||||
//renderPane.setBorder(null);
|
||||
//renderPane.setLayout(new BorderLayout(0, 0));
|
||||
add(renderPane);
|
||||
setUndecorated(true);
|
||||
addWindowListener(this);
|
||||
addKeyListener(this);
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
package com.flaremicro.visualforecast.displays;
|
||||
|
||||
import static com.flaremicro.visualforecast.graphics.RenderConstants.BG_BLUE;
|
||||
import static com.flaremicro.visualforecast.graphics.RenderConstants.MAINBAR_HEIGHT;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.flaremicro.visualforecast.RenderPanel;
|
||||
import com.flaremicro.visualforecast.api.ForecastProvider;
|
||||
import com.flaremicro.visualforecast.forecast.DayForecast;
|
||||
import com.flaremicro.visualforecast.forecast.ForecastDetails;
|
||||
import com.flaremicro.visualforecast.forecast.HourlyForecast;
|
||||
import com.flaremicro.visualforecast.forecast.TownForecast;
|
||||
import com.flaremicro.visualforecast.forecast.ValueCheck;
|
||||
import com.flaremicro.visualforecast.graphics.DrawingUtil;
|
||||
import com.flaremicro.visualforecast.graphics.FontManager;
|
||||
import com.flaremicro.visualforecast.graphics.RenderConstants;
|
||||
import com.flaremicro.visualforecast.icons.IconProvider;
|
||||
|
||||
public class HourlyForecastDisplay implements Display {
|
||||
private int dayOffset = 0;
|
||||
private Font font;
|
||||
private Font smallFont;
|
||||
private ForecastDetails details;
|
||||
private TownForecast currentTown = null;
|
||||
private int townIndex;
|
||||
|
||||
private int ticksBeforeChange = 200;
|
||||
private int animationTicks = -1;
|
||||
|
||||
DateFormat simpleDateFormat = new SimpleDateFormat("ha");
|
||||
|
||||
public HourlyForecastDisplay() {
|
||||
font = FontManager.getInstance().getOrCreateFont(Font.TRUETYPE_FONT, this.getClass().getResource("/Star4000.ttf"));
|
||||
smallFont = FontManager.getInstance().getOrCreateFont(Font.TRUETYPE_FONT, this.getClass().getResource("/Star4000 Small.ttf"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(RenderPanel renderer, long ticks, int iconTicks) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initDisplay(RenderPanel renderer, ForecastProvider forecastProvider, long ticks, int iconTicks) {
|
||||
this.details = forecastProvider != null ? forecastProvider.getForecast() : null;
|
||||
renderer.setCurrentForecast("12 Hour Forecast");
|
||||
if (details == null || details.getTownForecast() == null || details.getTownForecast().length <= 0)
|
||||
this.details = null;
|
||||
else
|
||||
{
|
||||
townIndex = 0;
|
||||
currentTown = details.getTownForecast()[townIndex];
|
||||
renderer.setCurrentTown(currentTown.getTownName());
|
||||
}
|
||||
redrawRegionlost(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawDisplay(RenderPanel renderer, Graphics2D g2d, long ticks, int iconTicks) {
|
||||
}
|
||||
|
||||
public int minTemp(HourlyForecast[] forecast) {
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (int i = 0; i < forecast.length; i++)
|
||||
{
|
||||
int currMin;
|
||||
if (ValueCheck.valueNoData(forecast[i].dewPoint) && ValueCheck.valueNoData(forecast[i].temp))
|
||||
continue;
|
||||
else if (ValueCheck.valueNoData(forecast[i].dewPoint))
|
||||
currMin = forecast[i].temp;
|
||||
else if (ValueCheck.valueNoData(forecast[i].temp))
|
||||
currMin = forecast[i].dewPoint;
|
||||
else currMin = Math.min(forecast[i].temp, forecast[i].dewPoint);
|
||||
if (currMin < min)
|
||||
min = currMin;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
public int maxTemp(HourlyForecast[] forecast) {
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < forecast.length; i++)
|
||||
{
|
||||
int currMax;
|
||||
if (ValueCheck.valueNoData(forecast[i].dewPoint) && ValueCheck.valueNoData(forecast[i].temp))
|
||||
continue;
|
||||
else if (ValueCheck.valueNoData(forecast[i].dewPoint))
|
||||
currMax = forecast[i].temp;
|
||||
else if (ValueCheck.valueNoData(forecast[i].temp))
|
||||
currMax = forecast[i].dewPoint;
|
||||
else currMax = Math.max(forecast[i].temp, forecast[i].dewPoint);
|
||||
if (currMax > max)
|
||||
max = currMax;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBoundLimitedDisplay(RenderPanel renderer, Graphics2D g2d, Rectangle bounds, long ticks, int iconTicks) {
|
||||
HourlyForecast[] forecast = currentTown.getHourlyForecast();
|
||||
if(forecast == null)
|
||||
return;
|
||||
|
||||
g2d.setColor(RenderConstants.BG_BLUE);
|
||||
//g2d.fillRect(RenderConstants.SIDE_OFFSET, RenderConstants.TOPBAR_HEIGHT + 20, RenderConstants.W - RenderConstants.SIDE_OFFSET * 2, RenderConstants.MAINBAR_HEIGHT - 40);
|
||||
|
||||
DrawingUtil.drawGradientRect(g2d, RenderConstants.SIDE_OFFSET, RenderConstants.TOPBAR_HEIGHT + 20, RenderConstants.W - RenderConstants.SIDE_OFFSET * 2, RenderConstants.MAINBAR_HEIGHT - 40, 15, BG_BLUE.darker(), BG_BLUE.brighter());
|
||||
|
||||
int min = minTemp(forecast);
|
||||
int max = maxTemp(forecast);
|
||||
|
||||
float range = Math.abs(min)+Math.abs(max);
|
||||
|
||||
|
||||
|
||||
g2d.setPaint(new GradientPaint(0, RenderConstants.TOPBAR_HEIGHT + 40, RenderConstants.BG_ORANGE, 0, RenderConstants.MAINBAR_HEIGHT, RenderConstants.BG_PURPLE));
|
||||
g2d.fillRect(RenderConstants.SIDE_OFFSET + 40, RenderConstants.TOPBAR_HEIGHT + 40, RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 60, RenderConstants.MAINBAR_HEIGHT - 124);
|
||||
|
||||
g2d.setColor(Color.BLACK);
|
||||
g2d.drawRect(RenderConstants.SIDE_OFFSET, RenderConstants.TOPBAR_HEIGHT + 20, RenderConstants.W - RenderConstants.SIDE_OFFSET * 2, RenderConstants.MAINBAR_HEIGHT - 40);
|
||||
|
||||
/*float lineHeight = (RenderConstants.MAINBAR_HEIGHT - 104) / 9F;
|
||||
for(int i = 0; i < 10; i++)
|
||||
{
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET + 36, (int)(RenderConstants.TOPBAR_HEIGHT + 40 + lineHeight * i), RenderConstants.W - RenderConstants.SIDE_OFFSET - 36, (int) (RenderConstants.TOPBAR_HEIGHT + 40 + lineHeight * i));
|
||||
}*/
|
||||
g2d.setFont(smallFont.deriveFont(20F));
|
||||
FontMetrics fm = g2d.getFontMetrics();
|
||||
|
||||
DrawingUtil.drawOutlinedString(g2d, 100, RenderConstants.TOPBAR_HEIGHT + 35, "Temperature\u00B0c", Color.RED, Color.BLACK, 2);
|
||||
DrawingUtil.drawOutlinedString(g2d, 260, RenderConstants.TOPBAR_HEIGHT + 35, "Dew point\u00B0c", Color.WHITE, Color.BLACK, 2);
|
||||
DrawingUtil.drawOutlinedString(g2d, 410, RenderConstants.TOPBAR_HEIGHT + 35, "Precipitation%", Color.CYAN, Color.BLACK, 2);
|
||||
|
||||
|
||||
String minText = min + "\u00B0";
|
||||
String maxText = max + "\u00B0";
|
||||
|
||||
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET+40-fm.stringWidth(maxText), RenderConstants.TOPBAR_HEIGHT + 53, maxText, Color.YELLOW, Color.BLACK, 2);
|
||||
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET+40-fm.stringWidth(minText), RenderConstants.TOPBAR_HEIGHT + MAINBAR_HEIGHT - 92, minText, Color.YELLOW, Color.BLACK, 2);
|
||||
|
||||
int slotWidth = (RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 60) / 12;
|
||||
|
||||
int lastDewpoint = 0;
|
||||
int lastTemperature = 0;
|
||||
int lastPercip = 0;
|
||||
|
||||
g2d.setColor(RenderConstants.BG_ORANGE.darker());
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40, (RenderConstants.TOPBAR_HEIGHT + 50), (RenderConstants.W - RenderConstants.SIDE_OFFSET - 20), (RenderConstants.TOPBAR_HEIGHT + 50));
|
||||
|
||||
g2d.setColor(RenderConstants.BG_PURPLE.brighter());
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40, RenderConstants.TOPBAR_HEIGHT + 50 + RenderConstants.MAINBAR_HEIGHT - 144, (RenderConstants.W - RenderConstants.SIDE_OFFSET - 20), RenderConstants.TOPBAR_HEIGHT + 50 + RenderConstants.MAINBAR_HEIGHT - 144);
|
||||
|
||||
//BlackLines
|
||||
g2d.setClip(RenderConstants.SIDE_OFFSET + 40, RenderConstants.TOPBAR_HEIGHT + 40, RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 60, RenderConstants.MAINBAR_HEIGHT - 124);
|
||||
g2d.setStroke(new BasicStroke(2));
|
||||
g2d.setColor(Color.BLACK);
|
||||
for(int i = 0; i < Math.min(12, forecast.length); i++)
|
||||
{
|
||||
int nextDewpoint = (RenderConstants.TOPBAR_HEIGHT + 50) + (RenderConstants.MAINBAR_HEIGHT - 144) - (int)(((max-forecast[i].dewPoint)/range)*(RenderConstants.MAINBAR_HEIGHT - 144));
|
||||
int nextTemperature = (RenderConstants.TOPBAR_HEIGHT + 50) + (RenderConstants.MAINBAR_HEIGHT - 144) - (int)(((max-forecast[i].temp)/range)*(RenderConstants.MAINBAR_HEIGHT - 144));
|
||||
int nextPercip = (RenderConstants.TOPBAR_HEIGHT + 50) + (RenderConstants.MAINBAR_HEIGHT - 144) - (int) ((forecast[i].percip/100F)*(RenderConstants.MAINBAR_HEIGHT - 144));
|
||||
if(i == 0)
|
||||
{
|
||||
lastDewpoint = nextDewpoint;
|
||||
lastTemperature = nextTemperature;
|
||||
lastPercip = nextPercip;
|
||||
}
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i-1))+1, lastDewpoint+2, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*i)+2, nextDewpoint+2);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i-1))+1, lastPercip+2, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*i)+2, nextPercip+2);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i-1))+1, lastTemperature+2, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*i)+2, nextTemperature+2);
|
||||
if(i == Math.min(12, forecast.length)-1)
|
||||
{
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i)), nextDewpoint+2, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i+2)), nextDewpoint+2);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i)), nextPercip+2, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i+2)), nextPercip+2);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i)), nextTemperature+2, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i+2)), nextTemperature+2);
|
||||
}
|
||||
lastPercip = nextPercip;
|
||||
lastTemperature = nextTemperature;
|
||||
lastDewpoint = nextDewpoint;
|
||||
}
|
||||
g2d.setClip(null);
|
||||
|
||||
for(int i = 0; i < Math.min(12, forecast.length); i++)
|
||||
{
|
||||
g2d.setClip(RenderConstants.SIDE_OFFSET + 40, RenderConstants.TOPBAR_HEIGHT + 40, RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 60, RenderConstants.MAINBAR_HEIGHT - 124);
|
||||
int nextDewpoint = (RenderConstants.TOPBAR_HEIGHT + 50) + (RenderConstants.MAINBAR_HEIGHT - 144) - (int)(((max-forecast[i].dewPoint)/range)*(RenderConstants.MAINBAR_HEIGHT - 144));
|
||||
int nextTemperature = (RenderConstants.TOPBAR_HEIGHT + 50) + (RenderConstants.MAINBAR_HEIGHT - 144) - (int)(((max-forecast[i].temp)/range)*(RenderConstants.MAINBAR_HEIGHT - 144));
|
||||
int nextPercip = (RenderConstants.TOPBAR_HEIGHT + 50) + (RenderConstants.MAINBAR_HEIGHT - 144) - (int) ((forecast[i].percip/100F)*(RenderConstants.MAINBAR_HEIGHT - 144));
|
||||
if(i == 0)
|
||||
{
|
||||
lastDewpoint = nextDewpoint;
|
||||
lastTemperature = nextTemperature;
|
||||
lastPercip = nextPercip;
|
||||
}
|
||||
g2d.setStroke(new BasicStroke(2));
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i-1)), lastDewpoint, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*i), nextDewpoint);
|
||||
g2d.setColor(Color.CYAN);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i-1)), lastPercip, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*i), nextPercip);
|
||||
g2d.setColor(Color.RED);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i-1)), lastTemperature, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*i), nextTemperature);
|
||||
if(i == Math.min(12, forecast.length)-1)
|
||||
{
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i)), nextDewpoint, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i+1)), nextDewpoint);
|
||||
g2d.setColor(Color.CYAN);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i)), nextPercip, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i+1)), nextPercip);
|
||||
g2d.setColor(Color.RED);
|
||||
g2d.drawLine(RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i)), nextTemperature, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*(i+1)), nextTemperature);
|
||||
}
|
||||
|
||||
g2d.setClip(null);
|
||||
lastPercip = nextPercip;
|
||||
lastTemperature = nextTemperature;
|
||||
lastDewpoint = nextDewpoint;
|
||||
|
||||
String timeString = simpleDateFormat.format(forecast[i].hour);
|
||||
if((i % 2) == 0)
|
||||
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*i)-fm.stringWidth(timeString)/2, RenderConstants.TOPBAR_HEIGHT + MAINBAR_HEIGHT - 70, timeString, Color.YELLOW, Color.BLACK, 2);
|
||||
else
|
||||
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET+40+slotWidth/2+(slotWidth*i)-fm.stringWidth(timeString)/2, RenderConstants.TOPBAR_HEIGHT + MAINBAR_HEIGHT - 60, timeString, Color.YELLOW, Color.BLACK, 2);
|
||||
|
||||
IconProvider.drawIcon(g2d, IconProvider.INDEXED_ICONS[forecast[i].iconId], RenderConstants.SIDE_OFFSET + 45 + i * slotWidth , RenderConstants.TOPBAR_HEIGHT + MAINBAR_HEIGHT - 55, slotWidth - 10, iconTicks);
|
||||
}
|
||||
g2d.setStroke(new BasicStroke(2));
|
||||
g2d.setColor(Color.BLACK);
|
||||
g2d.drawRect(RenderConstants.SIDE_OFFSET + 40, RenderConstants.TOPBAR_HEIGHT + 40, RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 60, RenderConstants.MAINBAR_HEIGHT - 124);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redrawRegionlost(RenderPanel renderer) {
|
||||
renderer.addRedrawBound(0, RenderConstants.TOPBAR_HEIGHT, RenderConstants.W, RenderConstants.MAINBAR_HEIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyForecastProviderUpdate(RenderPanel renderer, ForecastProvider forecastProvider) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.flaremicro.visualforecast.forecast;
|
||||
|
||||
import com.flaremicro.visualforecast.icons.IconProvider;
|
||||
|
||||
public class DayForecast {
|
||||
public byte hiTemp;
|
||||
public byte loTemp;
|
||||
@@ -11,7 +13,7 @@ public class DayForecast {
|
||||
public DayForecast(byte hiTemp, byte loTemp, byte iconId, String weatherLine1, String weatherLine2, float percipPercent){
|
||||
this.hiTemp = hiTemp;
|
||||
this.loTemp = loTemp;
|
||||
this.iconId = (byte)(iconId & 63);
|
||||
this.iconId = (byte)(iconId % IconProvider.INDEXED_ICONS.length);
|
||||
this.weatherLine1 = weatherLine1;
|
||||
this.weatherLine2 = weatherLine2;
|
||||
this.percipPercent = percipPercent;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.flaremicro.visualforecast.forecast;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.flaremicro.visualforecast.icons.IconProvider;
|
||||
|
||||
public class HourlyForecast {
|
||||
public final Date hour;
|
||||
public final byte iconId;
|
||||
public final byte temp;
|
||||
public final short windSpeed;
|
||||
public final float percip;
|
||||
public final byte dewPoint;
|
||||
|
||||
public HourlyForecast(Date hour, byte iconId, byte temp, short windSpeed, float percip, byte dewPoint)
|
||||
{
|
||||
this.hour = hour;
|
||||
this.iconId = (byte) (iconId % IconProvider.INDEXED_ICONS.length);
|
||||
this.temp = temp;
|
||||
this.windSpeed = windSpeed;
|
||||
this.percip = percip;
|
||||
this.dewPoint = dewPoint;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,22 @@
|
||||
package com.flaremicro.visualforecast.forecast;
|
||||
|
||||
public class TownForecast {
|
||||
public TownForecast(String townName, DayForecast[] dayForecast){
|
||||
public TownForecast(String townName, DayForecast[] dayForecast) {
|
||||
this.townName = townName;
|
||||
this.dayForecast = dayForecast;
|
||||
}
|
||||
|
||||
private final String townName;
|
||||
private final DayForecast[] dayForecast;
|
||||
private HourlyForecast[] hourlyForecast;
|
||||
|
||||
public void setHourlyForecast(HourlyForecast[] forecast) {
|
||||
this.hourlyForecast = forecast;
|
||||
}
|
||||
|
||||
public HourlyForecast[] getHourlyForecast() {
|
||||
return this.hourlyForecast;
|
||||
}
|
||||
|
||||
public DayForecast[] getDayForecast() {
|
||||
return dayForecast;
|
||||
|
||||
@@ -31,6 +31,6 @@ public class RenderConstants {
|
||||
|
||||
|
||||
public static final Color BG_PURPLE = new Color(0x2b29b3);
|
||||
public static final Color BG_OORANGE = new Color(0xff8c00);
|
||||
public static final Color BG_ORANGE = new Color(0xff8c00);
|
||||
public static final Color BG_BLUE = new Color(0x394aa8);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#VisualForecast 1000 Properties file. Functional provider must be set for successful boot!
|
||||
#Thu Mar 07 16:27:03 PST 2024
|
||||
forecast-provider-jar=CanadaDatamartProvider.jar
|
||||
#Fri Mar 08 21:30:25 PST 2024
|
||||
forecast-provider-jar=MockForecastProvider.jar
|
||||
|
||||
Reference in New Issue
Block a user