com.l2fprod.common.swing.plaf.basic.BasicOutlookBarUI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of orbit-image-analysis Show documentation
Show all versions of orbit-image-analysis Show documentation
Orbit, a versatile image analysis software for biological image-based quantification
/**
* $ $ License.
*
* Copyright $ L2FProd.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.l2fprod.common.swing.plaf.basic;
import com.actelion.research.orbit.imageAnalysis.utils.OrbitUtils;
import com.l2fprod.common.swing.JOutlookBar;
import com.l2fprod.common.swing.PercentLayout;
import com.l2fprod.common.swing.PercentLayoutAnimator;
import com.l2fprod.common.swing.plaf.OutlookBarUI;
import com.l2fprod.common.util.JVM;
import javax.swing.*;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.*;
import java.util.List;
/**
* BasicOutlookBarUI.
*
*/
public class BasicOutlookBarUI extends BasicTabbedPaneUI implements
OutlookBarUI {
public static ComponentUI createUI(JComponent c) {
return new BasicOutlookBarUI();
}
private ContainerListener tabListener;
private Map buttonToTab;
private Map tabToButton;
private Component nextVisibleComponent;
private PercentLayoutAnimator animator;
public JScrollPane makeScrollPane(Component component) {
// the component is not scrollable, wraps it in a ScrollableJPanel
JScrollPane scroll = new JScrollPane();
scroll.setBorder(BorderFactory.createEmptyBorder());
if (component instanceof Scrollable) {
scroll.getViewport().setView(component);
} else {
scroll.getViewport().setView(new ScrollableJPanel(component));
}
scroll.setOpaque(false);
scroll.getViewport().setOpaque(false);
return scroll;
}
protected void installDefaults() {
super.installDefaults();
TabLayout layout = new TabLayout();
tabPane.setLayout(layout);
// ensure constraints is correct for existing components
layout.setLayoutConstraints(tabPane);
updateTabLayoutOrientation();
buttonToTab = new HashMap();
tabToButton = new HashMap();
LookAndFeel.installBorder(tabPane, "OutlookBar.border");
LookAndFeel.installColors(tabPane, "OutlookBar.background","OutlookBar.foreground");
tabPane.setOpaque(true);
// add buttons for the current components already added in this panel
Component[] components = tabPane.getComponents();
for (int i = 0, c = components.length; i < c; i++) {
tabAdded(components[i]);
}
}
protected void uninstallDefaults() {
// remove all buttons created for components
List tabs = new ArrayList(buttonToTab.values());
for (Iterator iter = tabs.iterator(); iter.hasNext(); ) {
Component tab = (Component)iter.next();
tabRemoved(tab);
}
super.uninstallDefaults();
}
protected void installListeners() {
tabPane.addContainerListener(tabListener = createTabListener());
super.installListeners();
}
protected ContainerListener createTabListener() {
return new ContainerTabHandler();
}
protected PropertyChangeListener createPropertyChangeListener() {
return new PropertyChangeHandler();
}
protected void uninstallListeners() {
super.uninstallListeners();
tabPane.removeContainerListener(tabListener);
}
public Rectangle getTabBounds(JTabbedPane pane, int index) {
Component tab = pane.getComponentAt(index);
return tab.getBounds();
}
public int getTabRunCount(JTabbedPane pane) {
return 0;
}
public int tabForCoordinate(JTabbedPane pane, int x, int y) {
int index = -1;
for (int i = 0, c = pane.getTabCount(); i < c; i++) {
if (pane.getComponentAt(i).contains(x, y)) {
index = i;
break;
}
}
return index;
}
protected int indexOfComponent(Component component) {
int index = -1;
Component[] components = tabPane.getComponents();
for (int i = 0; i < components.length; i++) {
if (components[i] == component) {
index = i;
break;
}
}
return index;
}
protected TabButton createTabButton() {
TabButton button = new TabButton();
button.setOpaque(true);
return button;
}
protected void tabAdded(final Component newTab) {
TabButton button = (TabButton)tabToButton.get(newTab);
if (button == null) {
button = createTabButton();
buttonToTab.put(button, newTab);
tabToButton.put(newTab, button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Component current = getVisibleComponent();
Component target = newTab;
// animate the tabPane if there is a current tab selected and if the
// tabPane allows animation
if (((JOutlookBar)tabPane).isAnimated() && current != target
&& current != null && target != null) {
try { // patch Manuel 16.03.2011
if (animator != null) {
animator.stop();
}
animator = new PercentLayoutAnimator(tabPane,
(PercentLayout)tabPane.getLayout()) {
public void stop() {
super.stop();
tabPane.setSelectedComponent(newTab); // might throw an illegal argument exception
nextVisibleComponent = null;
}
};
nextVisibleComponent = newTab;
animator.setTargetPercent(current, 1.0f, 0.0f);
animator.setTargetPercent(newTab, 0.0f, 1.0f);
animator.start();
} catch (IllegalArgumentException ex) {
nextVisibleComponent = null;
tabPane.setSelectedComponent(newTab);
}
} else {
nextVisibleComponent = null;
tabPane.setSelectedComponent(newTab);
}
}
});
} else {
// the tab is already in the list, remove the button, it will be
// added again later
tabPane.remove(button);
}
// update the button with the tab information
updateTabButtonAt(tabPane.indexOfComponent(newTab));
int index = indexOfComponent(newTab);
tabPane.add(button, index);
// workaround for nullpointerexception in setRolloverTab
// introduced by J2SE 5
if (JVM.current().isOneDotFive()) {
assureRectsCreated(tabPane.getTabCount());
}
}
protected void tabRemoved(Component removedTab) {
TabButton button = (TabButton)tabToButton.get(removedTab);
tabPane.remove(button);
buttonToTab.remove(button);
tabToButton.remove(removedTab);
}
/**
* Called whenever a property of a tab is changed
*
* @param index
*/
protected void updateTabButtonAt(int index) {
TabButton button = buttonForTab(index);
button.setText(tabPane.getTitleAt(index));
button.setIcon(tabPane.getIconAt(index));
button.setDisabledIcon(tabPane.getDisabledIconAt(index));
// button.setBackground(tab.getBackgroundAt(index));
// button.setForeground(tab.getForegroundAt(index));
button.setToolTipText(tabPane.getToolTipTextAt(index));
button
.setDisplayedMnemonicIndex(tabPane.getDisplayedMnemonicIndexAt(index));
button.setMnemonic(tabPane.getMnemonicAt(index));
button.setEnabled(tabPane.isEnabledAt(index));
button.setHorizontalAlignment(((JOutlookBar)tabPane).getAlignmentAt(index));
if (OrbitUtils.DARKUI) {
button.setBackground(Color.darkGray); // patch Manuel (for substance ui) 14.01.2015 // TODO
}
}
protected TabButton buttonForTab(int index) {
Component component = tabPane.getComponentAt(index);
return (TabButton)tabToButton.get(component);
}
class PropertyChangeHandler implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
//JTabbedPane pane = (JTabbedPane)e.getSource();
String name = e.getPropertyName();
if ("tabPropertyChangedAtIndex".equals(name)) {
int index = ((Integer)e.getNewValue()).intValue();
updateTabButtonAt(index);
} else if ("tabPlacement".equals(name)) {
updateTabLayoutOrientation();
}
}
}
protected void updateTabLayoutOrientation() {
TabLayout layout = (TabLayout)tabPane.getLayout();
int placement = tabPane.getTabPlacement();
if (placement == JTabbedPane.TOP || placement == JTabbedPane.BOTTOM) {
layout.setOrientation(PercentLayout.HORIZONTAL);
} else {
layout.setOrientation(PercentLayout.VERTICAL);
}
}
/**
* Manages tabs being added or removed
*/
class ContainerTabHandler extends ContainerAdapter {
public void componentAdded(ContainerEvent e) {
if (!(e.getChild() instanceof UIResource)) {
Component newTab = e.getChild();
tabAdded(newTab);
}
}
public void componentRemoved(ContainerEvent e) {
if (!(e.getChild() instanceof UIResource)) {
Component oldTab = e.getChild();
tabRemoved(oldTab);
}
}
}
/**
* Layout for the tabs, buttons get preferred size, tabs get all
*/
protected class TabLayout extends PercentLayout {
public void addLayoutComponent(Component component, Object constraints) {
if (constraints == null) {
if (component instanceof TabButton) {
super.addLayoutComponent(component, "");
} else {
super.addLayoutComponent(component, "100%");
}
} else {
super.addLayoutComponent(component, constraints);
}
}
public void setLayoutConstraints(Container parent) {
Component[] components = parent.getComponents();
for (int i = 0, c = components.length; i < c; i++) {
if (!(components[i] instanceof TabButton)) {
super.addLayoutComponent(components[i], "100%");
}
}
}
public void layoutContainer(Container parent) {
int selectedIndex = tabPane.getSelectedIndex();
Component visibleComponent = getVisibleComponent();
if (selectedIndex < 0) {
if (visibleComponent != null) {
// The last tab was removed, so remove the component
setVisibleComponent(null);
}
} else {
Component selectedComponent = tabPane.getComponentAt(selectedIndex);
boolean shouldChangeFocus = false;
// In order to allow programs to use a single component
// as the display for multiple tabs, we will not change
// the visible compnent if the currently selected tab
// has a null component. This is a bit dicey, as we don't
// explicitly state we support this in the spec, but since
// programs are now depending on this, we're making it work.
//
if (selectedComponent != null) {
if (selectedComponent != visibleComponent && visibleComponent != null) {
if (SwingUtilities.findFocusOwner(visibleComponent) != null) {
shouldChangeFocus = true;
}
}
setVisibleComponent(selectedComponent);
// make sure only the selected component is visible
Component[] components = parent.getComponents();
for (int i = 0; i < components.length; i++) {
if (!(components[i] instanceof UIResource)
&& components[i].isVisible()
&& components[i] != selectedComponent) {
components[i].setVisible(false);
}
}
if (BasicOutlookBarUI.this.nextVisibleComponent != null) {
BasicOutlookBarUI.this.nextVisibleComponent.setVisible(true);
}
}
super.layoutContainer(parent);
if (shouldChangeFocus) {
if (!requestFocusForVisibleComponent0()) {
tabPane.requestFocus();
}
}
}
}
}
// PENDING(fred) JDK 1.5 may have this method from superclass
protected boolean requestFocusForVisibleComponent0() {
Component visibleComponent = getVisibleComponent();
if (visibleComponent.isFocusTraversable()) {
visibleComponent.requestFocus();
return true;
} else if (visibleComponent instanceof JComponent) {
if (((JComponent)visibleComponent).requestDefaultFocus()) { return true; }
}
return false;
}
protected static class TabButton extends JButton implements UIResource {
public TabButton() {}
public TabButton(ButtonUI ui) {
setUI(ui);
}
}
//
//
//
/**
* Overriden to return an empty adapter, the default listener was
* just implementing the tab selection mechanism
*/
protected MouseListener createMouseListener() {
return new MouseAdapter() {};
}
/**
* Wraps any component in a Scrollable JPanel so it can work
* correctly within a viewport
*/
private static class ScrollableJPanel extends JPanel implements Scrollable {
public ScrollableJPanel(Component component) {
setLayout(new BorderLayout(0, 0));
add("Center", component);
setOpaque(false);
}
public int getScrollableUnitIncrement(Rectangle visibleRect,
int orientation, int direction) {
return 16;
}
public Dimension getPreferredScrollableViewportSize() {
return (super.getPreferredSize());
}
public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation, int direction) {
return 16;
}
public boolean getScrollableTracksViewportWidth() {
return true;
}
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
//
// Override all paint methods of the BasicTabbedPaneUI to do nothing
//
public void paint(Graphics g, JComponent c) {}
protected void paintContentBorder(Graphics g, int tabPlacement,
int selectedIndex) {}
protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {}
protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {}
protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {}
protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {}
protected void paintFocusIndicator(Graphics g, int tabPlacement,
Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect,
boolean isSelected) {}
protected void paintIcon(Graphics g, int tabPlacement, int tabIndex,
Icon icon, Rectangle iconRect, boolean isSelected) {}
protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects,
int tabIndex, Rectangle iconRect, Rectangle textRect) {}
protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) {}
protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex,
int x, int y, int w, int h, boolean isSelected) {}
protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
int x, int y, int w, int h, boolean isSelected) {}
protected void paintText(Graphics g, int tabPlacement, Font font,
FontMetrics metrics, int tabIndex, String title, Rectangle textRect,
boolean isSelected) {}
}