Title icons

Is there a way to control the size of a title icon? For example, can I supply a large icon but have it always render at 16x16 in docking frame tabs?

I want to do this because the title icon becomes the window icon when a frame is floating. Some alt-tab window switchers display the window icon. If I use a 16x16 icon, it’s upscaled and blurry in the window switcher. If I use a large icon, it’s rendered at full size in the docking frame tab. (Using Eclipse theme.)

No, there is only one icon for each Dockable.

… but… you can modify the window that shows the icons, and replace it with a custom frame that shows larger icons. I admit, this is not the most beatiful code, but it should work:


import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;

import bibliothek.gui.Dockable;
import bibliothek.gui.dock.ScreenDockStation;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.intern.CDockable;
import bibliothek.gui.dock.common.intern.CommonDockable;
import bibliothek.gui.dock.station.screen.ScreenDockWindow;
import bibliothek.gui.dock.station.screen.ScreenDockWindowFactory;
import bibliothek.gui.dock.station.screen.window.ScreenDockFrame;
import bibliothek.gui.dock.station.screen.window.WindowConfiguration;

public class IconTest {
	public static void main( String[] args ) {
		JFrame frame = new JFrame();
		CControl control = new CControl( frame );
		frame.setBounds( 20, 20, 400, 400 );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.add( control.getContentArea() );
		
		DefaultSingleCDockable dockable = new DefaultSingleCDockable( "bla", "Bla" );
		control.addDockable( dockable );
		dockable.setVisible( true );
		
		control.putProperty( ScreenDockStation.WINDOW_FACTORY, windowFactory() );
		frame.setVisible( true );
	}
	
	private static ScreenDockWindowFactory windowFactory(){
		return new ScreenDockWindowFactory() {
			@Override
			public ScreenDockWindow updateWindow( ScreenDockWindow window, WindowConfiguration configuration, ScreenDockStation station ) {
				return createWindow( station, configuration );
			}
			
			@Override
			public ScreenDockWindow createWindow( ScreenDockStation station, WindowConfiguration configuration ) {
				return new CustomScreenDockWindow( station, configuration, false );
			}
		};
	}
	
	private static class CustomScreenDockWindow extends ScreenDockFrame{
		public CustomScreenDockWindow( ScreenDockStation station, WindowConfiguration configuration, boolean undecorated ) {
			super( station, configuration, undecorated );
		}
		
		@Override
		protected Icon getTitleIcon() {
			Icon icon = super.getTitleIcon();
			
			Dockable dockable = getDockable();
			if( dockable instanceof CommonDockable ){
				CDockable cdockable = ((CommonDockable)dockable).getDockable();
				
				// insert some fancy code here to get a large icon, e.g. ((MyCustomDockable)cdockable).getLargeIcon()
				icon = largeIcon();
			}
			return icon;
		}
	}
	
	private static Icon largeIcon(){
		BufferedImage image = new BufferedImage( 256, 256, BufferedImage.TYPE_INT_RGB );
		Graphics2D g = image.createGraphics();
		g.setColor( Color.WHITE );
		g.fillRect( 0, 0, 256, 256 );
		g.setColor( Color.RED );
		g.fillRect( 128, 0, 128, 256 );
		g.setColor( Color.BLUE );
		g.drawOval( 0, 0, 256, 256 );
		g.dispose();
		return new ImageIcon( image );
	}
}

I don’t want DF to show large icons. I want small icons in the tabs and menus. I’m looking for a way to supply a large icon but have DF render it small. The only place it would be displayed large is in the OS window switcher.

If this capability doesn’t exist, I guess I will have to extend SingleCDockableListMenuPiece and whatever class draws the icons in tabs.

*** Edit ***

I achieved partial success with this:


// these inline extensions give the menu icons a consistent size
final SingleCDockableListMenuPiece piece = new SingleCDockableListMenuPiece(dockControl) {
	@Override
	protected Item create(final Dockable dockable) {
		return new Item(dockable) {
			private static final long serialVersionUID = 1L;
			{
				Icon icon = dockable.getTitleIcon();
				if(icon instanceof ImageIcon) {
					Image image = ((ImageIcon) icon).getImage();
					// TODO can the preferred size be obtained from the look & feel?
					Image scaled = image.getScaledInstance(16, 16, java.awt.Image.SCALE_SMOOTH);
					ImageIcon scaledIcon = new ImageIcon(scaled);
					setIcon(scaledIcon);
				}
			}
		};
	}
};

This does what I wanted for the menu icons. But I noticed that my main goal may not be achievable. It seems that Java always supplies a scaled-down icon to the OS for use in the window switcher. This is not only true of the title icons of dockables, but the icon of my app’s main JFrame as well. I’ll have to solve that before there’s any point to what I was trying to do with the title icons.

Have you found any solution by now for the mein JFrame’s icon? because I have a similar problem that I’ve been trying to solve for days…

Sorry I was not around in the past few days.

And I must say I do not fully understand your problem. The only times DockingFrames shows some Icons on a JFrame is for floating Dockables and those Icons can be changed by the workaround/hack I provided earlier. So either I am not picking up a vital clue, or we are not speaking of the same frames. I need some more explanations to help you.