Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

updated to use latest android ddm lib.

refactoring: moved dev oriented cmds to dev frame.
  • Loading branch information...
commit 536bc320614a6bd4a671d738b1ce74a4ca9571ac 1 parent cca694d
@ribomation authored
Showing with 483 additions and 127 deletions.
  1. +5 −5 .gitignore
  2. 0  README.md
  3. +2 −2 pom.xml
  4. +0 −3  src/main/java/com/ribomation/droidAtScreen/DroidAtScreenApplication.java
  5. +29 −2 src/main/java/com/ribomation/droidAtScreen/Settings.java
  6. +43 −0 src/main/java/com/ribomation/droidAtScreen/cmd/AskBeforeScreenshotCommand.java
  7. +39 −0 src/main/java/com/ribomation/droidAtScreen/cmd/CommandWithTarget.java
  8. +58 −0 src/main/java/com/ribomation/droidAtScreen/cmd/ImageDirectoryCommand.java
  9. +28 −28 src/main/java/com/ribomation/droidAtScreen/cmd/ScreenShotCommand.java
  10. +67 −59 src/main/java/com/ribomation/droidAtScreen/cmd/VideoCommand.java
  11. +7 −1 src/main/java/com/ribomation/droidAtScreen/dev/AndroidDevice.java
  12. +3 −4 src/main/java/com/ribomation/droidAtScreen/dev/AndroidDeviceManager.java
  13. +56 −0 src/main/java/com/ribomation/droidAtScreen/dev/OrientationCommand.java
  14. +97 −0 src/main/java/com/ribomation/droidAtScreen/dev/ScaleCommand.java
  15. +1 −1  src/main/java/com/ribomation/droidAtScreen/dev/ScreenImage.java
  16. +10 −12 src/main/java/com/ribomation/droidAtScreen/gui/ApplicationFrame.java
  17. +38 −10 src/main/java/com/ribomation/droidAtScreen/gui/DeviceFrame.java
  18. 0  src/main/resources/img/camera.png
  19. BIN  src/main/resources/img/folder.png
  20. 0  src/main/resources/img/jens-riboe.jpg
  21. 0  src/main/resources/img/quit.png
  22. BIN  src/main/resources/img/save.png
View
10 .gitignore 100644 → 100755
@@ -1,5 +1,5 @@
-target
-*.iml
-*.iws
-*.ipr
-.idea
+target
+*.iml
+*.iws
+*.ipr
+.idea
View
0  README.md 100644 → 100755
File mode changed
View
4 pom.xml 100644 → 100755
@@ -8,7 +8,7 @@
<groupId>com.ribomation</groupId>
<artifactId>droidAtScreen</artifactId>
<packaging>jar</packaging>
- <version>0.5.1</version>
+ <version>0.5.2.1</version>
<properties>
<app.class>com.ribomation.droidAtScreen.DroidAtScreenApplication</app.class>
@@ -30,7 +30,7 @@
<dependency>
<groupId>com.google.android.tools</groupId>
<artifactId>ddmlib</artifactId>
- <version>r10</version>
+ <version>r13</version>
</dependency>
<dependency>
View
3  src/main/java/com/ribomation/droidAtScreen/DroidAtScreenApplication.java
@@ -38,9 +38,6 @@
*/
public class DroidAtScreenApplication implements Application, AndroidDeviceListener {
private Logger log = Logger.getLogger(DroidAtScreenApplication.class);
-// private final String appPropertiesPath = "/META-INF/maven/com.ribomation/droidAtScreen/pom.properties";
-// private String appName = "Droid@Screen";
-// private String appVersion = "0.0";
private AndroidDeviceManager deviceManager;
private ApplicationFrame appFrame;
private Map<String, DeviceFrame> devices = new HashMap<String, DeviceFrame>();
View
31 src/main/java/com/ribomation/droidAtScreen/Settings.java
@@ -116,6 +116,32 @@ public void setImageFormat(String value) {
set("imageFormat", value);
}
+
+ public File getImageDirectory() {
+ String dir = applicationPreferences.get("imageDirectory", null);
+ if (dir != null) return new File(dir);
+ return new File(".");
+ }
+
+ public void setImageDirectory(File value) {
+ File oldDir = getImageDirectory();
+ applicationPreferences.put("imageDirectory", value.getAbsolutePath());
+ savePreferences();
+ propSupport.firePropertyChange("imageDirectory", oldDir, value);
+ }
+
+
+ public boolean isAskBeforeScreenshot() {
+ try {
+ return applicationPreferences.getBoolean("askBeforeScreenshot", true);
+ } catch (Exception e) { return false; }
+ }
+
+ public void setAskBeforeScreenshot(boolean value) {
+ set("askBeforeScreenshot", value);
+ }
+
+
private static final Integer[] scales = {25,50,75,100,125,150,175,200,250,300};
public Integer[] getScales() {
return scales;
@@ -184,14 +210,14 @@ public void setAutoShow(boolean value) {
private void set(String name, String value) {
- String old = applicationPreferences.get(name, "PNG");
+ String old = applicationPreferences.get(name, "");
applicationPreferences.put(name, value);
savePreferences();
propSupport.firePropertyChange(name, old, value);
}
private void set(String name, int value) {
- int old = applicationPreferences.getInt(name, 60);
+ int old = applicationPreferences.getInt(name, 0);
applicationPreferences.putInt(name, value);
savePreferences();
propSupport.firePropertyChange(name, old, value);
@@ -204,5 +230,6 @@ private void set(String name, boolean value) {
propSupport.firePropertyChange(name, old, value);
}
+
}
View
43 src/main/java/com/ribomation/droidAtScreen/cmd/AskBeforeScreenshotCommand.java
@@ -0,0 +1,43 @@
+/*
+ * Project: droidAtScreen
+ * File: AskBeforeScreenshotCommand.java
+ * Modified: 2012-01-03
+ *
+ * Copyright (C) 2011, Ribomation AB (Jens Riboe).
+ * http://blog.ribomation.com/
+ *
+ * You are free to use this software and the source code as you like.
+ * We do appreciate if you attribute were it came from.
+ */
+
+package com.ribomation.droidAtScreen.cmd;
+
+import com.ribomation.droidAtScreen.Application;
+
+/**
+ * Controls if a prompt should be shown before taking a screenshot.
+ *
+ * @user jens
+ * @date Fri Sep 30 2011, 10:53:52 CEST
+ */
+public class AskBeforeScreenshotCommand extends CheckBoxCommand {
+ public AskBeforeScreenshotCommand() {
+ setLabel("Ask Before Screenshot");
+ setTooltip("If you want to specify the filename before a screenshot, else it's generated.");
+ }
+
+ @Override
+ protected void notifyApplication(Application app, boolean selected) {
+ setPreferenceValue(selected);
+ }
+
+ @Override
+ protected boolean getPreferenceValue() {
+ return getApplication().getSettings().isAskBeforeScreenshot();
+ }
+
+ @Override
+ protected void setPreferenceValue(boolean value) {
+ getApplication().getSettings().setAskBeforeScreenshot(value);
+ }
+}
View
39 src/main/java/com/ribomation/droidAtScreen/cmd/CommandWithTarget.java
@@ -0,0 +1,39 @@
+/*
+ * Project: droidAtScreen
+ * File: CommandWithTarget.java
+ * Modified: 2012-03-22
+ *
+ * Copyright (C) 2011, Ribomation AB (Jens Riboe).
+ * http://blog.ribomation.com/
+ *
+ * You are free to use this software and the source code as you like.
+ * We do appreciate if you attribute were it came from.
+ */
+
+package com.ribomation.droidAtScreen.cmd;
+
+/**
+ * A command that is associated with a target object, which is the subject for the execution of the command.
+ * <p/>
+ * User: Jens
+ * Created: 2012-03-22, 22:13
+ */
+public abstract class CommandWithTarget<TargetType> extends Command {
+ private TargetType target;
+
+
+ protected CommandWithTarget(TargetType target) {
+ this.target = target;
+ }
+
+ protected CommandWithTarget(String name, TargetType target) {
+ super(name);
+ this.target = target;
+ }
+
+ public TargetType getTarget() {
+ return target;
+ }
+
+
+}
View
58 src/main/java/com/ribomation/droidAtScreen/cmd/ImageDirectoryCommand.java
@@ -0,0 +1,58 @@
+/*
+ * Project: droidAtScreen
+ * File: ImageDirectoryCommand.java
+ * Modified: 2012-01-03
+ *
+ * Copyright (C) 2011, Ribomation AB (Jens Riboe).
+ * http://blog.ribomation.com/
+ *
+ * You are free to use this software and the source code as you like.
+ * We do appreciate if you attribute were it came from.
+ */
+
+package com.ribomation.droidAtScreen.cmd;
+
+import com.ribomation.droidAtScreen.Application;
+
+import javax.swing.*;
+import java.io.File;
+
+/**
+ * Sets the default image dir, when saving screen-shots.
+ *
+ * @user jens
+ * @date 2012-01-03 09:20
+ */
+public class ImageDirectoryCommand extends Command {
+
+ public ImageDirectoryCommand() {
+ setLabel("Image Dir");
+ setIcon("folder");
+ updateView(getApplication().getSettings().getImageDirectory());
+ }
+
+ protected void updateView(File imageDirectory) {
+ setTooltip(String.format("Directory when saving screen-shots (%s)", imageDirectory.getName()));
+ }
+
+ @Override
+ protected void doExecute(Application app) {
+ File imageDirectory = app.getSettings().getImageDirectory();
+
+ final JFileChooser chooser = new JFileChooser(imageDirectory);
+ chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ int rc = chooser.showSaveDialog(app.getAppFrame());
+ if (rc != JFileChooser.APPROVE_OPTION) return;
+
+ imageDirectory = chooser.getSelectedFile();
+ if (!(imageDirectory.isAbsolute() && imageDirectory.canWrite())) {
+ JOptionPane.showMessageDialog(app.getAppFrame(),
+ "Not a writable directory '" + imageDirectory + "'", "Invalid directory", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+
+ app.getSettings().setImageDirectory(imageDirectory);
+ updateView(imageDirectory);
+ }
+
+}
View
56 src/main/java/com/ribomation/droidAtScreen/cmd/ScreenShotCommand.java
@@ -13,6 +13,7 @@
package com.ribomation.droidAtScreen.cmd;
import com.ribomation.droidAtScreen.Application;
+import com.ribomation.droidAtScreen.Settings;
import com.ribomation.droidAtScreen.dev.AndroidDevice;
import com.ribomation.droidAtScreen.dev.ScreenImage;
import com.ribomation.droidAtScreen.gui.DeviceFrame;
@@ -30,7 +31,6 @@
* @date 30 september 2011, 14:19
*/
public class ScreenShotCommand extends Command {
- private File lastDir = null;
private int count = 1;
public ScreenShotCommand() {
@@ -45,35 +45,38 @@ protected void doExecute(final Application app) {
final DeviceFrame device = app.getSelectedDevice();
if (device == null) return;
- File suggestedFile = new File(String.format("droidAtScreen-%d.%s", count++, app.getSettings().getImageFormat().toLowerCase()));
-
- final JFileChooser chooser = new JFileChooser(lastDir);
- chooser.setCurrentDirectory(null);
- chooser.setSelectedFile(suggestedFile);
- chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
- chooser.addChoosableFileFilter(new FileNameExtensionFilter("Image Files", app.getSettings().getImageFormats()));
-
- int rc = chooser.showSaveDialog(app.getAppFrame());
- if (rc != JFileChooser.APPROVE_OPTION) return;
-
-
- final File imageFile = chooser.getSelectedFile();
- lastDir = imageFile.getParentFile();
-
+ final Settings settings = app.getSettings();
+
+ File suggestedFile = new File(String.format("droidAtScreen-%d.%s", count++, settings.getImageFormat().toLowerCase()));
+ if (settings.isAskBeforeScreenshot()) {
+ final JFileChooser chooser = new JFileChooser();
+ chooser.setCurrentDirectory(settings.getImageDirectory());
+ chooser.setSelectedFile(suggestedFile);
+ chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ chooser.addChoosableFileFilter(new FileNameExtensionFilter("Image Files", settings.getImageFormats()));
+
+ int rc = chooser.showSaveDialog(app.getAppFrame());
+ if (rc != JFileChooser.APPROVE_OPTION) return;
+
+ suggestedFile = chooser.getSelectedFile();
+ }
+
+ if (suggestedFile.exists()) {
+ int rc = JOptionPane.showConfirmDialog(app.getAppFrame(),
+ "File '" + suggestedFile + "' already exist. Do you want to overwrite?",
+ "Overwrite file",
+ JOptionPane.YES_NO_OPTION);
+ if (rc != JOptionPane.YES_OPTION) return;
+ }
+
+ final File imageFile = suggestedFile;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
- if (imageFile.exists()) {
- int rc = JOptionPane.showConfirmDialog(app.getAppFrame(),
- "File '" + imageFile + "' already exist. Do you want to overwrite?",
- "Overwrite file",
- JOptionPane.YES_NO_OPTION);
- if (rc != JOptionPane.YES_OPTION) return;
- }
-
ScreenImage screenShot = device.getLastScreenshot();
ImageIO.write(screenShot.toBufferedImage(), getFormat(imageFile), imageFile);
+ app.getAppFrame().getStatusBar().message("Written", imageFile.getAbsolutePath());
} catch (Exception e) {
JOptionPane.showMessageDialog(app.getAppFrame(),
"Failed to save file " + imageFile + ". " + e.getMessage(),
@@ -87,11 +90,8 @@ String getFormat(File f) {
final int dot = name.lastIndexOf('.');
if (dot > 0) {
String ext = name.substring(dot + 1).toUpperCase();
- if (Arrays.asList(app.getSettings().getImageFormats()).contains(ext)) {
- return ext;
- }
+ if (Arrays.asList(settings.getImageFormats()).contains(ext)) return ext;
}
-
throw new RuntimeException("Invalid extension: " + name);
}
});
View
126 src/main/java/com/ribomation/droidAtScreen/cmd/VideoCommand.java
@@ -13,6 +13,7 @@
package com.ribomation.droidAtScreen.cmd;
import com.ribomation.droidAtScreen.Application;
+import com.ribomation.droidAtScreen.Settings;
import com.ribomation.droidAtScreen.dev.RecordingListener;
import com.ribomation.droidAtScreen.dev.ScreenImage;
import com.ribomation.droidAtScreen.gui.DeviceFrame;
@@ -34,12 +35,11 @@
* @user jens
* @date 2010-jan-18 10:35:20
*/
-public class VideoCommand extends Command implements Runnable, RecordingListener {
- private File lastDir;
- private AtomicInteger count = new AtomicInteger(1);
- private AtomicBoolean capturing = new AtomicBoolean(false);
- private BlockingQueue<ScreenImage> imageQueue = new LinkedBlockingQueue<ScreenImage>(120);
- private Thread runner;
+public class VideoCommand extends Command implements RecordingListener {
+ private AtomicInteger count = new AtomicInteger(1);
+ private AtomicBoolean capturing = new AtomicBoolean(false);
+ private BlockingQueue<ScreenImage> imageQueue = new LinkedBlockingQueue<ScreenImage>(120);
+ private Thread runner;
public VideoCommand() {
setLabel("Record");
@@ -59,30 +59,35 @@ protected void doExecute(Application app) {
return;
}
- JFileChooser chooser = new JFileChooser();
- chooser.setCurrentDirectory(lastDir);
- chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
- chooser.setDialogTitle("Select target directory for the images");
- chooser.setApproveButtonText("Images Dir");
- chooser.setApproveButtonToolTipText("All screen-shots will go into this directory, sequentially numbered.");
-
- int rc = chooser.showOpenDialog(app.getAppFrame());
- if (rc != JFileChooser.APPROVE_OPTION) return;
-
- File dir = chooser.getSelectedFile();
- if (!(dir.isAbsolute() && dir.canWrite())) {
- JOptionPane.showMessageDialog(app.getAppFrame(),
- "Not a writable directory " + dir, "Invalid directory", JOptionPane.ERROR_MESSAGE);
- return;
+ final Settings settings = app.getSettings();
+
+ File imageDir = new File(".");
+ if (settings.isAskBeforeScreenshot()) {
+ JFileChooser chooser = new JFileChooser();
+ chooser.setCurrentDirectory(app.getSettings().getImageDirectory());
+ chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ chooser.setDialogTitle("Select target directory for the images");
+ chooser.setApproveButtonText("Images Dir");
+ chooser.setApproveButtonToolTipText("All screen-shots will go into this directory, sequentially numbered.");
+
+ int rc = chooser.showOpenDialog(app.getAppFrame());
+ if (rc != JFileChooser.APPROVE_OPTION) return;
+
+ imageDir = chooser.getSelectedFile();
+ if (!(imageDir.isAbsolute() && imageDir.canWrite())) {
+ JOptionPane.showMessageDialog(app.getAppFrame(),
+ "Not a writable directory " + imageDir, "Invalid directory", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
}
- boolean notEmpty = dir.listFiles(new FileFilter() {
+ boolean notEmpty = imageDir.listFiles(new FileFilter() {
public boolean accept(File f) {
return f.isFile();
}
}).length > 0;
if (notEmpty) {
- rc = JOptionPane.showConfirmDialog(app.getAppFrame(),
+ int rc = JOptionPane.showConfirmDialog(app.getAppFrame(),
"The chosen directory is not empty. \n" +
"Do you still want to proceed and possibly \n" +
"overwrite some/all of previously saved screen-shots?",
@@ -91,16 +96,51 @@ public boolean accept(File f) {
if (rc != JOptionPane.YES_OPTION) return;
}
- lastDir = dir;
+ final File destinationDir = imageDir;
+ Runnable task = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ while (capturing.get()) {
+ ScreenImage image = imageQueue.take();
+ String format = getApplication().getSettings().getImageFormat();
+ File file = new File(destinationDir, String.format("droidAtScreen-%d.%s", count.getAndIncrement(), format.toLowerCase()));
+
+ ImageIO.write(image.toBufferedImage(), format, file);
+ getLog().debug("written " + file);
+ }
+ } catch (InterruptedException ignore) {
+ return;
+ } catch (IOException e) {
+ getLog().error("Failed to write image to " + destinationDir, e);
+ return;
+ } finally {
+ getLog().info("Continuous screen capture recording stopped, count=" + count.get());
+ capturing.set(false);
+ imageQueue.clear();
+ final int oldCount = count.getAndSet(1) - 1;
+ runner = null;
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ setIcon("record");
+ getApplication().getAppFrame().getStatusBar().message("Recording stopped. %d images saved.", oldCount);
+ }
+ });
+ }
+ }
+ };
+
+
setIcon("recording");
imageQueue.clear();
capturing.set(true);
count.set(1);
- runner = new Thread(this);
+ runner = new Thread(task);
runner.start();
device.setRecordingListener(this);
- getLog().info("Continuous screen capture recording started, dir=" + lastDir.getAbsolutePath());
- app.getAppFrame().getStatusBar().message("Recording to %s", truncate(lastDir.getAbsolutePath(), 30));
+ getLog().info("Continuous screen capture recording started, dir=" + imageDir.getAbsolutePath());
+ app.getAppFrame().getStatusBar().message("Recording to %s", truncate(imageDir.getAbsolutePath(), 30));
}
public void record(ScreenImage image) {
@@ -110,38 +150,6 @@ public void record(ScreenImage image) {
}
}
- public void run() {
- try {
- while (capturing.get()) {
- ScreenImage image = imageQueue.take();
- String format = getApplication().getSettings().getImageFormat();
- File file = new File(lastDir, String.format("droidAtScreen-%d.%s",
- count.getAndIncrement(), format.toLowerCase()));
-
- ImageIO.write(image.toBufferedImage(), format, file);
- getLog().debug("written " + file);
- }
- } catch (InterruptedException ignore) {
- return;
- } catch (IOException e) {
- getLog().error("Failed to write image to " + lastDir, e);
- return;
- } finally {
- getLog().info("Continuous screen capture recording stopped, count=" + count.get());
- capturing.set(false);
- imageQueue.clear();
- final int oldCount = count.getAndSet(1) - 1;
- runner = null;
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- setIcon("record");
- getApplication().getAppFrame().getStatusBar().message("Recording stopped. %d images saved.", oldCount);
- }
- });
- }
- }
-
private String truncate(String s, int max) {
int n = s.length();
return (n > max ? "..." : "") + s.substring((n - max) < 0 ? 0 : n - max);
View
8 src/main/java/com/ribomation/droidAtScreen/dev/AndroidDevice.java
@@ -61,9 +61,15 @@ public ScreenImage getScreenImage() {
// log.debug(String.format("Captured %s in %.4f secs", image, elapsed / SECS));
return image;
- } catch (Exception e) {
+ } catch (IOException e) {
log.error("Failed to get screenshot: " + e);
throw new RuntimeException("Failed to get screenshot", e);
+ } catch (TimeoutException e) {
+ log.warn("Got timeout");
+ return null;
+ } catch (AdbCommandRejectedException e) {
+ log.error("ADB command rejected: OFFLINE=" + e.isDeviceOffline());
+ throw new RuntimeException(e);
}
}
View
7 src/main/java/com/ribomation/droidAtScreen/dev/AndroidDeviceManager.java
@@ -13,16 +13,15 @@
package com.ribomation.droidAtScreen.dev;
import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Client;
import com.android.ddmlib.IDevice;
import com.ribomation.droidAtScreen.Application;
-import com.ribomation.droidAtScreen.DroidAtScreenApplication;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
/**
* A facade to AndroidDebugBridge.
@@ -73,7 +72,7 @@ public void createBridge() {
}
try {
- AndroidDebugBridge.createBridge(getAdbExecutable().getCanonicalPath(), false);
+ AndroidDebugBridge.createBridge(getAdbExecutable().getCanonicalPath(), true);
log.info("Connected to ADB via " + getSocketAddress());
} catch (IOException e) {
throw new RuntimeException("Failed to created the absolute path to the ADB executable: " + getAdbExecutable());
View
56 src/main/java/com/ribomation/droidAtScreen/dev/OrientationCommand.java
@@ -0,0 +1,56 @@
+/*
+ * Project: droidAtScreen
+ * File: OrientationCommand.java
+ * Modified: 2012-03-22
+ *
+ * Copyright (C) 2011, Ribomation AB (Jens Riboe).
+ * http://blog.ribomation.com/
+ *
+ * You are free to use this software and the source code as you like.
+ * We do appreciate if you attribute were it came from.
+ */
+
+package com.ribomation.droidAtScreen.dev;
+
+import com.ribomation.droidAtScreen.Application;
+import com.ribomation.droidAtScreen.cmd.CommandWithTarget;
+import com.ribomation.droidAtScreen.gui.DeviceFrame;
+
+import javax.swing.*;
+
+/**
+ * Flips the device-frame 90 degrees.
+ * <p/>
+ * User: Jens
+ * Created: 2012-03-22, 22:18
+ */
+public class OrientationCommand extends CommandWithTarget<DeviceFrame> {
+
+ public OrientationCommand(DeviceFrame deviceFrame) {
+ super(deviceFrame);
+ updateLabelAndIcon(deviceFrame);
+ setTooltip("Flip the orientation (portrait | landscape)");
+ }
+
+ @Override
+ protected void doExecute(Application app) {
+ DeviceFrame deviceFrame = getTarget();
+ deviceFrame.setLandscapeMode(!deviceFrame.isLandscapeMode());
+ updateLabelAndIcon(deviceFrame);
+ deviceFrame.validate();
+ }
+
+ private void updateLabelAndIcon(DeviceFrame deviceFrame) {
+ setLabel(deviceFrame.isLandscapeMode() ? "Landscape" : "Portrait ");
+ setIcon("orientation-" + getLabel().toLowerCase().trim());
+ }
+
+ @Override
+ public AbstractButton newButton() {
+ JToggleButton b = new JToggleButton(this);
+ b.setVerticalTextPosition(AbstractButton.BOTTOM);
+ b.setHorizontalTextPosition(AbstractButton.CENTER);
+ b.setSelected(true);
+ return b;
+ }
+}
View
97 src/main/java/com/ribomation/droidAtScreen/dev/ScaleCommand.java
@@ -0,0 +1,97 @@
+/*
+ * Project: droidAtScreen
+ * File: ScaleCommand.java
+ * Modified: 2012-03-22
+ *
+ * Copyright (C) 2011, Ribomation AB (Jens Riboe).
+ * http://blog.ribomation.com/
+ *
+ * You are free to use this software and the source code as you like.
+ * We do appreciate if you attribute were it came from.
+ */
+
+package com.ribomation.droidAtScreen.dev;
+
+import com.ribomation.droidAtScreen.Application;
+import com.ribomation.droidAtScreen.cmd.CommandWithTarget;
+import com.ribomation.droidAtScreen.gui.DeviceFrame;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * Set the device frame projection scale, as a percentage.
+ * <p/>
+ * User: Jens
+ * Created: 2012-03-22, 22:18
+ */
+public class ScaleCommand extends CommandWithTarget<DeviceFrame> {
+
+ public ScaleCommand(DeviceFrame deviceFrame) {
+ super(deviceFrame);
+ setIcon("zoom");
+ setTooltip("Sets the projection scale % of the Android Device. 100% is normal size");
+ setMnemonic('Q');
+ updateLabel(deviceFrame);
+ }
+
+ @Override
+ protected void doExecute(Application app) {
+ final DeviceFrame deviceFrame = getTarget();
+ final JDialog dialog = new JDialog(app.getAppFrame(), "Set the Device Frame Scale", true);
+
+ ActionListener action = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ dialog.dispose();
+ int percentage = Integer.parseInt( e.getActionCommand() );
+ deviceFrame.setScale(percentage);
+ updateLabel(deviceFrame);
+ deviceFrame.validate();
+ }
+ };
+
+ JPanel scalePane = createScalePane(action);
+ dialog.setContentPane(new JOptionPane(scalePane, JOptionPane.QUESTION_MESSAGE));
+ dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ dialog.pack();
+ dialog.setLocationByPlatform(true);
+ dialog.setVisible(true);
+ }
+
+ private void updateLabel(DeviceFrame deviceFrame) {
+ setLabel(String.format("Scale (%d%%)", deviceFrame.getScale()));
+ }
+
+ @Override
+ public AbstractButton newButton() {
+ JToggleButton b = new JToggleButton(this);
+ b.setVerticalTextPosition(AbstractButton.BOTTOM);
+ b.setHorizontalTextPosition(AbstractButton.CENTER);
+ b.setSelected(true);
+ return b;
+ }
+
+ private JPanel createScalePane(ActionListener action) {
+ JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ p.setBorder( BorderFactory.createTitledBorder("Projection Scale") );
+ ButtonGroup scale = new ButtonGroup();
+ for (int s : getApplication().getSettings().getScales()) {
+ JRadioButton rb = createScaleRadioButton(s, action);
+ scale.add(rb);
+ p.add(rb);
+ }
+ return p;
+ }
+
+ private JRadioButton createScaleRadioButton(int percentage, ActionListener action) {
+ JRadioButton r = new JRadioButton(percentage + "%");
+ r.setActionCommand( Integer.toString(percentage) );
+ r.addActionListener(action);
+ r.setSelected(percentage == getTarget().getScale());
+ return r;
+ }
+
+}
View
2  src/main/java/com/ribomation/droidAtScreen/dev/ScreenImage.java
@@ -36,7 +36,7 @@ public RawImage getRawImage() {
public BufferedImage toBufferedImage() {
final int W = rawImage.width;
final int H = rawImage.height;
- BufferedImage image = new BufferedImage(W, H, BufferedImage.TYPE_INT_ARGB);
+ BufferedImage image = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB);
int bytesPerPixels = rawImage.bpp >> 3; //bpp = bits / pixels --> bytes / pixels
for (int y = 0, pixelIdx = 0; y < H; y++) {
View
22 src/main/java/com/ribomation/droidAtScreen/gui/ApplicationFrame.java
@@ -36,18 +36,15 @@
private DefaultComboBoxModel deviceListModel = new DefaultComboBoxModel();
private StatusBar statusBar;
- private final String[] TOOLBAR = {"Orientation", "Scale", "-", "ScreenShot", "Video", "-", "AdbRestart"};
- private final String[] FILE_MENU = {"ScreenShot", "Video", "-", "Quit"};
- private final String[] VIEW_MENU = {"Orientation", "Scale", "UpsideDown"};
- private final String[] ADB_MENU = {"AdbRestart", "AdbReloadDevices", "AdbExePath"};
- private final String[] HELP_MENU = {"About"};
- private final String[] OPTIONS_MENU = {
- "ImageFormat", "FrameRate",
- "-", "AutoShow", "SkipEmulator", "AskBeforeQuit",
- "-", "LookAndFeel", "-", "RemoveProperties"
- };
-
-
+ private final String[] TOOLBAR = {/*"Orientation",*/ /*"Scale", "-",*/ "ImageDirectory", "ScreenShot", "Video", "-", "About"};
+ private final String[] FILE_MENU = {"Quit"};
+ private final String[] IMAGE_MENU = {"ImageDirectory", "ImageFormat", "AskBeforeScreenshot", "-", "ScreenShot", "Video"};
+ private final String[] VIEW_MENU = {"Orientation", "Scale", "UpsideDown"};
+ private final String[] ADB_MENU = {"AdbRestart", "AdbReloadDevices", "AdbExePath"};
+ private final String[] OPTIONS_MENU = {"FrameRate", "-", "AutoShow", "SkipEmulator", "AskBeforeQuit", "-", "LookAndFeel", "-", "RemoveProperties"};
+ private final String[] HELP_MENU = {"About"};
+
+
public ApplicationFrame(Application app) throws HeadlessException {
this.app = app;
}
@@ -78,6 +75,7 @@ public void windowClosing(WindowEvent e) {
protected JMenuBar createMenubar() {
JMenuBar mb = new JMenuBar();
mb.add(GuiUtil.createMenu("File" , 'F', FILE_MENU));
+ mb.add(GuiUtil.createMenu("Image" , 'I', IMAGE_MENU));
mb.add(GuiUtil.createMenu("View" , 'V', VIEW_MENU));
mb.add(GuiUtil.createMenu("ADB" , 'A', ADB_MENU));
mb.add(GuiUtil.createMenu("Options", 'O', OPTIONS_MENU));
View
48 src/main/java/com/ribomation/droidAtScreen/gui/DeviceFrame.java
@@ -15,13 +15,11 @@
import com.ribomation.droidAtScreen.Application;
import com.ribomation.droidAtScreen.cmd.Command;
import com.ribomation.droidAtScreen.cmd.FrameRateCommand;
-import com.ribomation.droidAtScreen.dev.AndroidDevice;
-import com.ribomation.droidAtScreen.dev.RecordingListener;
-import com.ribomation.droidAtScreen.dev.ScreenImage;
-import com.ribomation.droidAtScreen.dev.ScreenshotTimer;
+import com.ribomation.droidAtScreen.dev.*;
import org.apache.log4j.Logger;
import javax.swing.*;
+import javax.swing.border.BevelBorder;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
@@ -50,9 +48,10 @@
private boolean upsideDown = false;
private boolean visibleEnabled = false;
+ private ImageCanvas canvas;
+ private JToolBar toolBar;
private ScreenImage lastScreenshot;
private ScreenshotTimer timer;
- private ImageCanvas canvas;
private AffineTransform scaleTX;
private AffineTransform upsideDownTX;
private RecordingListener recordingListener;
@@ -72,10 +71,10 @@ public DeviceFrame(Application app, AndroidDevice device, boolean landscape, boo
setResizable(false);
setIconImage(GuiUtil.loadIcon("device").getImage());
- canvas = new ImageCanvas();
setTitle(device.getName());
- add(canvas, BorderLayout.CENTER);
+ add(canvas = new ImageCanvas(), BorderLayout.CENTER);
+ add(toolBar = createToolBar(), BorderLayout.WEST);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@@ -88,7 +87,24 @@ public void windowClosing(WindowEvent e) {
}
});
}
+
+ protected JToolBar createToolBar() {
+ JToolBar tb = new JToolBar("Commands", JToolBar.VERTICAL);
+ tb.setFloatable(false);
+ tb.setRollover(true);
+ tb.setMargin(new Insets(5,5,5,5));
+ tb.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
+
+ tb.add(new OrientationCommand(this).newButton());
+ tb.add(new ScaleCommand(this).newButton());
+
+ return tb;
+ }
+
+
+
+
public AndroidDevice getDevice() { return device; }
public String getName() { return device.getName(); }
@@ -114,10 +130,12 @@ public void setVisible(boolean show) {
setVisibleEnabled(false);
}
- private void updateSize(int width, int height) {
+ private void updateSize(int imgWidth, int imgHeight) {
Insets margins = getInsets();
- Dimension frameSize = new Dimension(margins.left + scale(width) + margins.right,
- margins.top + scale(height) + margins.bottom);
+ Dimension tbSize = toolBar.getSize();
+ Dimension frameSize = new Dimension(
+ margins.left + tbSize.width + scale(imgWidth) + margins.right,
+ margins.top + scale(imgHeight) + margins.bottom);
Dimension currentSize = getSize();
if (!currentSize.equals(frameSize)) {
@@ -158,6 +176,8 @@ protected void paintComponent(Graphics g) {
}
public void setLastScreenshot(ScreenImage image) {
+ if (image == null) return;
+
lastScreenshot = image;
if (landscapeMode) lastScreenshot.rotate();
@@ -186,6 +206,10 @@ public void setLandscapeMode(boolean landscape) {
this.landscapeMode = landscape;
}
+ public boolean isLandscapeMode() {
+ return landscapeMode;
+ }
+
public void setScale(int scalePercentage) {
this.scalePercentage = scalePercentage;
if (scalePercentage == 100) {
@@ -196,6 +220,10 @@ public void setScale(int scalePercentage) {
}
}
+ public int getScale() {
+ return scalePercentage;
+ }
+
public void setUpsideDown(boolean upsideDown) {
this.upsideDown = upsideDown;
if (upsideDown && lastScreenshot != null) {
View
0  src/main/resources/img/camera.png 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  src/main/resources/img/folder.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0  src/main/resources/img/jens-riboe.jpg 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0  src/main/resources/img/quit.png 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  src/main/resources/img/save.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Please sign in to comment.
Something went wrong with that request. Please try again.