Package view

Source Code of view.Application

package view;

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Collections;

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

import model.OnlineComparator;
import model.Stream;

import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.SystemTray;
import java.awt.Toolkit;

import javax.swing.JCheckBox;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.io.File;

import javax.swing.JCheckBoxMenuItem;

public class Application implements ActionListener {

  JFrame frmStreamtrackerV;
  JPanel panel;
  JScrollPane scrollPane;
  static ArrayList<Stream> streams;
 
  boolean initial;
  boolean notificationsEnabled;
  boolean groupOnline;
  boolean minimizeToTray;

  STTrayIcon trayIcon;
 
  JButton btnAddStream;
  JButton btnDeleteStream;
 
  JLabel lblExamplechannel;
  JLabel lblLoadingChannels;

  Thread update;
 
  Timer updateTimer;

  /**
   * Launch the application.
   */
  public static void main(String[] args) {
   
    // Set the correct Look and Feel, based on the system used.
      try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (ClassNotFoundException e1) {
        e1.printStackTrace();
      } catch (InstantiationException e1) {
        e1.printStackTrace();
      } catch (IllegalAccessException e1) {
        e1.printStackTrace();
      } catch (UnsupportedLookAndFeelException e1) {
        e1.printStackTrace();
      }
   
    // Initialize the streams ArrayList
    controller.Init.init(new ArrayList<String>(0));
   
    // Create the actual window and frame
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        try {
          Application window = new Application();
          window.frmStreamtrackerV.setVisible(true);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  /**
   * Create the application.
   */
  public Application() {
   
    // Get the list of channels
    String[] channels = controller.Init.init(new ArrayList<String>(0));
   
    // Build a list of Stream objects out of the list of channel names
    streams = new ArrayList<Stream>(0);
   
    // Update all of the information for each stream
    for (int i = 0; i < channels.length; i++)
      streams.add(new Stream(channels[i]));
   
    // Create the main frame and panel
    panel = new JPanel();
    frmStreamtrackerV = new JFrame();
   
    // Set initial boolean values
    notificationsEnabled = true;
    initial = true;
    groupOnline = false;
    minimizeToTray = true;
   
    // Create an initial thread for the table updating method
    update = new Thread();
   
    // Create the timer for stream refreshing, running once per 60 seconds
    updateTimer = new Timer(60000, this);
    updateTimer.setInitialDelay(1);
   
    // Initialize the information in the window
    initialize();
   
    // Create and initialize the tray icon
    trayIcon = new STTrayIcon();
    trayIcon.init(this);
   
    // Start the API call timer
    updateTimer.start();
  }

  /**
   * Initialize the contents of the frame.
   */
  private void initialize() {
   
    // Set properties of the main frame
    frmStreamtrackerV.setTitle("StreamTracker v1.3");
    frmStreamtrackerV.setIconImage(Toolkit.getDefaultToolkit().getImage("icon.gif"));
    frmStreamtrackerV.setBounds(100, 100, 400, 410);
    frmStreamtrackerV.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frmStreamtrackerV.addWindowListener(new WindowExitAdapter());
    frmStreamtrackerV.addWindowListener(new WindowRestoreAdapter());
   
    Dimension dim = new Dimension();
    dim.setSize(400, 410);
    frmStreamtrackerV.setMinimumSize(dim);
   
    // Set proprerties of the Add stream button
    btnAddStream = new JButton("Add stream");
    btnAddStream.setFont(new Font("Tahoma", Font.PLAIN, 11));
    btnAddStream.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent arg0) {
        String streamToAdd = JOptionPane.showInputDialog(frmStreamtrackerV, "Enter the name of the channel you'd like to track:");
       
        // Do not attempt to add invalid streams
        if (streamToAdd == null || streamToAdd == "") return;
        if (streams.contains(new Stream(streamToAdd))) return;
       
        // Get the correct location to add the stream
        int i;
        for(i = 0; i < streams.size() && streamToAdd.toLowerCase().compareTo(streams.get(i).getChannel().toLowerCase()) > 0; i++) { }
        if (i == streams.size()) streams.add(new Stream(streamToAdd));
        else streams.add(i, new Stream(streamToAdd));
       
        // Refresh the newly-added stream, update the table of information, then repaint the window
        streams.get(i).refresh();
        updateTable();
        frmStreamtrackerV.validate();
        frmStreamtrackerV.repaint();
       
      }
    });
   
    // Set the properties for the delete stream button
    btnDeleteStream = new JButton("Delete stream");
    btnDeleteStream.setFont(new Font("Tahoma", Font.PLAIN, 11));
    btnDeleteStream.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent arg0) {
        String streamToRemove = JOptionPane.showInputDialog(frmStreamtrackerV, "Enter the name of the channel you'd like to stop tracking:");
        Stream r = new Stream(streamToRemove);
       
        // Do not remove invalid streams
        if (streamToRemove == null || streamToRemove == "" || !streams.contains(r))
        {
          return;
        }
       
        streams.remove(r);
       
        // Update and repaint the table
        updateTable();
        frmStreamtrackerV.validate();
        frmStreamtrackerV.repaint();
      }
    });
   
    // Create the scroll pane for the table
    scrollPane = new JScrollPane();
    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
   
    JPanel panel_1 = new JPanel();
   
    // Set the properties for the "Group online streams" checkbox
    JCheckBox chckbxGroupOnlineStreams = new JCheckBox("Group online streams");
    chckbxGroupOnlineStreams.addItemListener(new ItemListener() {
      public void itemStateChanged(ItemEvent ie) {
       
        // Sort by the proper comparator based on whether the box was checked or unchecked
        if (ie.getStateChange() == ItemEvent.SELECTED) {
          groupOnline = true;
          Collections.sort(streams, new OnlineComparator());
        }
        if (ie.getStateChange() == ItemEvent.DESELECTED) {
          groupOnline = false;
          Collections.sort(streams);
        }
       
        // Update and repaint the table
        updateTable();
        frmStreamtrackerV.validate();
        frmStreamtrackerV.repaint();
       
      }
    });
    chckbxGroupOnlineStreams.setFont(new Font("Tahoma", Font.PLAIN, 10));
   
    // Set up the loading labels
    lblLoadingChannels = new JLabel("Loading channels...");
    lblLoadingChannels.setFont(new Font("Tahoma", Font.PLAIN, 10));
   
    lblExamplechannel = new JLabel("");
    lblExamplechannel.setFont(new Font("Tahoma", Font.PLAIN, 10));
   
    GroupLayout groupLayout = new GroupLayout(frmStreamtrackerV.getContentPane());
    groupLayout.setHorizontalGroup(
      groupLayout.createParallelGroup(Alignment.LEADING)
        .addGroup(groupLayout.createSequentialGroup()
          .addContainerGap()
          .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(groupLayout.createSequentialGroup()
              .addComponent(panel_1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
              .addGap(150))
            .addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
              .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 247, Short.MAX_VALUE)
              .addPreferredGap(ComponentPlacement.RELATED)
              .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
                .addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
                  .addComponent(btnAddStream, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE)
                  .addComponent(btnDeleteStream, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE))
                .addComponent(chckbxGroupOnlineStreams)
                .addComponent(lblLoadingChannels)
                .addComponent(lblExamplechannel))))
          .addGap(0))
    );
    groupLayout.setVerticalGroup(
      groupLayout.createParallelGroup(Alignment.LEADING)
        .addGroup(groupLayout.createSequentialGroup()
          .addContainerGap()
          .addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 17, GroupLayout.PREFERRED_SIZE)
          .addPreferredGap(ComponentPlacement.RELATED)
          .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(groupLayout.createSequentialGroup()
              .addComponent(btnAddStream)
              .addPreferredGap(ComponentPlacement.RELATED)
              .addComponent(btnDeleteStream)
              .addPreferredGap(ComponentPlacement.UNRELATED)
              .addComponent(chckbxGroupOnlineStreams)
              .addGap(28)
              .addComponent(lblLoadingChannels)
              .addPreferredGap(ComponentPlacement.RELATED)
              .addComponent(lblExamplechannel))
            .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE))
          .addGap(10))
    );
   
    // Set the table layout for the column headers
    GridBagLayout gbl_panel_1 = new GridBagLayout();
    gbl_panel_1.columnWidths = new int[]{101, 63, 60};
    gbl_panel_1.rowHeights = new int[]{25, 0};
    gbl_panel_1.columnWeights = new double[]{0.0};
    gbl_panel_1.rowWeights = new double[]{Double.MIN_VALUE};
    panel_1.setLayout(gbl_panel_1);
   
    // Create the column headers
    JLabel lblChannel = new JLabel("Channel");
    lblChannel.setFont(new Font("Tahoma", Font.BOLD, 11));
    GridBagConstraints gbc_lblChannel = new GridBagConstraints();
    gbc_lblChannel.insets = new Insets(4, 5, 5, 5);
    gbc_lblChannel.gridx = 0;
    gbc_lblChannel.gridy = 0;
    gbc_lblChannel.anchor = GridBagConstraints.NORTH;
    panel_1.add(lblChannel, gbc_lblChannel);
   
    JLabel lblOnline_1 = new JLabel("Online");
    lblOnline_1.setFont(new Font("Tahoma", Font.BOLD, 11));
    GridBagConstraints gbc_lblOnline_1 = new GridBagConstraints();
    gbc_lblOnline_1.insets = new Insets(4, 0, 5, 5);
    gbc_lblOnline_1.gridx = 1;
    gbc_lblOnline_1.gridy = 0;
    gbc_lblChannel.anchor = GridBagConstraints.NORTHWEST;
    panel_1.add(lblOnline_1, gbc_lblOnline_1);
   
    JLabel lblViewers = new JLabel("Viewers");
    lblViewers.setFont(new Font("Tahoma", Font.BOLD, 11));
    GridBagConstraints gbc_lblViewers = new GridBagConstraints();
    gbc_lblViewers.insets = new Insets(4, 0, 5, 0);
    gbc_lblViewers.gridx = 2;
    gbc_lblViewers.gridy = 0;
    gbc_lblChannel.anchor = GridBagConstraints.NORTHWEST;
    panel_1.add(lblViewers, gbc_lblViewers);
   
    scrollPane.setViewportView(panel);
   
    frmStreamtrackerV.getContentPane().setLayout(groupLayout);
   
    // Set the properties of the menu bar
    JMenuBar menuBar = new JMenuBar();
    frmStreamtrackerV.setJMenuBar(menuBar);
   
    JMenu mnFile = new JMenu("File");
    menuBar.add(mnFile);
   
    JMenuItem mntmExit = new JMenuItem("Exit");
    mntmExit.addMouseListener(new MouseAdapter() {
      @Override
      public void mousePressed(MouseEvent arg0) {
        new WindowExitAdapter().windowClosing(null);
        System.exit(0);
      }
    });
    mnFile.add(mntmExit);
   
    JMenu mnHelp = new JMenu("Help");
    menuBar.add(mnHelp);
   
    JMenuItem mntmAbout = new JMenuItem("About");
    mntmAbout.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(frmStreamtrackerV, "StreamTracker v1.3, May 27 2012\n" +
                                  "Built using Eclipse and WindowBuilderPro", "About", JOptionPane.INFORMATION_MESSAGE);             
      }
    });
   
    // Set properties for disabling notifications
    JCheckBoxMenuItem chckbxmntmDisableNotifications = new JCheckBoxMenuItem("Disable notifications");
    chckbxmntmDisableNotifications.addItemListener(new ItemListener() {
      public void itemStateChanged(ItemEvent ie) {
       
        // Enable or disable the notifications boolean
        if (ie.getStateChange() == ItemEvent.SELECTED) notificationsEnabled = false;
        if (ie.getStateChange() == ItemEvent.DESELECTED) notificationsEnabled = true;
      }
    });
    mnHelp.add(chckbxmntmDisableNotifications);
   
    JCheckBoxMenuItem chckbxmntmMinimizeToTray = new JCheckBoxMenuItem("Minimize to tray", true);
    chckbxmntmMinimizeToTray.addItemListener(new ItemListener() {
      public void itemStateChanged(ItemEvent ie) {
       
        // Enable or disable the minimize boolean
        if (ie.getStateChange() == ItemEvent.DESELECTED) minimizeToTray = false;
        if (ie.getStateChange() == ItemEvent.SELECTED) minimizeToTray = true;
      }
    });
    mnHelp.add(chckbxmntmMinimizeToTray);
    mnHelp.add(mntmAbout);
  }

  public static Stream[] getStreams() {
    return streams.toArray(new Stream[0]);
  }
 
  public void updateTable()
  {
    // Set the layout
    GridBagLayout gbl_panel = new GridBagLayout();
    gbl_panel.columnWidths = new int[]{101, 60, 60, 0};
   
    // Let the row heights be based on the number of streams
    int[] rowHeights = new int[streams.size()+1];
    for(int i = 0; i < streams.size(); i++)
      rowHeights[i] = 25;
    rowHeights[streams.size()] = 0;
    gbl_panel.rowHeights = rowHeights;   
    gbl_panel.columnWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
    gbl_panel.rowWeights = new double[]{0.0};
    panel.setLayout(gbl_panel);
   
    panel.removeAll();
   
    synchronized (streams)
    {
      if (groupOnline) Collections.sort(streams, new OnlineComparator());
      else Collections.sort(streams);
     
      for(int i = 0; i < streams.size(); i++)
      {       
        JLabel lbl = new JLabel(streams.get(i).getChannel());
        lbl.setFont(new Font("Tahoma", Font.PLAIN, 11));
        GridBagConstraints gbc_lbl = new GridBagConstraints();
        gbc_lbl.insets = new Insets(4, 5, 5, 5);
        gbc_lbl.gridx = 0;
        gbc_lbl.gridy = i;
        gbc_lbl.anchor = GridBagConstraints.NORTHWEST;
        panel.add(lbl, gbc_lbl);
       
        JLabel lblOnline = new JLabel(streams.get(i).isOnline() ? "Online" : "Offline");
        if (streams.get(i).isOnline())
        {
          lblOnline.setFont(new Font("Tahoma", Font.BOLD, 11));
          JLabelLink.makeLinkable(lblOnline, new JLabelLink.LinkMouseListener(), streams.get(i).getChannel());
        }
        else
          lblOnline.setFont(new Font("Tahoma", Font.PLAIN, 11));
       
        GridBagConstraints gbc_lblOnline = new GridBagConstraints();
        gbc_lblOnline.insets = new Insets(4, 0, 5, 5);
        gbc_lblOnline.gridx = 1;
        gbc_lblOnline.gridy = i;
        gbc_lblOnline.anchor = GridBagConstraints.NORTH;
        panel.add(lblOnline, gbc_lblOnline);
       
        JLabel label = new JLabel(streams.get(i).isOnline() ? ""+streams.get(i).getViewers() : "-");
        label.setFont(new Font("Tahoma", Font.PLAIN, 11));
        GridBagConstraints gbc_label = new GridBagConstraints();
        gbc_label.insets = new Insets(4, 0, 5, 0);
        gbc_label.gridx = 2;
        gbc_label.gridy = i;
        gbc_label.anchor = GridBagConstraints.NORTH;
       
        // Set weights to avoid entire list being center-aligned on resize
        // I have absolutely no idea how this could be done better, or even how this actually works
        gbc_label.weightx = 1.0;
        if (i == streams.size() - 1)
          gbc_label.weighty = 1.0;
       
        panel.add(label, gbc_label);
      }
    }
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    try {
      // Force the current update thread to finish
      update.join();
     
      // Create new thread
      update = new Thread(new Runnable() {
        @Override
        public void run() {
          synchronized (streams)
          { 
            for (Stream s : streams)
            {
              boolean oldOnline = s.isOnline();
              lblExamplechannel.setText(s.getChannel());
              s.refresh();
              if (!initial && notificationsEnabled && s.isOnline() && !oldOnline) trayIcon.displayPopupMessage(s.getChannel());
            }
            updateTable();
           
            if (initial)
            {
              lblLoadingChannels.setVisible(false);
              lblExamplechannel.setVisible(false);
              initial = false;
            }
           
            frmStreamtrackerV.validate();
            frmStreamtrackerV.repaint();
          }
        }
      });
      update.start();
    } catch (InterruptedException e1) {
      e1.printStackTrace();
    }
  }
 
  public class WindowRestoreAdapter extends WindowAdapter {
   
    public void windowDeiconified(WindowEvent e) {
      EventQueue.invokeLater(new Runnable() { 
        @Override
        public void run() {
          int state = frmStreamtrackerV.getExtendedState();
          state = state & ~JFrame.ICONIFIED;
          frmStreamtrackerV.setExtendedState(state);
          frmStreamtrackerV.setVisible(true);
          frmStreamtrackerV.toFront();
          frmStreamtrackerV.repaint();
        }
      });
    }
  }
 
  public class WindowExitAdapter extends WindowAdapter {

    // When the window is closed, uninitialize the application then quit.
    public void windowClosing(WindowEvent e)
    {
      controller.Uninit.uninit(Application.getStreams(), new File("config.ini"));
      System.exit(0);
    }
   
    // Hide the window when iconified
    public void windowIconified(WindowEvent e)
    {
      if (SystemTray.isSupported() && minimizeToTray)
        e.getComponent().setVisible(false);
    }
  }
 
}
TOP

Related Classes of view.Application

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.