diff --git a/.DS_Store b/.DS_Store index cda8047c93a7c84cc01fb857eadf0551f6389735..a7cc044258099c475a7c644624015d3e6d174cfb 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/WatcherGui/pom.xml b/WatcherGui/pom.xml index dff5ea69ae8068fb4b1ed09339e4208f98de178d..d6d3fc7c0101578561903fd0475e82dc967491bb 100644 --- a/WatcherGui/pom.xml +++ b/WatcherGui/pom.xml @@ -17,5 +17,10 @@ <artifactId>json</artifactId> <version>20210307</version> </dependency> + <dependency> + <groupId>jfree</groupId> + <artifactId>jfreechart</artifactId> + <version>1.0.13</version> +</dependency> </dependencies> </project> \ No newline at end of file diff --git a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/LoginPage.java b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/LoginPage.java index 6f2f9008052facae370bd48b2c71902309042cbe..168b7fdf46a347c22bb65f2e39b95c372643b679 100644 --- a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/LoginPage.java +++ b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/LoginPage.java @@ -19,13 +19,17 @@ public class LoginPage implements ActionListener{ private JButton loginButton; private JButton newButton; private JTextField userIDField; + private JLabel titleLabel; private JLabel messageLabel; private JLabel retryLabel; private JPasswordField passwordField; + private JPanel bottomPanel; + private JLabel imageLabel; + private ImageIcon lightImageOff = new ImageIcon("src/main/resources/images/lightbulb_off.png"); + private ImageIcon lightImageOn = new ImageIcon("src/main/resources/images/lightbulb_on.png"); private final int width = 800, height = 420; private final int[] retry_intervals = {5, 15, 30, 60, 180}; - private final Color loginPanelColor = new Color(30, 99, 204); private int retry_count = 0; // Constructor @@ -36,10 +40,12 @@ public class LoginPage implements ActionListener{ newButton = new JButton("Sign Up"); newButton.setBackground(Color.GREEN); userIDField = new JTextField(); + titleLabel = new JLabel("Sign In"); messageLabel = new JLabel(); retryLabel = new JLabel(); + bottomPanel = new JPanel(); + imageLabel = new JLabel(); - JPanel bottomPanel = new JPanel(); JPanel topPanel = new JPanel(); JLabel emailLabel = new JLabel("Email"); JLabel userPasswordLabel = new JLabel("Password"); @@ -48,11 +54,17 @@ public class LoginPage implements ActionListener{ emailLabel.setForeground(Color.white); userPasswordLabel.setBounds(50,137,75,25); userPasswordLabel.setForeground(Color.white); - messageLabel.setBounds(125,250,250,35); + titleLabel.setBounds(175,0,250,35); + titleLabel.setFont(new Font(null, Font.BOLD, 25)); + titleLabel.setForeground(Color.white); + messageLabel.setBounds(125,240,250,35); messageLabel.setFont(new Font(null,Font.ITALIC,15)); - retryLabel.setBounds(125, 275, 250, 35); + retryLabel.setBounds(125, 255, 250, 35); retryLabel.setFont(new Font(null, Font.ITALIC, 15)); - + retryLabel.setForeground(Color.red); + imageLabel.setBackground(Color.black); + imageLabel.setBounds(80,0, width, height-100); + userIDField.setBounds(125,100,200,25); loginButton.setBounds(225,188,100,25); loginButton.setFocusable(false); @@ -71,17 +83,19 @@ public class LoginPage implements ActionListener{ bottomPanel.setBounds(0,0,width, height); bottomPanel.setLayout(null); - setLightBulb(bottomPanel); + setLightBulb(); topPanel.setLayout(null); topPanel.add(emailLabel); topPanel.add(userPasswordLabel); + topPanel.add(titleLabel); topPanel.add(messageLabel); topPanel.add(retryLabel); topPanel.add(userIDField); topPanel.add(loginButton); topPanel.add(passwordField); bottomPanel.add(newButton); + bottomPanel.add(imageLabel); topPanel.setBackground(Color.black); topPanel.setBounds(width / 2, 60, width/2-30, height-140); @@ -92,7 +106,7 @@ public class LoginPage implements ActionListener{ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(width,height); frame.setMinimumSize(new Dimension(800, 420)); - //frame.setMaximumSize(new Dimension(800, 420)); + frame.setMaximumSize(new Dimension(800, 420)); frame.getContentPane().setLayout(null); frame.setLocationRelativeTo(null); @@ -102,17 +116,18 @@ public class LoginPage implements ActionListener{ CheckBackendStatus(); } - private void setLightBulb(JPanel panel) { - ImageIcon image = new ImageIcon("src/main/resources/images/lightbulb_off.png"); - - JLabel label = new JLabel(); - label.setBackground(Color.black); - label.setIcon(resizeIcon(image, 255, 343)); - label.setBounds(80,0, width, height-100); - panel.add(label); + // Sets a lightbulb image on login window + private void setLightBulb() { + imageLabel.setIcon(resizeIcon(lightImageOff, 255, 343)); } - private static Icon resizeIcon(ImageIcon icon, int resizedWidth, int resizedHeight) { + // Sets the lightbulb image on + private void setLightBulbOn() { + imageLabel.setIcon(resizeIcon(lightImageOn, 255, 343)); + } + + // Resize the given image to given width and height + protected static Icon resizeIcon(ImageIcon icon, int resizedWidth, int resizedHeight) { Image img = icon.getImage(); Image resizedImage = img.getScaledInstance(resizedWidth, resizedHeight, java.awt.Image.SCALE_SMOOTH); return new ImageIcon(resizedImage); @@ -123,12 +138,13 @@ public class LoginPage implements ActionListener{ try { if(!HttpRequests.PingRequest()) { SetError("Can't connect to server"); - loginButton.setEnabled(false); LoopConnect(); + loginButton.setEnabled(false); } else { messageLabel.setText(null); retryLabel.setText(null); loginButton.setEnabled(true); + setLightBulbOn(); } } catch (IOException e) { e.printStackTrace(); diff --git a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/RegisterPage.java b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/RegisterPage.java index ce843ec9e2e5bbc2beb9488b9c55127b4107eb3b..a2d19cecce296716474243b0014d1786eff8f898 100644 --- a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/RegisterPage.java +++ b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/RegisterPage.java @@ -100,7 +100,6 @@ public class RegisterPage implements ActionListener, KeyListener { } - @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == cancelButton) { frame.dispose(); @@ -142,20 +141,17 @@ public class RegisterPage implements ActionListener, KeyListener { return true; } - @Override public void keyReleased(KeyEvent e) { if(validateForm()) confirmButton.setEnabled(true); else confirmButton.setEnabled(false); } - @Override public void keyTyped(KeyEvent e) { // } - @Override public void keyPressed(KeyEvent e) { // } diff --git a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/WelcomePage.java b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/WelcomePage.java index 33caf12ae28d5ba4f2400ada23d4ded89089b131..5de712f6615d8a562b0592a3281b540d13a8bad2 100644 --- a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/WelcomePage.java +++ b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/WelcomePage.java @@ -4,6 +4,8 @@ import java.awt.*; import javax.swing.*; import com.joelhelkala.watcherGui.User.User; +import com.joelhelkala.watcherGui.frames.panels.LineChartPanel; +import com.joelhelkala.watcherGui.frames.panels.ProgressBarCirclePanel; public class WelcomePage { @@ -13,62 +15,118 @@ public class WelcomePage { private static final int cardPanelHeight = (height-topPanelHeight-height/11)/2; private static final int cardWidth = 300; - public WelcomePage(){ + private static final Color gray = new Color(45, 45, 45); + private static final Color lightgray = new Color(73, 73, 73); + private static final Color darkwhite = new Color(96, 96, 96); + private static final Color dark = new Color(33, 33, 33); + + public WelcomePage(){ JPanel topPanel = new JPanel(); - topPanel.setBackground(Color.red); + topPanel.setBackground(dark); topPanel.setBounds(0,0,width, topPanelHeight); JPanel leftPanel = new JPanel(); - leftPanel.setBackground(Color.red); + leftPanel.setBackground(dark); leftPanel.setBounds(0, topPanelHeight, leftPanelWidth, height); JPanel bottomPanel = new JPanel(); - bottomPanel.setBackground(Color.blue); + bottomPanel.setBackground(gray); bottomPanel.setBounds(leftPanelWidth, height-height/11, width, height/11); JPanel cardPanel = new JPanel(); - cardPanel.setBackground(Color.black); + cardPanel.setBackground(gray); cardPanel.setBounds(leftPanelWidth, topPanelHeight, width-leftPanelWidth, cardPanelHeight); cardPanel.setLayout(null); JPanel card1 = new JPanel(); - card1.setBackground(Color.gray); + card1.setBackground(lightgray); card1.setBounds(15, 10, cardWidth, cardPanelHeight-20); cardPanel.add(card1); - JPanel card2 = new JPanel(); - card2.setBackground(Color.gray); + JPanel card2 = new ProgressBarCirclePanel().makeUI(); + card2.setBackground(lightgray); card2.setBounds(cardWidth+30, 10, cardWidth, cardPanelHeight-20); cardPanel.add(card2); JPanel card3 = new JPanel(); - card3.setBackground(Color.gray); + card3.setBackground(lightgray); card3.setBounds(cardWidth*2+45, 10, cardWidth, cardPanelHeight-20); cardPanel.add(card3); - JPanel chartPanel = new JPanel(); - chartPanel.setBackground(Color.green); + chartPanel.setBackground(gray); chartPanel.setBounds(leftPanelWidth, topPanelHeight+cardPanelHeight, width-leftPanelWidth, cardPanelHeight); chartPanel.setLayout(null); - JPanel chart = new JPanel(); - chart.setBackground( new Color(22, 147, 30)); + JPanel chart = new LineChartPanel("Temperature").getPanel(); + chart.setBackground(darkwhite); chart.setBounds(15, 10, width - leftPanelWidth - 30, cardPanelHeight - 20); chartPanel.add(chart); JFrame frame = new JFrame(); frame.getContentPane().setBackground( new Color(128, 127, 137) ); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setLayout(null); + frame.getContentPane().setLayout(null); frame.setSize(width, height); frame.setLocationRelativeTo(null); - frame.add(topPanel); - frame.add(leftPanel); - frame.add(cardPanel); - frame.add(chartPanel); - frame.add(bottomPanel); + frame.getContentPane().add(topPanel); + topPanel.setLayout(null); + + JLabel userLabel = new JLabel("Hello, " + User.getName()); + userLabel.setBounds(1060, 32, 71, 16); + userLabel.setHorizontalAlignment(SwingConstants.CENTER); + userLabel.setForeground(Color.WHITE); + topPanel.add(userLabel); + JLabel iconLabel = new JLabel(); + iconLabel.setBounds(20,10,50,50); + ImageIcon image = new ImageIcon("src/main/resources/images/lightbulb_on.png"); + iconLabel.setIcon(LoginPage.resizeIcon(image, 50, 50)); + topPanel.add(iconLabel); + JLabel titleLabel = new JLabel("WATCHER"); + titleLabel.setForeground(Color.yellow); + titleLabel.setBounds(100, 0, 100, 50); + topPanel.add(titleLabel); + frame.getContentPane().add(leftPanel); + leftPanel.setLayout(null); + + JLabel nodeDataLabel = new JLabel("Node data"); + nodeDataLabel.setHorizontalAlignment(SwingConstants.CENTER); + nodeDataLabel.setFont(new Font("Apple SD Gothic Neo", Font.PLAIN, 16)); + nodeDataLabel.setBounds(64, 57, 98, 16); + nodeDataLabel.setForeground(Color.WHITE); + leftPanel.add(nodeDataLabel); + + JLabel nodeSettingsLabel = new JLabel("Node settings"); + nodeSettingsLabel.setHorizontalAlignment(SwingConstants.CENTER); + nodeSettingsLabel.setForeground(Color.WHITE); + nodeSettingsLabel.setFont(new Font("Apple SD Gothic Neo", Font.PLAIN, 16)); + nodeSettingsLabel.setBounds(64, 110, 98, 16); + leftPanel.add(nodeSettingsLabel); + + JLabel friendsLabel = new JLabel("Friends"); + friendsLabel.setHorizontalAlignment(SwingConstants.CENTER); + friendsLabel.setForeground(Color.WHITE); + friendsLabel.setFont(new Font("Apple SD Gothic Neo", Font.PLAIN, 16)); + friendsLabel.setBounds(64, 163, 98, 16); + leftPanel.add(friendsLabel); + + JLabel helpLabel = new JLabel("Help"); + helpLabel.setHorizontalAlignment(SwingConstants.CENTER); + helpLabel.setForeground(Color.WHITE); + helpLabel.setFont(new Font("Apple SD Gothic Neo", Font.PLAIN, 16)); + helpLabel.setBounds(20, 615, 98, 16); + leftPanel.add(helpLabel); + + JLabel settingsLabel = new JLabel("Settings"); + settingsLabel.setHorizontalAlignment(SwingConstants.CENTER); + settingsLabel.setForeground(Color.WHITE); + settingsLabel.setFont(new Font("Apple SD Gothic Neo", Font.PLAIN, 16)); + settingsLabel.setBounds(123, 615, 98, 16); + leftPanel.add(settingsLabel); + frame.getContentPane().add(cardPanel); + frame.getContentPane().add(chartPanel); + frame.getContentPane().add(bottomPanel); frame.setVisible(true); } diff --git a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/panels/LineChartPanel.java b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/panels/LineChartPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..4ced634c22157b06af1c127d4bb54491b8af3098 --- /dev/null +++ b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/panels/LineChartPanel.java @@ -0,0 +1,49 @@ +package com.joelhelkala.watcherGui.frames.panels; + +import java.awt.Dimension; + +import javax.swing.JPanel; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.data.category.DefaultCategoryDataset; +import java.awt.BorderLayout; +import java.time.LocalDateTime; + +public class LineChartPanel { + + private JPanel panel; + + // Constructor + public LineChartPanel(String chartTitle) { + JFreeChart lineChart = ChartFactory.createLineChart(chartTitle, "DateTime","Temperature", + createDataset(), + PlotOrientation.VERTICAL, + true,true,false); + + ChartPanel chartPanel = new ChartPanel( lineChart ); + chartPanel.setPreferredSize( new Dimension( 560 , 367 ) ); + panel = new JPanel(); + panel.setLayout(new BorderLayout()); + panel.add(chartPanel, BorderLayout.CENTER); + panel.validate(); + } + + public JPanel getPanel() { + return panel; + } + + // Mockup dataset + private DefaultCategoryDataset createDataset( ) { + DefaultCategoryDataset dataset = new DefaultCategoryDataset( ); + dataset.addValue( -17 , "temp" , LocalDateTime.now().minusDays(5) ); + dataset.addValue( -15 , "temp" , LocalDateTime.now().minusDays(5).plusHours(2)); + dataset.addValue( -16 , "temp" , LocalDateTime.now().minusDays(4).minusHours(2) ); + dataset.addValue( -17 , "temp" , LocalDateTime.now().minusDays(1).minusHours(3) ); + dataset.addValue( -10 , "temp" , LocalDateTime.now().minusDays(1) ); + dataset.addValue( -3 , "temp" , LocalDateTime.now() ); + return dataset; + } +} diff --git a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/panels/ProgressBarCirclePanel.java b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/panels/ProgressBarCirclePanel.java new file mode 100644 index 0000000000000000000000000000000000000000..88954aae9f9e98e8ff61f2758561ca2a23ab73cc --- /dev/null +++ b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/panels/ProgressBarCirclePanel.java @@ -0,0 +1,86 @@ +package com.joelhelkala.watcherGui.frames.panels; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.Timer; +import javax.swing.plaf.basic.BasicProgressBarUI; +import org.jfree.chart.ChartColor; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Shape; +import java.awt.geom.Arc2D; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.awt.RenderingHints; + +public class ProgressBarCirclePanel extends BasicProgressBarUI { + + // https://java-swing-tips.blogspot.com/2014/06/how-to-create-circular-progress.html + @Override + public Dimension getPreferredSize(JComponent c) { + Dimension d = super.getPreferredSize(c); + int v = Math.max(d.width, d.height); + d.setSize(v, v); + return d; + } + + @Override + public void paint(Graphics g, JComponent c) { + Insets b = progressBar.getInsets(); // area for border + int barRectWidth = progressBar.getWidth() - b.right - b.left; + int barRectHeight = progressBar.getHeight() - b.top - b.bottom; + if (barRectWidth <= 0 || barRectHeight <= 0) { + return; + } + + // draw the cells + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setPaint(progressBar.getForeground()); + double degree = 360 * progressBar.getPercentComplete(); + double sz = Math.min(barRectWidth, barRectHeight); + double cx = b.left + barRectWidth * .5; + double cy = b.top + barRectHeight * .5; + double or = sz * .5; + double ir = or * .5; // or - 20; + Shape inner = new Ellipse2D.Double(cx - ir, cy - ir, ir * 2, ir * 2); + Shape outer = new Arc2D.Double(cx - or, cy - or, sz, sz, 90 - degree, degree, Arc2D.PIE); + Area area = new Area(outer); + area.subtract(new Area(inner)); + g2.fill(area); + g2.dispose(); + + // Deal with possible text painting + if (progressBar.isStringPainted()) { + paintString(g, b.left, b.top, barRectWidth, barRectHeight, 0, b); + } + } + + // Returns the panel which contains the circle progressbar + public JPanel makeUI() { + JProgressBar progress = new JProgressBar(); + // use JProgressBar#setUI(...) method + progress.setUI(new ProgressBarCirclePanel()); + progress.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); + progress.setStringPainted(true); + progress.setFont(progress.getFont().deriveFont(24f)); + progress.setForeground(ChartColor.ORANGE); + + // Timer for animation + (new Timer(50, e -> { + int iv = Math.min(100, progress.getValue() + 1); + progress.setValue(iv); + })).start(); + + JPanel p = new JPanel(); + p.setLayout(new BorderLayout()); + p.add(progress, BorderLayout.CENTER); + return p; + } +} diff --git a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/panels/TestPanel.java b/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/panels/TestPanel.java deleted file mode 100644 index ccae3e64b9106d85273b095ccc50236bb93a2ddb..0000000000000000000000000000000000000000 --- a/WatcherGui/src/main/java/com/joelhelkala/watcherGui/frames/panels/TestPanel.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.joelhelkala.watcherGui.frames.panels; - -import java.awt.Color; -import java.awt.GradientPaint; -import java.awt.Graphics; -import java.awt.Graphics2D; - -import javax.swing.BorderFactory; -import javax.swing.JFrame; -import javax.swing.JPanel; - -public class TestPanel extends JPanel { - - public TestPanel() { - this.setBorder(BorderFactory.createEmptyBorder(300, 400, 300, 400)); - } - - @Override - public void paintComponent(Graphics g) { - super.paintComponent(g); - Graphics2D g2d = (Graphics2D) g; - Color color1 = new Color(87,86,89); - Color color2 = new Color(56,56,58); - int w = getWidth(); - int h = getHeight(); - GradientPaint gp = new GradientPaint( - 0, 0, color1, 0, h, color2); - g2d.setPaint(gp); - g2d.fillRect(0, 0, w, h); - } - - void display() { - JFrame.setDefaultLookAndFeelDecorated(true); - JFrame frame = new JFrame("Watcher"); - - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - frame.getContentPane().add(this); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - } -} diff --git a/WatcherGui/src/main/resources/images/lightbulb_on.png b/WatcherGui/src/main/resources/images/lightbulb_on.png index b35e1b850ad817d0dd3871bf0e3856fdb7e7bd58..036ec2916e96a4f3483cd2584ce833fd3dd24cc5 100644 Binary files a/WatcherGui/src/main/resources/images/lightbulb_on.png and b/WatcherGui/src/main/resources/images/lightbulb_on.png differ diff --git a/WatcherGui/src/main/resources/images/lightbulb_warm.png b/WatcherGui/src/main/resources/images/lightbulb_warm.png index d9d175800ffbffc5507bbabac180c92e44100216..d8c43073fe1e60e383513965b88ce87c484aa1cf 100644 Binary files a/WatcherGui/src/main/resources/images/lightbulb_warm.png and b/WatcherGui/src/main/resources/images/lightbulb_warm.png differ