package uk.ac.open.punchingbag; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.DisplayMode; import java.awt.Graphics; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import javax.imageio.ImageIO; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.ListCellRenderer; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; import javax.sound.sampled.Line; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.Mixer; import javax.sound.sampled.TargetDataLine; import javax.sound.sampled.UnsupportedAudioFileException; import javax.sound.sampled.AudioFormat.Encoding; import javax.sound.sampled.Mixer.Info; import uk.ac.open.punchingbag.examples.SimpleKeyboard; import PicHelper.ImagePanel; public class PunchingBagGUI implements MouseListener, MouseMotionListener, ButtonListener, LEDListener { public static enum Mode { Debug, Menu }; Mode currentMode = Mode.Menu; JFrame frame; JPanel bagDebugingPanel = new JPanel(); JPanel programOptionsPanel = new JPanel(new GridBagLayout()); // Contact public enum Direction { None, Up, Down, Left, Right }; String soundDir = System.getProperty("user.dir") + System.getProperty("file.separator"); File[] keys = { new File(soundDir + "G4.wav"), new File(soundDir + "C5.wav"), new File(soundDir + "D5.wav"), new File(soundDir + "E5.wav"), new File(soundDir + "F5.wav"), new File(soundDir + "G5.wav") }; String imageDirectory = System.getProperty("user.home") + System.getProperty("file.separator") + "My Documents" + System.getProperty("file.separator") + "images"; static PunchingBag bag = PunchingBag.getBag(); final boolean useDebugScreen = true; boolean debugImages = true; public static void main(String[] args) throws InterruptedException { new PunchingBagGUI(); new SimpleKeyboard(); } PunchingBagGUI() throws InterruptedException { // System.out.println(AudioSystem.getMixerInfo()[0].getName()); // System.out.println(AudioSystem.getMixerInfo()[0].getDescription()); // Mixer mix = AudioSystem.getMixer(AudioSystem.getMixerInfo()[0]); try { // bag.connectToArduinos(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } frame = new JFrame("Punching Bag GUI"); frame.setUndecorated(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // frame.setSize(600, 600); frame.addMouseListener(this); frame.addMouseMotionListener(this); bag.addButtonListener(this); bag.addLEDChangeListener(this); JSplitPane bottomTopSplitPane = new JSplitPane( JSplitPane.VERTICAL_SPLIT); JSplitPane centerTopSplitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT); JTabbedPane tabbedPane = new JTabbedPane(); tabbedPane.addTab("LED Control Panel", null, new LEDControlPanel(), "Allows control of individual LED's"); tabbedPane.addTab("GUI Control Panel", null, new GUIControlPanel(), "Allows control of the GUI"); centerTopSplitPane.setLeftComponent(new PunchingBagSim()); centerTopSplitPane.setRightComponent(tabbedPane); bottomTopSplitPane.setTopComponent(centerTopSplitPane); bottomTopSplitPane.setBottomComponent(new SerialPanel()); bagDebugingPanel.add(bottomTopSplitPane, BorderLayout.CENTER); programOptionsPanel.add(new JButton("Debug")); frame.add(bagDebugingPanel); frame.add(new DisplayPanel(), BorderLayout.CENTER); frame.add(programOptionsPanel, BorderLayout.SOUTH); setMode(currentMode); GraphicsDevice device; device = GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice(); if (device.isFullScreenSupported()) { device.setFullScreenWindow(frame); } else { System.err.println("Full screen not supported"); } frame.setVisible(true); // frame.pack(); } void setMode(Mode mode) { this.currentMode = mode; if (currentMode == Mode.Menu) { bagDebugingPanel.setVisible(false); programOptionsPanel.setVisible(true); } else if (currentMode == Mode.Debug) { bagDebugingPanel.setVisible(true); programOptionsPanel.setVisible(false); } } class MenuPanel extends JPanel implements ActionListener { MenuPanel() { this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(Box.createVerticalGlue()); JPanel bottom = new JPanel(); bottom.setAlignmentX(1f); bottom.setLayout(new BoxLayout(bottom, BoxLayout.X_AXIS)); JButton debugMode = new JButton("Debug Mode"); debugMode.addActionListener(this); bottom.add(debugMode); bottom.add(Box.createRigidArea(new Dimension(15, 0))); this.add(bottom); this.add(Box.createRigidArea(new Dimension(0, 15))); } @Override public void actionPerformed(ActionEvent e) { setMode(Mode.Debug); } } class DisplayPanel extends ImagePanel implements Runnable { ArrayList files = new ArrayList(); int image = 0; DisplayPanel() { super(); new Thread(this).start(); } public void run() { loadImages(); while (true) { try { this.loadImage(files.get(image)); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } this.repaint(); if (image == (files.size() - 1)) { image = 0; } else { image++; } if (debugImages) System.out.println("Moving to the next image "); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void loadImages() { if (debugImages) System.out.println("Loading images..."); File imageDir = new File(imageDirectory); System.out.println("Looking in " + imageDirectory); File[] dirFiles = imageDir.listFiles(); for (int i = 0; i < dirFiles.length; i++) { if (dirFiles[i].getName().contains(".jpg")) { if (debugImages) System.out.println("Found .jpg " + dirFiles[i].getName()); files.add(dirFiles[i]); } } if (debugImages) System.out.println("Finished loading images"); } } class SerialPanel extends JPanel implements ActionListener, SerialReadListener, SerialWriteListener { JTextArea buttonIn = new JTextArea(); JTextArea buttonOut = new JTextArea(); JTextArea ledIn = new JTextArea(); JTextArea ledOut = new JTextArea(); public SerialPanel() { JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); JSplitPane buttonSplitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT); JSplitPane ledSplitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT); /* * splitPane.setOneTouchExpandable(true); * buttonSplitPane.setOneTouchExpandable(true); * ledSplitPane.setOneTouchExpandable(true); */ splitPane.setMinimumSize(new Dimension(200, 50)); buttonSplitPane.setMinimumSize(new Dimension(100, 50)); ledSplitPane.setMinimumSize(new Dimension(100, 50)); JButton clear = new JButton("Clear"); clear.addActionListener(this); JPanel buttonInPanel = new JPanel(); JScrollPane areaScrollPane = new JScrollPane(buttonIn); areaScrollPane .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); areaScrollPane.setPreferredSize(new Dimension(250, 100)); buttonInPanel.add(areaScrollPane, BorderLayout.CENTER); clear.setActionCommand("BI"); buttonInPanel.add(clear, BorderLayout.SOUTH); buttonInPanel.setBorder(BorderFactory .createTitledBorder("Serial In - Button Arduino")); buttonSplitPane.setLeftComponent(buttonInPanel); JPanel buttonOutPanel = new JPanel(); areaScrollPane = new JScrollPane(buttonOut); areaScrollPane .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); areaScrollPane.setPreferredSize(new Dimension(250, 100)); buttonOutPanel.add(areaScrollPane, BorderLayout.CENTER); clear = new JButton("Clear"); clear.setActionCommand("BO"); buttonOutPanel.add(clear, BorderLayout.SOUTH); buttonOutPanel.setBorder(BorderFactory .createTitledBorder("Serial Out - Button Arduino")); buttonSplitPane.setRightComponent(buttonOutPanel); JPanel ledInPanel = new JPanel(); areaScrollPane = new JScrollPane(ledIn); areaScrollPane .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); areaScrollPane.setPreferredSize(new Dimension(250, 100)); ledInPanel.add(areaScrollPane, BorderLayout.CENTER); clear = new JButton("Clear"); clear.setActionCommand("LI"); ledInPanel.add(clear, BorderLayout.SOUTH); ledInPanel.setBorder(BorderFactory .createTitledBorder("Serial In - LED Arduino")); ledSplitPane.setLeftComponent(ledInPanel); JPanel ledOutPanel = new JPanel(); areaScrollPane = new JScrollPane(ledOut); areaScrollPane .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); areaScrollPane.setPreferredSize(new Dimension(250, 100)); ledOutPanel.add(areaScrollPane, BorderLayout.CENTER); clear = new JButton("Clear"); clear.setActionCommand("LO"); ledOutPanel.add(clear, BorderLayout.SOUTH); ledOutPanel.setBorder(BorderFactory .createTitledBorder("Serial Out - LED Arduino")); ledSplitPane.setRightComponent(ledOutPanel); splitPane.setLeftComponent(buttonSplitPane); splitPane.setRightComponent(ledSplitPane); this.add(splitPane); bag.buttonArduino.addSerialReadListener(this); bag.buttonArduino.addSerialWriteListener(this); } @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub } @Override public void serialWriteEvent(byte b) { buttonOut.append(String.valueOf((char) b)); } @Override public void serialWriteEvent(byte[] b) { buttonOut.append(String.valueOf(b)); } @Override public void serialReadEvent(int b) { if (b != -1) buttonIn.append(String.valueOf((char) b)); } } class GUIControlPanel extends JPanel implements ActionListener { public GUIControlPanel() { JButton menuButton = new JButton("Menu"); menuButton.addActionListener(this); this.add(menuButton); } @Override public void actionPerformed(ActionEvent e) { setMode(Mode.Menu); } } class LEDControlPanel extends JPanel implements ActionListener { String[] colours = { " ", "R", "Y", "G" }; public LEDControlPanel() { this.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; // c.weightx = 0.2; // c.weighty = 0.2; for (int y = 0; y < bag.ledHeight; y++) { for (int x = 0; x < bag.ledWidth; x++) { c.gridx = x; c.gridy = y; RYGComboBoxRenderer renderer = new RYGComboBoxRenderer(); JComboBox rygCombo = new JComboBox(colours); rygCombo.setSelectedIndex(0); rygCombo.addActionListener(this); rygCombo.setActionCommand(String.valueOf(x) + "," + String.valueOf(y)); // rygCombo.setRenderer(renderer); this.add(rygCombo, c); } } c.gridx = 0; c.gridy = 20; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.CENTER; c.gridwidth = 9; JButton clear = new JButton("Clear"); clear.setActionCommand("C"); clear.addActionListener(this); this.add(clear, c); } public void actionPerformed(ActionEvent a) { if (a.getActionCommand() == "C") { bag.clearLEDs(); } else { Color colour = Color.white; if (((JComboBox) a.getSource()).getSelectedIndex() == 1) { colour = Color.red; } else if (((JComboBox) a.getSource()).getSelectedIndex() == 2) { colour = Color.yellow; } else if (((JComboBox) a.getSource()).getSelectedIndex() == 3) { colour = Color.green; } System.out.println("Setting " + a.getActionCommand().split(",")[0] + " " + a.getActionCommand().split(",")[1]); bag.setLED(Integer.valueOf(a.getActionCommand().split(",")[0]), Integer.valueOf(a.getActionCommand().split(",")[1]), colour); } } class RYGComboBoxRenderer extends JLabel implements ListCellRenderer { public RYGComboBoxRenderer() { super(); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { // Get the selected index. (The index param isn't // always valid, so just use the value.) if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } if (index != -1) setText(colours[index]); return this; } } } class PunchingBagSim extends JPanel implements ButtonListener, LEDListener, MouseListener { int buttonMinSize = 10; int buttonMaxSize = 50; int ledMinSize = 10; int ledMaxSize = 50; int buttonSize = 40; int ledSize = 8; public PunchingBagSim() { /* * this.setMinimumSize(new Dimension((bag.buttonWidth * * buttonMinSize) + (bag.ledWidth * ledMinSize), (bag.buttonHeight * * buttonMinSize) + (bag.ledHeight * ledMaxSize))); * this.setMaximumSize(new Dimension((bag.buttonWidth * * buttonMaxSize) + (bag.ledWidth * ledMaxSize), (bag.buttonHeight * * buttonMaxSize) + (bag.ledHeight * ledMaxSize))); */ bag.addButtonListener(this); bag.addLEDChangeListener(this); this.addMouseListener(this); GridBagLayout gbl = new GridBagLayout(); this.setLayout(gbl); GridBagConstraints c = new GridBagConstraints(); // c.insets = new Insets(1, 1, 1, 1); c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; // c.weightx = 0.2; // c.weighty = 0.2; for (int y = 0; y < bag.ledHeight; y++) { for (int x = 0; x < bag.ledWidth; x++) { c.gridx = x * 2; c.gridy = y * 2; this.add(new LED(x, y), c); } } // c.weightx = 0.8; // c.weighty = 0.8; for (int y = 0; y < bag.buttonHeight; y++) { for (int x = 0; x < bag.buttonWidth; x++) { c.gridx = (x * 2) + 1; c.gridy = (y * 2) + 1; this.add(new Button(x, y), c); } } // this.setMinimumSize(new Dimension(500,500)); // this.setPreferredSize(new Dimension(500,500)); // this.setBackground(Color.BLUE); frame.pack(); frame.setSize(500, 500); this.setBorder(BorderFactory.createLineBorder(Color.black)); } /* * public Dimension getPreferredSize() { if () return new * Dimension(super.,10); } */ class LED extends JComponent implements LEDListener { final int x; final int y; public LED(int x, int y) { this.x = x; this.y = y; /* * this.setMinimumSize(new Dimension(50,50)); this.setSize(50, * 50); this.setPreferredSize(new Dimension(50,50)); */ bag.addLEDChangeListener(this); } public Dimension getPreferredSize() { return new Dimension(5, 5); } public void paintComponent(Graphics g) { if (bag.getLED(x, y) == Color.red) { g.setColor(Color.red); } else if (bag.getLED(x, y) == Color.green) { g.setColor(Color.green); } else if (bag.getLED(x, y) == Color.yellow) { g.setColor(Color.yellow); } else { g.setColor(Color.white); } g.fillOval(0, 0, this.getWidth(), this.getHeight()); } @Override public void LEDchanged() { this.repaint(); } } class Button extends JComponent implements MouseListener { final int x; final int y; public Button(int x, int y) { this.x = x; this.y = y; setBorder(BorderFactory.createLineBorder(Color.black)); this.addMouseListener(this); } public Dimension getPreferredSize() { return new Dimension(20, 20); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.black); g.fillRect(0, 0, this.getWidth(), this.getHeight()); g.setColor(new Color(220, 220, 220)); g.fillRect(4, 4, this.getWidth() - 8, this.getHeight() - 8); } public void mouseClicked(MouseEvent arg0) { } public void mouseEntered(MouseEvent arg0) { } public void mouseExited(MouseEvent arg0) { } public void mousePressed(MouseEvent arg0) { System.out.println("Button Pressed"); bag.buttonPressed(x, y); } public void mouseReleased(MouseEvent arg0) { } } public void buttonPressed(int x, int y) { this.repaint(); } public void LEDchanged() { this.repaint(); } @Override public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent me) { } @Override public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void contact(Contact c) { // TODO Auto-generated method stub } } public void runInteractively(Contact contact) { System.out.println("Contact"); bag.buttonPressed(contact.x, contact.y); } public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } public void mousePressed(MouseEvent arg0) { /* * if (currentMode == Mode.Interactive) { runInteractively(new * Contact(System.currentTimeMillis(), (arg0 .getX() - 4) / 40, * (arg0.getY() - 30) / 40, 0)); } */ } public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseDragged(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseMoved(MouseEvent arg0) { // TODO Auto-generated method stub } public void contact(Contact c) { // TODO Auto-generated method stub } @Override public void buttonPressed(int x, int y) { System.out.println("Button Pressed: " + x + " " + y); // bag.circleExpand(x, y, 16); // bag.setLED(x, y, Color.red); //bag.noise(new Rectangle(0, 0, 9, 20), 5000); /* * for (int bx=0; bx