Subscribe to Grim's Projects        RSS Feed
-----

Imagemagick for your Linux Wallpaper

Icon 6 Comments
So I've been using Arch Linux as my distro of choice. I'll tell you why with a screenshot:
Attached Image
The setup has been involved, so it definitely wasn't fun (at first). However, I have learned quite a bit. For instance, before, I was using an ethernet bridge since I hadn't been able to determine how to set up the PCMCIA card. I guess once one thing makes sense, more things start to make sense and I was able to set up and get the PCMCIA card working (that was also a headache). However, I digress.

One of the, let's call it "novice" techniques I was using was trying to find specific software that would do what I wanted on my machine. For instance, I had used a neat application called nitrogen for managing my wallpapers, and secondly an application called scrot for taking screenshots. They're good, lightweight apps for doing so, readily available from the repository.

For image manipulation I would use imagemagick's convert command line utility. Recently, I figured out it will also take screenshots and you can set your wallpaper with it. Linux just keeps getting better and better. This meant I wouldn't need nitrogen or scrot anymore. The only issue is that imagemagick's command line can get fairly cryptic, which I didn't much like. Furthermore, to be very much a non-geek, I just happen to prefer GUIs for things like this as opposed to command line.

I didn't want to bother with having to try and remind myself or decipher what the proper command would be each time I wanted to change my wallpaper (as I don't do it frequently). So I decided I would code a Java application to do this tedious work for me. I hate when I get an idea like this because it always turns out to be more work than I naively thought beforehand.

So here's what I wanted the application to do for me: allow me to pick a wallpaper, select how I want the wallpaper applied (stretched, cropped or padded), then execute the relevant imagemagick command. Here is what I've coded so far:

Wallmagick.java
/* 
 * Icons taken from http://p.yusukekamiyamane.com/
 * http://www.iconarchive.com/show/fugue-icons-by-yusuke-kamiyamane/document-image-icon.html
 */

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JWindow;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.JRadioButton;
import javax.swing.BorderFactory;
import javax.swing.border.TitledBorder;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.GraphicsEnvironment;
import java.awt.GraphicsDevice;
import java.awt.DisplayMode;
import java.awt.Window;

import java.io.InputStream;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.util.Properties;

public class Wallmagick {

	public static final double REQUIRED_JVM_VERSION = 1.7;

	public static final String CONFIGURATION_FILENAME = "config.xml";

	// Wallpaper display styles
	public static final String STRETCH = "Stretch";
	public static final String PAD = "Pad";
	public static final String CROP = "Crop";

	private static void createAndShowGUI(Properties configuration) {
		// Create left panel with 5 radio buttons for display style of wallpaper
		JRadioButton stretchButton = new JRadioButton(STRETCH);
		JRadioButton padButton = new JRadioButton(PAD);
		JRadioButton cropButton = new JRadioButton(CROP);
		
		StyleSetter styleListener = new StyleSetter(configuration);
		stretchButton.addActionListener(styleListener);
		padButton.addActionListener(styleListener);
		cropButton.addActionListener(styleListener);

		switch (configuration.getProperty("style")) {
		case STRETCH:
			stretchButton.setSelected(true);
			break;
		case PAD:
			padButton.setSelected(true);
			break;
		case CROP:
			cropButton.setSelected(true);
			break;
		}

		ButtonGroup displayRadioButtons = new ButtonGroup();

		displayRadioButtons.add(stretchButton);
		displayRadioButtons.add(padButton);
		displayRadioButtons.add(cropButton);

		TitledBorder titledBorder = BorderFactory.createTitledBorder("Display");

		JPanel leftPanel = new JPanel(new GridLayout(0, 1));

		leftPanel.add(stretchButton);
		leftPanel.add(padButton);
		leftPanel.add(cropButton);

		leftPanel.setBorder(titledBorder);

		// Create right panel button with two standard buttons
		JButton wallpaperButton = new JButton("Wallpaper");
		wallpaperButton.setAlignmentX(Component.CENTER_ALIGNMENT);

		JButton applyButton = new JButton("Apply");
		applyButton.setAlignmentX(Component.CENTER_ALIGNMENT);
	
		// Set wallpaper using imagemagick's display command
		applyButton.addActionListener(new WallpaperSetter(configuration));

		JPanel rightPanel = new JPanel();
		rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));

		rightPanel.add(Box.createVerticalGlue());
		rightPanel.add(wallpaperButton);
		rightPanel.add(applyButton);
		rightPanel.add(Box.createVerticalGlue());

		// Load application icon
		String iconFile = configuration.getProperty("config.path");
		iconFile += configuration.getProperty("file.separator");
		iconFile += "document-image-icon.png";
		ImageIcon icon = new ImageIcon(iconFile);

		JInternalFrame frame = new JInternalFrame("Wallmagick", false, true, false, false);
		frame.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
		frame.getContentPane().add(leftPanel, BorderLayout.WEST);
		frame.getContentPane().add(rightPanel, BorderLayout.CENTER);
		frame.setFrameIcon(icon);
		frame.pack();
		frame.setVisible(true);
		
		frame.addInternalFrameListener(new InternalFrameAdapter() {
		    public void internalFrameClosed(InternalFrameEvent e) {
		    	for(Window windows : window.getWindows()){
		    		if(windows.getName().equals(e.getInternalFrame().getTopLevelAncestor().getName())){
		    			windows.dispose();
		    			break;
		    		}
		    	}
		        System.exit(0);
		    }
		});
		
		FrameDragManager frameDragManager = new FrameDragManager();
		frame.addComponentListener(frameDragManager);
		
		JWindow window = new JWindow();
		window.getContentPane().add(frame);
		window.pack();
		window.setLocationRelativeTo(null);
		window.setVisible(true);
		
	}

	public static Properties getConfiguration() {
		// Confirm Java Virtual Machine version
		try {
			double jvmversion = Double.parseDouble(System
					.getProperty("java.vm.specification.version"));
			if (jvmversion < REQUIRED_JVM_VERSION) {
				throw new Exception();
			}
		} catch (Exception e) {
			System.err.println("JVM version check failed.");
			System.exit(1);
		}

		// Determine config.xml path
		Path configPath = null;

		String fileSeparator = new String();
		try {
			String configFile = System.getProperty("java.class.path");
			fileSeparator = System.getProperty("file.separator");
			if (!configFile.endsWith(fileSeparator)) {
				configFile += fileSeparator;
			}
			configFile += CONFIGURATION_FILENAME;
			configPath = Paths.get(configFile).toAbsolutePath();
		} catch (Exception e) {
			System.err.println("Unable to determine configuration path.");
			System.exit(1);
		}

		// Test if configuration is readable/exists
		boolean configReadable = false;

		try {
			configReadable = Files.isReadable(configPath);
		} catch (Exception e) {
			configReadable = false;
		}

		// Instantiate Wallmagick properties
		Properties configuration = new Properties();
		configuration.setProperty("wallpaper.path", /*configPath.getParent()
				.toString()*/ "/home/tron/.wallpapers");
		configuration.setProperty("wallpaper.image", "tron.png");
		configuration.setProperty("style", STRETCH);

		// Load properties from configuration file if possible
		if (configReadable) {
			try (InputStream configStream = Files.newInputStream(configPath)) {
				configuration.loadFromXML(configStream);
			} catch (Exception e) {
				System.err.println("Unable to read configuration file.");
				System.exit(1);
			}
		}

		// These configuration properties are dynamic
		configuration.setProperty("file.separator", fileSeparator);
		configuration.setProperty("config.path", configPath.getParent()
				.toString());

		// Determine display's current resolution
		int height = 0;
		int width = 0;
		try {
			GraphicsDevice graphicsDevice = GraphicsEnvironment
					.getLocalGraphicsEnvironment().getDefaultScreenDevice();
			DisplayMode displayMode = graphicsDevice.getDisplayMode();
			height = displayMode.getHeight();
			width = displayMode.getWidth();
		} catch (Exception e) {
			System.err.println("System is running headless.");
			System.exit(1);
		}

		configuration.setProperty("display.width", String.valueOf(width));
		configuration.setProperty("display.height", String.valueOf(height));

		return configuration;
	}

	public static void main(String[] args) {

		// Event Dispatch Thread
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				// Set Nimbus L&F
				try {
					for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
						if ("Nimbus".equals(info.getName())) {
							UIManager.setLookAndFeel(info.getClassName());
							break;
						}
					}
				} catch (Exception e) {
					System.err.println("Nimbus L&F not supported.");
					System.exit(1);
				}

				// Display GUI
				createAndShowGUI(getConfiguration());
			}
		});

	}

}

FrameDragManager.java
import java.awt.event.ComponentEvent;
import java.awt.Component;
import java.awt.event.ComponentAdapter;
import javax.swing.JInternalFrame;
import javax.swing.JWindow;
import java.awt.MouseInfo;
import java.awt.Point;

public class FrameDragManager extends ComponentAdapter {
	
	public void componentMoved(ComponentEvent e) {
		try{
			JInternalFrame frame = (JInternalFrame)e.getComponent();
			JWindow window = (JWindow)frame.getTopLevelAncestor();
			Point mousePoint = MouseInfo.getPointerInfo().getLocation();
			Point windowPoint = new Point();
			windowPoint.setLocation(
					mousePoint.getX() - window.getWidth() / 2.0,
					mousePoint.getY()
				);
			for(Component components : frame.getComponents()){
				if(!"JRootPane".equals(components.getClass().getSimpleName())){
					windowPoint.setLocation(
							mousePoint.getX() - window.getWidth() / 2.0,
							mousePoint.getY() - components.getHeight() / 2.0
						);
					break;
				}
			}
			window.setLocation(windowPoint);
		}catch(Exception ex){
			System.err.println("Unable to drag window.");
		}
	}
}

StyleSetter.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Properties;
import javax.swing.JRadioButton;

public class StyleSetter implements ActionListener {
	private Properties configuration;
	
	public StyleSetter(Properties configuration){
		this.configuration = configuration;
	}

	public void actionPerformed(ActionEvent e){
		JRadioButton selectedButton = (JRadioButton)e.getSource();
		configuration.setProperty("style", selectedButton.getText());
	}
}

WallPaperSetter.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Properties;

public class WallpaperSetter implements ActionListener {
	private Properties configuration;
	
	public WallpaperSetter(Properties configuration){
		this.configuration = configuration;
	}

	public void actionPerformed(ActionEvent e){
		String wallpaper = configuration.getProperty("wallpaper.path");
		wallpaper += configuration.getProperty("file.separator");
		wallpaper += configuration.getProperty("wallpaper.image");
		
		int displayWidth = Integer.parseInt(configuration.getProperty("display.width"));
		int displayHeight = Integer.parseInt(configuration.getProperty("display.height"));
		
		String pipedCommand = "";
		switch(configuration.getProperty("style")){
		case Wallmagick.STRETCH:
			pipedCommand = "convert -resize ";
			pipedCommand += displayWidth;
			pipedCommand += "x";
			pipedCommand += displayHeight;
			pipedCommand += "\\! ";
			pipedCommand += wallpaper;
			pipedCommand += " - | display -window root -";
			break;
		case Wallmagick.PAD:
			pipedCommand = "convert -resize ";
			pipedCommand += displayWidth;
			pipedCommand += "x";
			pipedCommand += displayHeight;
			pipedCommand += "\\> -background black -gravity center -extent ";
			pipedCommand += displayWidth;
			pipedCommand += "x";
			pipedCommand += displayHeight;
			pipedCommand += " ";
			pipedCommand += wallpaper;
			pipedCommand += " - | display -window root -";
			break;
		case Wallmagick.CROP:
			pipedCommand = "convert -resize ";
			pipedCommand += displayWidth;
			pipedCommand += "x";
			pipedCommand += displayHeight;
			pipedCommand += "^ -gravity center -extent ";
			pipedCommand += displayWidth;
			pipedCommand += "x";
			pipedCommand += displayHeight;
			pipedCommand += " ";
			pipedCommand += wallpaper;
			pipedCommand += " - | display -window root -";
			break;
		}
		
		String[] command = {
			"/bin/sh",
			"-c",
			pipedCommand
		};
		
		try {
			Runtime.getRuntime().exec(command);
		} catch(Exception ex) {
			System.err.println("Unable to execute imagemagick.");
			System.exit(1);
		}
	}
}

Right now it's operational and sets the wallpaper as intended. However, I still have to implement a graphical JFileChooser and handle exceptions and such more elegantly. Another oddity is my use of a JWindow and JInternalFrame. Basically, I did this because I wanted to be able to instantiate the application in an X server without a window manager. I also wanted to ensure the look and feel (Nimbus). The config.xml file uses the try-with so I included a jvm version check (as it's only supposed to work in 1.7 and Nimbus wasn't on all 1.6 versions). The application should also generate a modal dialog that gives you the command line for imagemagick so you can prepend it to your ~/.xprofile or ~/.xinitrc and have the wallpaper autoset on startup. I created the config.xml along those same lines, but it's silly to call a java -jar Wallmagick.jar -restore or something to that effect with the overhead of the jvm rather than just using imagemagick directly.

Anyhow, suggestions for improvements or different/better way of doing things are also welcome.

EDIT: Forgot to post what it looks like.
Attached Image

6 Comments On This Entry

Page 1 of 1

grimpirate Icon

03 July 2012 - 03:50 PM
Changes:
Wallmagick.java
/* 
 * Icons taken from http://p.yusukekamiyamane.com/
 * http://www.iconarchive.com/show/fugue-icons-by-yusuke-kamiyamane/document-image-icon.html
 */

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JWindow;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.JRadioButton;
import javax.swing.BorderFactory;
import javax.swing.border.TitledBorder;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.GraphicsEnvironment;
import java.awt.GraphicsDevice;
import java.awt.DisplayMode;
import java.awt.Window;

import java.io.InputStream;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.util.Properties;

public class Wallmagick {

	public static final double REQUIRED_JVM_VERSION = 1.7;

	public static final String CONFIGURATION_FILENAME = "config.xml";
	
	public static final String APPLICATION_ICON = "document-image-icon.png";

	// Wallpaper display styles
	public static final String STRETCH = "Stretch";
	public static final String PAD = "Pad";
	public static final String CROP = "Crop";

	private static void createAndShowGUI(Properties configuration) {
		// Create left panel with 5 radio buttons for display style of wallpaper
		JRadioButton stretchButton = new JRadioButton(STRETCH);
		JRadioButton padButton = new JRadioButton(PAD);
		JRadioButton cropButton = new JRadioButton(CROP);
		
		StyleSetter styleListener = new StyleSetter(configuration);
		stretchButton.addActionListener(styleListener);
		padButton.addActionListener(styleListener);
		cropButton.addActionListener(styleListener);

		switch (configuration.getProperty("style")) {
		case STRETCH:
			stretchButton.setSelected(true);
			break;
		case PAD:
			padButton.setSelected(true);
			break;
		case CROP:
			cropButton.setSelected(true);
			break;
		}

		ButtonGroup displayRadioButtons = new ButtonGroup();

		displayRadioButtons.add(stretchButton);
		displayRadioButtons.add(padButton);
		displayRadioButtons.add(cropButton);

		TitledBorder titledBorder = BorderFactory.createTitledBorder("Display");

		JPanel leftPanel = new JPanel(new GridLayout(0, 1));

		leftPanel.add(stretchButton);
		leftPanel.add(padButton);
		leftPanel.add(cropButton);

		leftPanel.setBorder(titledBorder);

		// Create right panel button with two standard buttons
		JButton wallpaperButton = new JButton("Wallpaper");
		wallpaperButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		JButton applyButton = new JButton("Apply");
		applyButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		
		// Select wallpaper using a JFileChooser
		wallpaperButton.addActionListener(new WallpaperChooser(configuration, wallpaperButton));
		// Set wallpaper using imagemagick's display command
		applyButton.addActionListener(new WallpaperSetter(configuration));

		JPanel rightPanel = new JPanel();
		rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));

		rightPanel.add(Box.createVerticalGlue());
		rightPanel.add(wallpaperButton);
		rightPanel.add(applyButton);
		rightPanel.add(Box.createVerticalGlue());

		// Load application icon
		Path iconPath = null;
		try{
			iconPath = Paths.get(configuration.getProperty("config.path"), APPLICATION_ICON);
		}catch(Exception e){
			System.err.println("Unable to generate application icon path information.");
		}
		ImageIcon icon = new ImageIcon(iconPath.toString());

		JInternalFrame frame = new JInternalFrame("Wallmagick", false, true, false, false);
		frame.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
		frame.getContentPane().add(leftPanel, BorderLayout.WEST);
		frame.getContentPane().add(rightPanel, BorderLayout.CENTER);
		frame.setFrameIcon(icon);
		frame.pack();
		frame.setVisible(true);
		
		frame.addInternalFrameListener(new InternalFrameAdapter() {
		    public void internalFrameClosed(InternalFrameEvent e) {
		    	for(Window windows : window.getWindows()){
		    		if(windows.getName().equals(e.getInternalFrame().getTopLevelAncestor().getName())){
		    			windows.dispose();
		    			break;
		    		}
		    	}
		        System.exit(0);
		    }
		});
		
		FrameDragManager frameDragManager = new FrameDragManager();
		frame.addComponentListener(frameDragManager);
		
		JWindow window = new JWindow();
		window.getContentPane().add(frame);
		window.pack();
		window.setLocationRelativeTo(null);
		window.setVisible(true);
	}

	public static Properties getConfiguration() {
		// Confirm Java Virtual Machine version
		try {
			double jvmversion = Double.parseDouble(System
					.getProperty("java.vm.specification.version"));
			if (jvmversion < REQUIRED_JVM_VERSION) {
				throw new Exception();
			}
		} catch (Exception e) {
			System.err.println("JVM version check failed.");
			System.exit(1);
		}

		// Determine config.xml path
		Path configPath = null;
		try {
			configPath = Paths.get(System.getProperty("java.class.path"), CONFIGURATION_FILENAME);
			configPath = configPath.toAbsolutePath();
		} catch (Exception e) {
			System.err.println("Unable to determine configuration path.");
			System.exit(1);
		}

		// Test if configuration is readable/exists
		boolean configReadable = false;

		try {
			configReadable = Files.isReadable(configPath);
		} catch (Exception e) {
			configReadable = false;
		}

		// Instantiate Wallmagick properties
		Properties configuration = new Properties();
		configuration.setProperty("wallpaper.path", configPath.getParent().toString());
		configuration.setProperty("wallpaper.image", "wallmagick.png");
		configuration.setProperty("style", STRETCH);

		// Load properties from configuration file if possible
		if (configReadable) {
			try (InputStream configStream = Files.newInputStream(configPath)) {
				configuration.loadFromXML(configStream);
			} catch (Exception e) {
				System.err.println("Unable to read configuration file.");
				System.exit(1);
			}
		}

		// These configuration properties are dynamic
		configuration.setProperty("config.path", configPath.getParent()
				.toString());

		// Determine display's current resolution
		int height = 0;
		int width = 0;
		try {
			GraphicsDevice graphicsDevice = GraphicsEnvironment
					.getLocalGraphicsEnvironment().getDefaultScreenDevice();
			DisplayMode displayMode = graphicsDevice.getDisplayMode();
			height = displayMode.getHeight();
			width = displayMode.getWidth();
		} catch (Exception e) {
			System.err.println("System is running headless.");
			System.exit(1);
		}

		configuration.setProperty("display.width", String.valueOf(width));
		configuration.setProperty("display.height", String.valueOf(height));

		return configuration;
	}

	public static void main(String[] args) {

		// Event Dispatch Thread
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				// Set Nimbus L&F
				try {
					for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
						if ("Nimbus".equals(info.getName())) {
							UIManager.setLookAndFeel(info.getClassName());
							break;
						}
					}
				} catch (Exception e) {
					System.err.println("Nimbus L&F not supported.");
					System.exit(1);
				}

				// Display GUI
				createAndShowGUI(getConfiguration());
			}
		});

	}

}

WallpaperSetter.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Properties;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class WallpaperSetter implements ActionListener {
	private Properties configuration;
	
	public WallpaperSetter(Properties configuration){
		this.configuration = configuration;
	}

	public void actionPerformed(ActionEvent e){
		
		Path wallpaperPath = null;
		try{
			wallpaperPath = Paths.get(
					configuration.getProperty("wallpaper.path"),
					configuration.getProperty("wallpaper.image")
				);
		}catch(Exception ex){
			System.err.println("Unable to determine wallpaper path.");
			System.exit(1);
		}
		
		int displayWidth = Integer.parseInt(configuration.getProperty("display.width"));
		int displayHeight = Integer.parseInt(configuration.getProperty("display.height"));
		
		String pipedCommand = "convert -resize ";
		pipedCommand += displayWidth;
		pipedCommand += "x";
		pipedCommand += displayHeight;
		
		switch(configuration.getProperty("style")){
		case Wallmagick.STRETCH:
			pipedCommand += "\\!";
			break;
		case Wallmagick.PAD:
			pipedCommand += "\\> -background black -gravity center -extent ";
			pipedCommand += displayWidth;
			pipedCommand += "x";
			pipedCommand += displayHeight;
			break;
		case Wallmagick.CROP:
			pipedCommand += "^ -gravity center -extent ";
			pipedCommand += displayWidth;
			pipedCommand += "x";
			pipedCommand += displayHeight;
			break;
		}
		
		pipedCommand += " ";
		pipedCommand += wallpaperPath.toString();
		pipedCommand += " - | display -window root -";
		
		String[] command = {
			"/bin/sh",
			"-c",
			pipedCommand
		};
		
		try {
			Runtime.getRuntime().exec(command);
		} catch(Exception ex) {
			System.err.println("Unable to execute imagemagick.");
			System.exit(1);
		}
		
		Path configPath = null;
		try{
			configPath = Paths.get(configuration.getProperty("config.path"), Wallmagick.CONFIGURATION_FILENAME);
		}catch(Exception ex){
			System.err.println("Unable to set configuration path information.");
			System.exit(1);
		}
		
		// Equivalent to Files.newOutputStream(configPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
		try(OutputStream configOut = Files.newOutputStream(configPath)){
			configuration.storeToXML(configOut, "Wallmagick configuration");
		}catch(Exception ex){
			System.err.println("Unable to store configuration.");
			System.exit(1);
		}
	}
}

WallpaperChooser.java
import java.util.Properties;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileSystemView;
import javax.swing.JButton;

import java.nio.file.Path;
import java.nio.file.Paths;
//import java.nio.file.Files;


public class WallpaperChooser implements ActionListener {
	private Properties configuration;
	private JButton button;

	public WallpaperChooser(Properties configuration, JButton button){
		this.configuration = configuration;
		this.button = button;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		Path wallpaperPath = null;
		try{
			wallpaperPath = Paths.get(
					configuration.getProperty("wallpaper.path"),
					configuration.getProperty("wallpaper.image")
				);
		}catch(Exception ex){
			System.err.println("Unable to generate chooser path information.");
			System.exit(1);
		}
		
		JFileChooser wallpaperChooser;
		wallpaperChooser = new JFileChooser(wallpaperPath.getParent().toString(), FileSystemView.getFileSystemView());
		try{
			if(wallpaperChooser.showOpenDialog(button) == JFileChooser.APPROVE_OPTION){
				wallpaperPath = Paths.get(
						wallpaperChooser.getSelectedFile().getAbsolutePath()
					);
				configuration.setProperty("wallpaper.path", wallpaperPath.getParent().toString());
				configuration.setProperty("wallpaper.image", wallpaperPath.getFileName().toString());
			}
		}catch(Exception ex){
			System.err.print("Unable to select wallpaper.");
			System.exit(1);
		}
	}

}

Implementing a JFileChooser with a graphical preview seems like overkill to me. I'm not so sure I want the added overhead of loading and converting the thumbnails, particularly since you can readily view the images in another application. Still missing the modal dialog that provides the code for .xprofile/.xinitrc.
0

KYA Icon

07 July 2012 - 09:32 AM
What window manager do you have sitting on top of arch? I like it.
0

SegFaulty Icon

11 July 2012 - 04:33 PM
Kya, it looks like Openbox with maybe AWN for the dock.
1

grimpirate Icon

23 July 2012 - 08:54 PM
ahh shoot KYA sorry I hadn't realized someone had replied to this thread, lol. It's Joe's Window Manager, otherwise known as JWM, the dock at the bottom is wbar in fact SegFaulty. I just spent a lot of time tweaking the JWM configuration to get it JUST how I wanted. It comes with its own taskbar, but I didn't particularly care for it. There was something about it visually that I didn't find very eye-catching.
1

bigmatt267 Icon

03 March 2014 - 06:18 PM
That's pretty bad azz, but why didn't you use
 javax.swing.* 
?
0

bigmatt267 Icon

03 March 2014 - 06:18 PM
That's pretty bad azz, but why didn't you use
 import javax.swing.* 
?
0
Page 1 of 1