May 30

People often have trouble when trying to set the initial position of the divider of a JSplitPane. This is caused by the fact that the method for setting the dividers location only works if the JSplitPane has been realized ie. it is currently visible.

There is a RFE to address the limitation, but until that’s resolved it you need to be aware of it.

written by objects \\ tags: , ,

May 28

In an earlier question we showed how to make a single tab flash. Since then many people have asked if it is possible to have more than one tab flashing.

To support multiple flashing tabs we need to refactor the original code a little to allow for a separate Timer for each tab that is flashing. This can achieved by moving the timer and flashing colour details into the listener as shown in the following code.

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

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;
import javax.swing.Timer;
import javax.swing.WindowConstants;

public class FlashingTab extends JTabbedPane {

	public Flasher flash(String tabName, Color fg, Color bg) {
		Flasher flasher = new Flasher(tabName, fg, bg);
		flasher.startFlashing();
		return flasher;
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();

		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		frame.setSize(300, 300);

		FlashingTab tabs = new FlashingTab();

		tabs.addTab("tab1", new JLabel("Tab 1"));
		tabs.addTab("tab2", new JLabel("Tab 2"));
		tabs.addTab("tab3", new JLabel("Tab 3"));
		tabs.addTab("tab4", new JLabel("Tab 4"));
		tabs.addTab("tab5", new JLabel("Tab 5"));

		tabs.flash("tab2", Color.green, Color.white);
		tabs.flash("tab5", Color.red, Color.yellow);
		frame.add(tabs);

		frame.setVisible(true);

	}

	public class Flasher implements ActionListener {

		private Color background;
		private Color foreground;
		private Color savedBackground;
		private Color savedForeground;
		private boolean on = false;
		private String tabName;
		private Timer timer = new Timer(1000, this);

		public Flasher(String tabName, Color fg, Color bg) {
			this.tabName = tabName;
			this.savedBackground = getBackground();
			this.savedForeground = getForeground();
			this.background = bg;
			this.foreground = fg;
		}

		public void startFlashing() {
			timer.start();
		}

		public void actionPerformed(ActionEvent e) {
			flash(on);
			on = !on;
		}

		public void flash(boolean on) {
			int tabIndex = indexOfTab(tabName);
			if (on) {

				if (foreground != null) {
					setForegroundAt(tabIndex, foreground);
				}
				if (background != null) {
					setBackgroundAt(tabIndex, background);
				}
			} else {
				if (savedForeground != null) {
					setForegroundAt(tabIndex, savedForeground);
				}
				if (savedBackground != null) {
					setBackgroundAt(tabIndex, savedBackground);
				}
			}
			repaint();
		}

		public void clearFlashing() {
			int tabIndex = indexOfTab(tabName);
			timer.stop();
			setForegroundAt(tabIndex, savedForeground);
			setBackgroundAt(tabIndex, savedBackground);
		}
	}
}

We chose to subclass JTabbedPane in the example for simplicity sakes, it’s not really required. With a few minor changes the listener would be able to be used with any JTabbedPane.

written by objects \\ tags: , ,

May 23
// Load the image

image = new ImageIcon(image).getImage();

// Determine transparency for BufferedImage
// http://helpdesk.objects.com.au/java/how-to-determine-if-image-supports-alpha

boolean hasAlpha = hasAlpha(image);
int transparency = hasAlpha ? Transparency.BITMASK : Transparency.OPAQUE;

// Create the buffered image

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
BufferedImage bufferedImage = gc.createCompatibleImage(image.getWidth(null),
		image.getHeight(null), transparency);

if (bufferedImage == null) {
	
	// if that failed then use the default color model
	
	int type = hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
	bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
}

// Copy image

Graphics g = bufferedImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();

written by objects \\ tags: , , ,