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 21

A simple approach would be to use a Swing Timer to repeatedly change the foreground and or background colours of the tab you wish to flash. The following code demonstrates this approach

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;

public class FlashingTab extends JTabbedPane {

	private int _tabIndex;
	private Color _background;
	private Color _foreground;
	private Color _savedBackground;
	private Color _savedForeground;
	private Timer timer = new Timer(1000, new ActionListener() {
		
		private boolean on = false;
		
		@Override
		public void actionPerformed(ActionEvent e) {
			flash(on);
			on = !on;
		}
	});

	public void flash(int tabIndex, Color foreground, Color background) {

		_tabIndex = tabIndex;
		_savedForeground = getForeground();
		_savedBackground = getBackground();
		_foreground = foreground;
		_background = background;
		timer.start();
	}

	private void flash(boolean on) {
		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() {
		timer.stop();
		setForegroundAt(_tabIndex, _savedForeground);
		setBackgroundAt(_tabIndex, _savedBackground);
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		FlashingTab tabs = new FlashingTab();
		tabs.addTab("ABC", new JLabel("Tab 1"));
		tabs.addTab("XYZ", new JLabel("Tab 2"));
		tabs.flash(1, Color.red, Color.yellow);
		frame.add(tabs);
		frame.pack();
		frame.setVisible(true);
	}
}

written by objects \\ tags: , ,