/******************************************************************************* * Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html * * Contributors: * Mathew A. Nelson * - Initial API and implementation * Flemming N. Larsen * - Code cleanup * - Replaced FileSpecificationVector with plain Vector * - Replaced deprecated show() method with setVisible(true) * - Updated to use methods from the FileUtil, which replaces file operations * that have been (re)moved from the robocode.util.Utils class * - Changed to use FileUtil.getRobotsDir() * - Fixed the layout, where the filename field was too high * - Showing the frame is now performed in the Swing Event Thread * Robert D. Maupin * - Replaced old collection types like Vector and Hashtable with * synchronized List and HashMap *******************************************************************************/ package net.sf.robocode.ui.packager; import net.sf.robocode.io.FileUtil; import net.sf.robocode.io.Logger; import net.sf.robocode.repository.IRepositoryItem; import net.sf.robocode.ui.dialog.WizardPanel; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.Caret; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.List; /** * @author Mathew A. Nelson (original) * @author Flemming N. Larsen (contributor) * @author Robert D. Maupin (contributor) */ @SuppressWarnings("serial") public class FilenamePanel extends WizardPanel { private final RobotPackager robotPackager; private final EventHandler eventHandler = new EventHandler(); private boolean robocodeErrorShown; private JButton browseButton; private JTextField filenameField; private class EventHandler implements ActionListener, DocumentListener, ComponentListener { public void insertUpdate(DocumentEvent e) { fireStateChanged(); } public void changedUpdate(DocumentEvent e) { fireStateChanged(); } public void removeUpdate(DocumentEvent e) { fireStateChanged(); } public void actionPerformed(ActionEvent e) { if (e.getSource() == getBrowseButton()) { showFileSelectDialog(); } } public void componentMoved(ComponentEvent e) {} public void componentResized(ComponentEvent e) {} public void componentHidden(ComponentEvent e) {} public void componentShown(ComponentEvent e) { String fileName = FileUtil.getRobotsDir().getAbsolutePath() + File.separator; File outgoingFile = new File(fileName); if (!outgoingFile.exists()) { if (!outgoingFile.mkdirs()) { Logger.logError("Cannot create: " + outgoingFile); } } String jarName = "myrobots.jar"; List<IRepositoryItem> selectedRobots = robotPackager.getRobotSelectionPanel().getSelectedRobots(); if (selectedRobots != null && selectedRobots.size() == 1) { jarName = selectedRobots.get(0).getFullClassName() + "_" + robotPackager.getPackagerOptionsPanel().getVersionField().getText() + ".jar"; } getFilenameField().setText(fileName + jarName); Caret caret = getFilenameField().getCaret(); caret.setDot(fileName.length()); caret.moveDot(fileName.length() + jarName.length() - 4); getFilenameField().requestFocus(); } } public FilenamePanel(RobotPackager robotPackager) { super(); this.robotPackager = robotPackager; initialize(); } private void initialize() { setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); addComponentListener(eventHandler); GridBagLayout layout = new GridBagLayout(); setLayout(layout); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(5, 5, 5, 5); c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = 1; c.weightx = 1; add(new JLabel("Please type in a .jar file to save this robot package to: "), c); c.gridy = 1; add(getFilenameField(), c); c.fill = GridBagConstraints.NONE; c.gridy = 2; c.insets = new Insets(3, 3, 3, 3); add(getBrowseButton(), c); c.fill = GridBagConstraints.VERTICAL; c.weighty = 1; c.gridy = 3; add(new JPanel(), c); } @Override public boolean isReady() { if (filenameField.getText() == null) { return false; } int robocodeIndex = filenameField.getText().lastIndexOf(File.separatorChar); if (robocodeIndex > 0) { if (filenameField.getText().substring(robocodeIndex + 1).indexOf("robocode") == 0) { if (!robocodeErrorShown) { robocodeErrorShown = true; new Thread(new Runnable() { public void run() { JOptionPane.showMessageDialog(FilenamePanel.this, "Filename cannot begin with robocode"); } }).start(); } return false; } } return (filenameField.getText().toLowerCase().indexOf(".jar") != 0); } public static void main(String[] args) { JFrame frame = new JFrame("options"); frame.setSize(new Dimension(500, 300)); frame.getContentPane().add(new FilenamePanel(null)); try { SwingUtilities.invokeAndWait(new ShowFrameWorker(frame)); } catch (InterruptedException e) { // Immediately reasserts the exception by interrupting the caller thread itself Thread.currentThread().interrupt(); e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } public JButton getBrowseButton() { if (browseButton == null) { browseButton = new JButton("Browse"); browseButton.addActionListener(eventHandler); } return browseButton; } public JTextField getFilenameField() { if (filenameField == null) { filenameField = new JTextField("(none selected)", 60); filenameField.getDocument().addDocumentListener(eventHandler); } return filenameField; } public void showFileSelectDialog() { File f = new File("outgoing" + File.separatorChar); JFileChooser chooser = new JFileChooser(f); chooser.setCurrentDirectory(f); javax.swing.filechooser.FileFilter filter = new javax.swing.filechooser.FileFilter() { @Override public boolean accept(File pathname) { if (pathname.isDirectory()) { return true; } String fn = pathname.getName(); int idx = fn.lastIndexOf('.'); String extension = ""; if (idx >= 0) { extension = fn.substring(idx); } return extension.equalsIgnoreCase(".jar"); } @Override public String getDescription() { return "JAR files"; } }; chooser.setFileFilter(filter); boolean done = false; while (!done) { done = true; int rv = chooser.showSaveDialog(this); String robotFileName; if (rv == JFileChooser.APPROVE_OPTION) { robotFileName = chooser.getSelectedFile().getPath(); if (robotFileName.toLowerCase().indexOf(".jar") < 0) { robotFileName += ".jar"; } File outFile = new File(robotFileName); if (outFile.exists()) { int ok = JOptionPane.showConfirmDialog(this, robotFileName + " already exists. Are you sure you want to replace it?", "Warning", JOptionPane.YES_NO_CANCEL_OPTION); if (ok == JOptionPane.NO_OPTION) { done = false; continue; } if (ok == JOptionPane.CANCEL_OPTION) { return; } } getFilenameField().setText(robotFileName); fireStateChanged(); } } } static class ShowFrameWorker implements Runnable { final JFrame frame; public ShowFrameWorker(JFrame frame) { this.frame = frame; } public void run() { if (frame != null) { frame.setVisible(true); } } } }