This is the fourth part of the series that describes the additional capabilities that you can get on your tabbed panes once you start using the Substance look-and-feel.
jtp.putClientProperty(SubstanceLookAndFeel.TABBED_PANE_PREVIEW_PAINTER,
new DefaultTabPreviewPainter());
/**
* Base class for tab preview painters.
*
* @author Kirill Grouchnikov
*/
public abstract class TabPreviewPainter {
/**
* Draws a tab preview on the specified graphics.
*
* @param tabPane
* Tabbed pane.
* @param tabIndex
* tabIndex Tab index for the preview paint.
* @param g
* Graphics context.
* @param x
* X coordinate of the preview area.
* @param y
* Y coordinate of the preview area.
* @param w
* Width of the preview area.
* @param h
* Height of the preview area.
*/
public void previewTab(JTabbedPane tabPane, int tabIndex, Graphics g,
int x, int y, int w, int h) {
}
/**
* Checks whether the specified tab component is previewable.
*
* @param tabPane
* Tabbed pane.
* @param tabIndex
* Tab index for the preview paint.
* @return <code>true</code> if the specified tab component is
* previewable, <code>false</code> otherwise.
*/
public boolean hasPreview(JTabbedPane tabPane, int tabIndex) {
return false;
}
/**
* Returns the screen bounds of the tab preview dialog window.
*
* @param tabPane
* Tabbed pane.
* @return Screen bounds of the preview dialog window of the specified
* tabbed pane.
*/
public Rectangle getPreviewDialogScreenBounds(JTabbedPane tabPane) {
Rectangle tabPaneBounds = tabPane.getBounds();
Point tabPaneScreenLoc = tabPane.getLocationOnScreen();
return new Rectangle(tabPaneScreenLoc.x, tabPaneScreenLoc.y,
tabPaneBounds.width, tabPaneBounds.height);
}
/**
* Returns the owner of the overview dialog of the specified tabbed pane. If
* this function retuns a non-<code>null</code> value, the overview
* dialog will be modal for the corresponding frame.
*
* @param tabPane
* Tabbed pane.
* @return If not <code>null</code>, the overview dialog for the
* specified tabbed pane will be modal for the corresponding frame.
*/
public JFrame getModalOwner(JTabbedPane tabPane) {
return null;
}
/**
* Checks whether the specified tabbed pane has an overview dialog.
*
* @param tabPane
* Tabbed pane.
* @return <code>true</code> if the specified tabbed pane has an overview
* dialog, <code>false</code> otherwise.
*/
public boolean hasOverviewDialog(JTabbedPane tabPane) {
return false;
}
/**
* Checks whether the specified tabbed pane has a preview window for the
* specified tab.
*
* @param tabPane
* Tabbed pane.
* @param tabIndex
* Tab index.
* @return <code>true</code> if the specified tabbed pane has a preview
* window for the specified tab, <code>false</code> otherwise.
*/
public boolean hasPreviewWindow(JTabbedPane tabPane, int tabIndex) {
return false;
}
/**
* Returns the dimension for the tab preview window.
*
* @param tabPane
* Tabbed pane.
* @param tabIndex
* Tab index.
* @return Dimension of the tab preview window for the specified tab in the
* specified tabbed pane.
*/
public Dimension getPreviewWindowDimension(JTabbedPane tabPane, int tabIndex) {
return new Dimension(300, 200);
}
/**
* Returns extra delay (in milliseconds) for showing the tab preview window.
* The base delay is 2000 milliseconds (2 seconds). This function must
* return a non-negative value.
*
* @param tabPane
* Tabbed pane.
* @param tabIndex
* Tab index.
* @return Non-negative extra delay (in milliseconds) for showing the tab
* preview window.
*/
public int getPreviewWindowExtraDelay(JTabbedPane tabPane, int tabIndex) {
return 0;
}
}
/**
* Default implementation of the tab preview painter. The tab preview is a
* scaled-down (as necessary) thumbnail of the relevant tab.
*
* @author Kirill Grouchnikov
*/
public class DefaultTabPreviewPainter extends TabPreviewPainter {
/*
* (non-Javadoc)
*
* @see org.jvnet.substance.tabbed.TabPreviewPainter#hasPreview(javax.swing.JTabbedPane,
* int)
*/
@Override
public boolean hasPreview(JTabbedPane tabPane, int tabIndex) {
return (tabPane.getComponentAt(tabIndex) != null);
}
/*
* (non-Javadoc)
*
* @see org.jvnet.substance.tabbed.TabPreviewPainter#previewTab(javax.swing.JTabbedPane,
* int, java.awt.Graphics, int, int, int, int)
*/
@Override
public void previewTab(JTabbedPane tabPane, int tabIndex, Graphics g,
int x, int y, int w, int h) {
Component tabComponent = tabPane.getComponentAt(tabIndex);
if (tabComponent == null)
return;
// if (!tabComponent.isShowing())
// return;
int compWidth = tabComponent.getWidth();
int compHeight = tabComponent.getHeight();
if ((compWidth > 0) && (compHeight > 0)) {
// draw tab component
BufferedImage tempCanvas = new BufferedImage(compWidth, compHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics tempCanvasGraphics = tempCanvas.getGraphics();
tabComponent.paint(tempCanvasGraphics);
// check if need to scale down
double coef = Math.min((double) w / (double) compWidth, (double) h
/ (double) compHeight);
if (coef < 1.0) {
int sdWidth = (int) (coef * compWidth);
int sdHeight = (int) (coef * compHeight);
int dx = (w - sdWidth) / 2;
int dy = (h - sdHeight) / 2;
g.drawImage(SubstanceCoreUtilities.createThumbnail(tempCanvas,
sdWidth), dx, dy, null);
} else {
// System.out.println("Putting " + frame.hashCode() + "
// -> " + snapshot.hashCode());
g.drawImage(tempCanvas, 0, 0, null);
}
}
}
/*
* (non-Javadoc)
*
* @see org.jvnet.substance.tabbed.TabPreviewPainter#hasPreviewWindow(javax.swing.JTabbedPane,
* int)
*/
@Override
public boolean hasPreviewWindow(JTabbedPane tabPane, int tabIndex) {
return true;
}
/*
* (non-Javadoc)
*
* @see org.jvnet.substance.tabbed.TabPreviewPainter#hasOverviewDialog(javax.swing.JTabbedPane)
*/
@Override
public boolean hasOverviewDialog(JTabbedPane tabPane) {
return true;
}
}