/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.desktop.classic; import gnu.java.security.action.SetPropertyAction; import java.awt.BorderLayout; import java.awt.Color; import java.awt.GraphicsConfiguration; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Timer; import java.util.TimerTask; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.BevelBorder; import javax.swing.border.EmptyBorder; import javax.swing.plaf.metal.DefaultMetalTheme; import javax.swing.plaf.metal.MetalLookAndFeel; import javax.swing.plaf.metal.OceanTheme; import org.apache.log4j.Logger; import org.jnode.awt.JNodeGraphicsConfiguration; import org.jnode.awt.JNodeToolkit; import org.jnode.plugin.ExtensionPoint; /** * @author Levente S\u00e1ntha */ public class TaskBar extends JPanel { private static final long serialVersionUID = 1L; static final Logger log = Logger.getLogger(TaskBar.class); private static final Class<?>[] mainTypes = {String[].class}; JButton startButton; JPopupMenu startMenu; WindowBar windowBar; JMenuItem quitMI; JMenuItem haltMI; JMenuItem restartMI; JMenuItem desktopColorMI; Desktop desktop; Clock clock; JMenuItem[] chgSizeMenuItem; public TaskBar(Desktop desk, ExtensionPoint appsEP) { this.desktop = desk; BorderLayout layout = new BorderLayout(); layout.setHgap(5); layout.setVgap(0); setLayout(layout); setBorder(new BevelBorder(BevelBorder.RAISED)); startButton = new JButton("JNode", new ImageIcon(Desktop.loadImage("jnode_icon.png"))); startButton.setToolTipText("JNode Menu"); startButton.setBorder(new EmptyBorder(1, 3, 1, 3)); add(startButton, BorderLayout.WEST); startMenu = new JPopupMenu(); JMenu awtMenu = new JMenu("AWT tests"); startMenu.add(awtMenu); awtMenu.add(createMenuItem("AWTDemo", "org.jnode.test.gui.AWTDemo")); awtMenu.add(createMenuItem("AWTFrameTest", "org.jnode.test.gui.AWTFrameTest")); awtMenu.add(createMenuItem("AWTMenuBuilderTest", "org.jnode.test.gui.AWTMenuBuilderTest")); awtMenu.add(createMenuItem("AWTMenuTest", "org.jnode.test.gui.AWTMenuTest")); awtMenu.add(createMenuItem("AWTTest", "org.jnode.test.gui.AWTTest")); awtMenu.add(createMenuItem("RobotTest", "org.jnode.test.gui.RobotTest")); JMenu swingMenu = new JMenu("Swing tests"); startMenu.add(swingMenu); swingMenu.add(createMenuItem("Editor", "org.jnode.test.gui.Editor")); swingMenu.add(createMenuItem("SwingTest", "org.jnode.test.gui.SwingTest")); swingMenu.add(createMenuItem("JTableTest", "org.jnode.test.gui.JTableTest")); swingMenu.add(createMenuItem("JTreeTest", "org.jnode.test.gui.JTreeTest")); swingMenu.add(createMenuItem("JInternalFrameTest", "org.jnode.test.gui.JInternalFrameTest")); swingMenu.add(createMenuItem("JDPTest", "org.jnode.test.gui.JDPTest")); JMenu gamesMenu = new JMenu("Games"); startMenu.add(gamesMenu); gamesMenu.add(createMenuItem("Tetris", "org.jnode.games.tetris.Tetris")); gamesMenu.add(createMenuItem("BoxWorld", "org.jnode.games.boxworld.BoxWorld")); gamesMenu.add(createMenuItem("Rubik", "org.jnode.games.rubik.Rubik")); JMenu toolsMenu = new JMenu("Tools"); startMenu.add(toolsMenu); toolsMenu.add(createMenuItem("Console", "org.jnode.apps.console.SwingConsole")); JMenu settingsMenu = new JMenu("Settings"); startMenu.add(settingsMenu); JMenu resMenu = new JMenu("Screen Resolution"); settingsMenu.add(resMenu); int i = 0; GraphicsConfiguration[] configs = ((JNodeToolkit) Toolkit.getDefaultToolkit()).getConfigurations(); chgSizeMenuItem = new JMenuItem[configs.length]; for (GraphicsConfiguration config : configs) { Action a = new ChangeScreenResolution((JNodeGraphicsConfiguration) config); resMenu.add(new JMenuItem(a)); chgSizeMenuItem[i++] = new JMenuItem(a); } JMenu lfMenu = new JMenu("Look & Feel"); settingsMenu.add(lfMenu); UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels(); for (i = 0; i < lafs.length; ++i) { final UIManager.LookAndFeelInfo laf = lafs[i]; String name = laf.getName(); if (!"Metal".equals(name)) { JMenuItem item = new JMenuItem(name); item.addActionListener(new SetLFAction(laf)); lfMenu.add(item); } } //todo fix nimbus startup // JMenuItem nimbus = new JMenuItem("Nimbus"); // lfMenu.add(nimbus); // nimbus.addActionListener(new SetLFAction("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel") { // public void actionPerformed(ActionEvent e) { // super.actionPerformed(e); // } // }); JMenuItem metal_theme = new JMenuItem("Metal Default"); lfMenu.add(metal_theme); metal_theme.addActionListener(new SetLFAction("javax.swing.plaf.metal.MetalLookAndFeel") { public void actionPerformed(ActionEvent e) { MetalLookAndFeel.setCurrentTheme(new DefaultMetalTheme()); super.actionPerformed(e); } }); JMenuItem ocean_theme = new JMenuItem("Metal Ocean"); lfMenu.add(ocean_theme); ocean_theme.addActionListener(new SetLFAction("javax.swing.plaf.metal.MetalLookAndFeel") { public void actionPerformed(ActionEvent e) { MetalLookAndFeel.setCurrentTheme(new OceanTheme()); super.actionPerformed(e); } }); settingsMenu.add(desktopColorMI = new JMenuItem("Desktop color")); final JCheckBoxMenuItem desktopImage = new JCheckBoxMenuItem("Desktop image"); desktopImage.setSelected(false); desktopImage.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { desktop.enableBackgroundImage(desktopImage.isSelected()); } }); settingsMenu.add(desktopImage); JMenu exitMenu = new JMenu("Exit"); startMenu.add(exitMenu); exitMenu.add(quitMI = new JMenuItem("Quit")); exitMenu.add(restartMI = new JMenuItem("Restart")); exitMenu.add(haltMI = new JMenuItem("Halt")); windowBar = new WindowBar(); add(windowBar, BorderLayout.CENTER); clock = new Clock(); add(clock, BorderLayout.EAST); } private class SetLFAction implements ActionListener { private LookAndFeel lf; private final String lfName; public SetLFAction(UIManager.LookAndFeelInfo lfInfo) { this.lfName = lfInfo.getClassName(); } public SetLFAction(String lfName) { this.lfName = lfName; } public void actionPerformed(ActionEvent e) { if (lf == null) { try { Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(lfName); this.lf = (LookAndFeel) c.newInstance(); } catch (Exception ex) { log.error("Error crating look & feel " + lfName, ex); return; } } try { UIManager.setLookAndFeel(lf); } catch (UnsupportedLookAndFeelException ex) { log.error("", ex); return; } final Color bg_color = desktop.desktopPane.getBackground(); //TODO review this, Classpath plaf code is still instable failures can occure //so we try to minimise the effect of a failure try { SwingUtilities.updateComponentTreeUI(desktop.desktopFrame.getTopLevelRootComponent()); } catch (Exception x) { log.error("", x); } try { SwingUtilities.updateComponentTreeUI(startMenu); } catch (Exception x) { log.error("", x); } try { SwingUtilities.updateComponentTreeUI(desktop.desktopMenu); } catch (Exception x) { log.error("", x); } SwingUtilities.invokeLater(new Runnable() { public void run() { desktop.desktopPane.setBackground(bg_color); } }); } } class ChangeScreenResolution extends AbstractAction implements Runnable { private static final long serialVersionUID = 1L; private final JNodeGraphicsConfiguration config; public ChangeScreenResolution(JNodeGraphicsConfiguration config) { super("Set to " + config.toString()); this.config = config; } @Override public void run() { ((JNodeToolkit) Toolkit.getDefaultToolkit()).changeScreenSize(config); desktop.desktopFrame.getAwtRoot().repaint(); AccessController.doPrivileged(new SetPropertyAction("jnode.awt.screensize", config.toString())); } @Override public void actionPerformed(ActionEvent event) { SwingUtilities.invokeLater(this); } } private JMenuItem createMenuItem(final String label, final String classname) { final JMenuItem mi = new JMenuItem(label); mi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { startApp(label, classname, mi); } }); return mi; } final void startApp(final String name, final String className, final JMenuItem mi) { try { final Runnable runner = new Runnable() { public void run() { try { mi.setEnabled(false); final ClassLoader cl = Thread.currentThread().getContextClassLoader(); final Class<?> cls = cl.loadClass(className); final Method main = cls.getMethod("main", mainTypes); final Object[] args = {new String[0]}; main.invoke(null, args); mi.setEnabled(true); } catch (SecurityException ex) { log.error("Security exception in starting class " + className, ex); } catch (ClassNotFoundException ex) { log.error("Cannot find class " + className); } catch (NoSuchMethodException ex) { log.error("Cannot find main method in " + className); } catch (IllegalAccessException ex) { log.error("Cannot access main method in " + className); } catch (InvocationTargetException ex) { log.error("Error in " + className, ex.getTargetException()); } } }; final Thread t = new Thread(runner); t.start(); } catch (SecurityException ex) { log.error("Security exception in starting class " + className, ex); } } static class Clock extends JLabel { private static final long serialVersionUID = 1L; private Timer timer; private TimerTask task; Clock() { setBorder(new EmptyBorder(1, 1, 1, 5)); timer = new Timer(true); startTimer(); } public void setVisible(boolean v) { if (v) { if (task == null) { startTimer(); } } else { if (task != null) { task.cancel(); task = null; } } super.setVisible(v); } private void startTimer() { timer.schedule(task = new TimerTask() { Calendar calendar = new GregorianCalendar(); public void run() { calendar.setTimeInMillis(System.currentTimeMillis()); final int h = calendar.get(Calendar.HOUR_OF_DAY); final int m = calendar.get(Calendar.MINUTE); SwingUtilities.invokeLater(new Runnable() { public void run() { // insure that the modification of swing component // is done in the awt event dispatcher thread setText((h < 10 ? "0" : "") + h + ":" + (m < 10 ? "0" : "") + m); } }); } }, 0, 60 * 1000); } void stop() { timer.cancel(); } } }