| /* |
| * Copyright 2000-2009 JetBrains s.r.o. |
| * |
| * 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.intellij.uiDesigner.radComponents; |
| |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.uiDesigner.*; |
| import com.intellij.uiDesigner.core.GridConstraints; |
| import com.intellij.uiDesigner.designSurface.*; |
| import com.intellij.uiDesigner.lw.*; |
| import com.intellij.uiDesigner.palette.ComponentItem; |
| import com.intellij.uiDesigner.palette.Palette; |
| import com.intellij.uiDesigner.propertyInspector.*; |
| import com.intellij.uiDesigner.propertyInspector.editors.IconEditor; |
| import com.intellij.uiDesigner.propertyInspector.editors.string.StringEditor; |
| import com.intellij.uiDesigner.propertyInspector.properties.AbstractBooleanProperty; |
| import com.intellij.uiDesigner.propertyInspector.properties.IntroIconProperty; |
| import com.intellij.uiDesigner.propertyInspector.renderers.IconRenderer; |
| import com.intellij.uiDesigner.propertyInspector.renderers.LabelPropertyRenderer; |
| import com.intellij.uiDesigner.propertyInspector.renderers.StringRenderer; |
| import com.intellij.uiDesigner.snapShooter.SnapshotContext; |
| import com.intellij.util.containers.HashMap; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import javax.swing.plaf.TabbedPaneUI; |
| import java.awt.*; |
| import java.awt.event.MouseEvent; |
| |
| /** |
| * @author Anton Katilin |
| * @author Vladimir Kondratyev |
| * @author yole |
| */ |
| public final class RadTabbedPane extends RadContainer implements ITabbedPane { |
| |
| public static class Factory extends RadComponentFactory { |
| public RadComponent newInstance(ModuleProvider module, Class aClass, String id) { |
| return new RadTabbedPane(module, aClass, id); |
| } |
| |
| public RadComponent newInstance(final Class componentClass, final String id, final Palette palette) { |
| return new RadTabbedPane(componentClass, id, palette); |
| } |
| } |
| |
| private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.radComponents.RadTabbedPane"); |
| /** |
| * value: HashMap<String, LwTabbedPane.Constraints> |
| */ |
| @NonNls |
| private static final String CLIENT_PROP_ID_2_CONSTRAINTS = "index2descriptor"; |
| |
| private int mySelectedIndex = -1; |
| private IntrospectedProperty mySelectedIndexProperty = null; |
| |
| public RadTabbedPane(final ModuleProvider module, Class componentClass, final String id){ |
| super(module, componentClass, id); |
| } |
| |
| public RadTabbedPane(Class componentClass, @NotNull final String id, final Palette palette) { |
| super(componentClass, id, palette); |
| } |
| |
| @Override protected RadLayoutManager createInitialLayoutManager() { |
| return new RadTabbedPaneLayoutManager(); |
| } |
| |
| @Override public RadComponent getComponentToDrag(final Point pnt) { |
| final int i = getTabbedPane().getUI().tabForCoordinate(getTabbedPane(), pnt.x, pnt.y); |
| if (i >= 0) { |
| RadComponent c = getRadComponent(i); |
| if (c != null) { |
| return c; |
| } |
| } |
| return this; |
| } |
| |
| private RadComponent getRadComponent(final int i) { |
| RadComponent c = null; |
| final Component component = getTabbedPane().getComponentAt(i); |
| if (component instanceof JComponent) { |
| JComponent jc = (JComponent) component; |
| c = (RadComponent) jc.getClientProperty(RadComponent.CLIENT_PROP_RAD_COMPONENT); |
| } |
| return c; |
| } |
| |
| @Override public void init(final GuiEditor editor, @NotNull final ComponentItem item) { |
| super.init(editor, item); |
| // add one tab by default |
| addComponent(InsertComponentProcessor.createPanelComponent(editor)); |
| } |
| |
| @NotNull |
| private JTabbedPane getTabbedPane(){ |
| return (JTabbedPane)getDelegee(); |
| } |
| |
| private String calcTabName(final StringDescriptor titleDescriptor) { |
| if (titleDescriptor == null) { |
| return UIDesignerBundle.message("tab.untitled"); |
| } |
| return getDescriptorText(titleDescriptor); |
| } |
| |
| @Nullable |
| private String getDescriptorText(@Nullable final StringDescriptor titleDescriptor) { |
| if (titleDescriptor == null) return null; |
| final String value = titleDescriptor.getValue(); |
| if (value == null) { // from res bundle |
| final String resolvedValue = StringDescriptorManager.getInstance(getModule()).resolve(this, titleDescriptor); |
| titleDescriptor.setResolvedValue(resolvedValue); |
| return resolvedValue; |
| } |
| return value; |
| } |
| |
| /** |
| * @return inplace property for editing of the title of the clicked tab |
| */ |
| public Property getInplaceProperty(final int x, final int y) { |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| final TabbedPaneUI ui = tabbedPane.getUI(); |
| LOG.assertTrue(ui != null); |
| final int index = ui.tabForCoordinate(tabbedPane, x, y); |
| return index != -1 ? new MyTitleProperty(null, index) : null; |
| } |
| |
| @Override @Nullable |
| public Property getDefaultInplaceProperty() { |
| final int index = getTabbedPane().getSelectedIndex(); |
| if (index >= 0) { |
| return new MyTitleProperty(null, index); |
| } |
| return null; |
| } |
| |
| public Rectangle getInplaceEditorBounds(final Property property, final int x, final int y) { |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| final TabbedPaneUI ui = tabbedPane.getUI(); |
| LOG.assertTrue(ui != null); |
| final int index = ui.tabForCoordinate(tabbedPane, x, y); |
| LOG.assertTrue(index != -1); |
| return ui.getTabBounds(tabbedPane, index); |
| } |
| |
| @Override @Nullable |
| public Rectangle getDefaultInplaceEditorBounds() { |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| final int index = tabbedPane.getSelectedIndex(); |
| if (index >= 0) { |
| return tabbedPane.getUI().getTabBounds(tabbedPane, index); |
| } |
| return null; |
| } |
| |
| @Nullable |
| public StringDescriptor getChildTitle(RadComponent component) { |
| final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(this); |
| final LwTabbedPane.Constraints constraints = id2Constraints.get(component.getId()); |
| return constraints == null ? null : constraints.myTitle; |
| } |
| |
| public void setTabProperty(RadComponent component, final String propName, StringDescriptor title) throws Exception { |
| final JComponent delegee = component.getDelegee(); |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| int index = tabbedPane.indexOfComponent(delegee); |
| if (index >= 0) { |
| if (propName.equals(ITabbedPane.TAB_TITLE_PROPERTY)) { |
| new MyTitleProperty(null, index).setValue(component, title); |
| } |
| else if (propName.equals(ITabbedPane.TAB_TOOLTIP_PROPERTY)) { |
| new MyToolTipProperty(null, index).setValue(component, title); |
| } |
| else { |
| throw new IllegalArgumentException("Invalid property name " + propName); |
| } |
| } |
| } |
| |
| /** |
| * This allows user to select and scroll tabs via the mouse |
| */ |
| public void processMouseEvent(final MouseEvent event){ |
| event.getComponent().dispatchEvent(event); |
| } |
| |
| public void write(final XmlWriter writer) { |
| writer.startElement(UIFormXmlConstants.ELEMENT_TABBEDPANE); |
| try{ |
| writeId(writer); |
| writeClassIfDifferent(writer, JTabbedPane.class.getName()); |
| writeBinding(writer); |
| |
| // Constraints and properties |
| writeConstraints(writer); |
| writeProperties(writer); |
| |
| writeBorder(writer); |
| writeChildren(writer); |
| }finally{ |
| writer.endElement(); |
| } |
| } |
| |
| @NotNull |
| private static HashMap<String, LwTabbedPane.Constraints> getId2Constraints(final RadComponent component){ |
| //noinspection unchecked |
| HashMap<String, LwTabbedPane.Constraints> id2Constraints = (HashMap<String, LwTabbedPane.Constraints>)component.getClientProperty(CLIENT_PROP_ID_2_CONSTRAINTS); |
| if(id2Constraints == null){ |
| id2Constraints = new HashMap<String,LwTabbedPane.Constraints>(); |
| component.putClientProperty(CLIENT_PROP_ID_2_CONSTRAINTS, id2Constraints); |
| } |
| return id2Constraints; |
| } |
| |
| @Nullable |
| public RadComponent getSelectedTab() { |
| int index = getTabbedPane().getSelectedIndex(); |
| return index < 0 ? null : getComponent(index); |
| } |
| |
| public void selectTab(final RadComponent component) { |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| int index = tabbedPane.indexOfComponent(component.getDelegee()); |
| if (index >= 0) { |
| tabbedPane.setSelectedIndex(index); |
| } |
| } |
| |
| public StringDescriptor getTabProperty(IComponent component, final String propName) { |
| final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(this); |
| final LwTabbedPane.Constraints constraints = id2Constraints.get(component.getId()); |
| return constraints == null ? null : constraints.getProperty(propName); |
| } |
| |
| public boolean refreshChildTitle(final RadComponent radComponent) { |
| StringDescriptor childTitle = getChildTitle(radComponent); |
| if (childTitle == null) return false; |
| String oldTitle = childTitle.getResolvedValue(); |
| childTitle.setResolvedValue(null); |
| try { |
| setTabProperty(radComponent, ITabbedPane.TAB_TITLE_PROPERTY, childTitle); |
| } |
| catch (Exception e) { |
| LOG.error(e); |
| } |
| return !Comparing.equal(oldTitle, childTitle.getResolvedValue()); |
| } |
| |
| @Override public void loadLwProperty(final LwComponent lwComponent, final LwIntrospectedProperty lwProperty, final IntrospectedProperty property) { |
| if (lwProperty.getName().equals(SwingProperties.SELECTED_INDEX)) { |
| mySelectedIndexProperty = property; |
| mySelectedIndex = ((Integer)lwProperty.getPropertyValue(lwComponent)).intValue(); |
| } |
| else { |
| super.loadLwProperty(lwComponent, lwProperty, property); |
| } |
| } |
| |
| @Override public void doneLoadingFromLw() { |
| if (mySelectedIndex >= 0) { |
| getTabbedPane().setSelectedIndex(mySelectedIndex); |
| markPropertyAsModified(mySelectedIndexProperty); |
| } |
| } |
| |
| @Override |
| protected void importSnapshotComponent(final SnapshotContext context, final JComponent component) { |
| JTabbedPane tabbedPane = (JTabbedPane) component; |
| for(int i=0; i<tabbedPane.getTabCount(); i++) { |
| String title = tabbedPane.getTitleAt(i); |
| Component child = tabbedPane.getComponentAt(i); |
| if (child instanceof JComponent) { |
| RadComponent childComponent = createSnapshotComponent(context, (JComponent) child); |
| if (childComponent != null) { |
| childComponent.setCustomLayoutConstraints(new LwTabbedPane.Constraints(StringDescriptor.create(title))); |
| addComponent(childComponent); |
| } |
| } |
| } |
| } |
| |
| @NotNull |
| private LwTabbedPane.Constraints getConstraintsForComponent(final RadComponent tabComponent) { |
| final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(this); |
| LwTabbedPane.Constraints constraints = id2Constraints.get(tabComponent.getId()); |
| if (constraints == null) { |
| int index = indexOfComponent(tabComponent); |
| constraints = new LwTabbedPane.Constraints(StringDescriptor.create(getTabbedPane().getTitleAt(index))); |
| id2Constraints.put(tabComponent.getId(), constraints); |
| } |
| return constraints; |
| } |
| |
| private final class MyTabGroupProperty extends ReadOnlyProperty { |
| private final int myIndex; |
| private final LabelPropertyRenderer myRenderer = new LabelPropertyRenderer(""); |
| |
| public MyTabGroupProperty(final int index) { |
| super(null, "Tab"); |
| myIndex = index; |
| } |
| |
| @NotNull |
| public PropertyRenderer getRenderer() { |
| return myRenderer; |
| } |
| |
| |
| @NotNull @Override |
| public Property[] getChildren(final RadComponent component) { |
| return new Property[] { |
| new MyTitleProperty(this, myIndex), |
| new MyToolTipProperty(this, myIndex), |
| new MyIconProperty(this, myIndex, false), |
| new MyIconProperty(this, myIndex, true), |
| new MyEnabledProperty(this, myIndex) |
| }; |
| } |
| } |
| |
| private class MyTitleProperty extends Property<RadComponent, StringDescriptor> { |
| protected final int myIndex; |
| private final StringEditor myEditor = new StringEditor(getProject()); |
| private final StringRenderer myRenderer = new StringRenderer(); |
| |
| public MyTitleProperty(final Property parent, final int index) { |
| super(parent, TAB_TITLE_PROPERTY); |
| myIndex = index; |
| } |
| |
| protected MyTitleProperty(final Property parent, @NonNls final String name, final int index) { |
| super(parent, name); |
| myIndex = index; |
| } |
| |
| public StringDescriptor getValue(final RadComponent component) { |
| final RadComponent tabComponent = getRadComponent(myIndex); |
| // 1. resource bundle |
| final LwTabbedPane.Constraints constraints = getId2Constraints(RadTabbedPane.this).get(tabComponent.getId()); |
| final StringDescriptor descriptor = constraints == null ? null : getValueFromConstraints(constraints); |
| if(descriptor != null){ |
| return descriptor; |
| } |
| |
| // 2. plain value |
| return StringDescriptor.create(getValueFromTabbedPane()); |
| } |
| |
| protected void setValueImpl(final RadComponent component, StringDescriptor value) throws Exception { |
| final RadComponent tabComponent = getRadComponent(myIndex); |
| // 1. Put value into map |
| if (value == null) value = StringDescriptor.create(""); |
| LwTabbedPane.Constraints constraints = getConstraintsForComponent(tabComponent); |
| putValueToConstraints(value, constraints); |
| |
| // 2. Apply real string value to JComponent peer |
| final String text = StringDescriptorManager.getInstance(getModule()).resolve(RadTabbedPane.this, value); |
| if (value.getValue() == null) { |
| value.setResolvedValue(text); |
| } |
| putValueToTabbedPane(text); |
| } |
| |
| protected String getValueFromTabbedPane() { |
| return getTabbedPane().getTitleAt(myIndex); |
| } |
| |
| protected StringDescriptor getValueFromConstraints(final LwTabbedPane.Constraints constraints) { |
| return constraints.myTitle; |
| } |
| |
| protected void putValueToTabbedPane(final String text) { |
| getTabbedPane().setTitleAt(myIndex, text); |
| } |
| |
| protected void putValueToConstraints(final StringDescriptor value, final LwTabbedPane.Constraints constraints) { |
| constraints.myTitle = value; |
| } |
| |
| @NotNull |
| public PropertyRenderer<StringDescriptor> getRenderer() { |
| return myRenderer; |
| } |
| |
| public PropertyEditor<StringDescriptor> getEditor() { |
| return myEditor; |
| } |
| |
| @Override public boolean isModified(final RadComponent component) { |
| return !getTabbedPane().getTitleAt(myIndex).equals(UIDesignerBundle.message("tab.untitled")); |
| } |
| |
| @Override public void resetValue(final RadComponent component) throws Exception { |
| setValue(component, StringDescriptor.create(UIDesignerBundle.message("tab.untitled"))); |
| } |
| } |
| |
| private class MyToolTipProperty extends MyTitleProperty { |
| protected MyToolTipProperty(final Property parent, final int index) { |
| super(parent, TAB_TOOLTIP_PROPERTY, index); |
| } |
| |
| @Override protected String getValueFromTabbedPane() { |
| return getTabbedPane().getToolTipTextAt(myIndex); |
| } |
| |
| @Override protected StringDescriptor getValueFromConstraints(final LwTabbedPane.Constraints constraints) { |
| return constraints.myToolTip; |
| } |
| |
| @Override protected void putValueToTabbedPane(final String text) { |
| getTabbedPane().setToolTipTextAt(myIndex, text); |
| } |
| |
| @Override protected void putValueToConstraints(final StringDescriptor value, final LwTabbedPane.Constraints constraints) { |
| constraints.myToolTip = value; |
| } |
| |
| @Override public boolean isModified(final RadComponent component) { |
| String toolTipText = getTabbedPane().getToolTipTextAt(myIndex); |
| return !StringUtil.isEmpty(toolTipText); |
| } |
| |
| @Override public void resetValue(final RadComponent component) throws Exception { |
| setValue(component, StringDescriptor.create("")); |
| } |
| } |
| |
| private class MyIconProperty extends Property<RadComponent, IconDescriptor> { |
| private final int myIndex; |
| private final boolean myDisabledIcon; |
| private final IconRenderer myRenderer = new IconRenderer(); |
| private final IconEditor myEditor = new IconEditor(); |
| |
| public MyIconProperty(final Property parent, final int index, final boolean disabledIcon) { |
| super(parent, disabledIcon ? "Tab Disabled Icon" : "Tab Icon"); |
| myIndex = index; |
| myDisabledIcon = disabledIcon; |
| } |
| |
| public IconDescriptor getValue(final RadComponent component) { |
| LwTabbedPane.Constraints constraints = getConstraintsForComponent(component); |
| return myDisabledIcon ? constraints.myDisabledIcon : constraints.myIcon; |
| } |
| |
| protected void setValueImpl(final RadComponent component, final IconDescriptor value) throws Exception { |
| Icon icon = (value != null) ? value.getIcon() : null; |
| LwTabbedPane.Constraints constraints = getConstraintsForComponent(component); |
| if (myDisabledIcon) { |
| constraints.myDisabledIcon = value; |
| getTabbedPane().setDisabledIconAt(myIndex, icon); |
| } |
| else |
| { |
| constraints.myIcon = value; |
| getTabbedPane().setIconAt(myIndex, icon); |
| } |
| } |
| |
| @NotNull |
| public PropertyRenderer<IconDescriptor> getRenderer() { |
| return myRenderer; |
| } |
| |
| public PropertyEditor<IconDescriptor> getEditor() { |
| return myEditor; |
| } |
| |
| @Override public boolean isModified(final RadComponent radComponent) { |
| return getValue(radComponent) != null; |
| } |
| |
| @Override public void resetValue(final RadComponent radComponent) throws Exception { |
| setValue(radComponent, null); |
| } |
| } |
| |
| private class MyEnabledProperty extends AbstractBooleanProperty<RadComponent> { |
| private final int myIndex; |
| |
| public MyEnabledProperty(final Property parent, final int index) { |
| super(parent, "Tab Enabled", true); |
| myIndex = index; |
| } |
| |
| public Boolean getValue(final RadComponent component) { |
| LwTabbedPane.Constraints constraints = getConstraintsForComponent(component); |
| return constraints.myEnabled; |
| } |
| |
| protected void setValueImpl(final RadComponent component, final Boolean value) throws Exception { |
| LwTabbedPane.Constraints constraints = getConstraintsForComponent(component); |
| constraints.myEnabled = value.booleanValue(); |
| getTabbedPane().setEnabledAt(myIndex, value.booleanValue()); |
| } |
| } |
| |
| private class RadTabbedPaneLayoutManager extends RadLayoutManager { |
| |
| @Nullable public String getName() { |
| return null; |
| } |
| |
| @Override @NotNull |
| public ComponentDropLocation getDropLocation(RadContainer container, @Nullable final Point location) { |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| final TabbedPaneUI ui = tabbedPane.getUI(); |
| if (location != null && tabbedPane.getTabCount() > 0) { |
| for(int i=0; i<tabbedPane.getTabCount(); i++) { |
| Rectangle rc = ui.getTabBounds(tabbedPane, i); |
| if (location.x < rc.getCenterX()) { |
| return new InsertTabDropLocation(i, new Rectangle(rc.x-4, rc.y, 8, rc.height)); |
| } |
| } |
| } |
| return new InsertTabDropLocation(tabbedPane.getTabCount(), null); |
| } |
| |
| public void writeChildConstraints(final XmlWriter writer, final RadComponent child) { |
| writer.startElement(UIFormXmlConstants.ELEMENT_TABBEDPANE); |
| try{ |
| final JComponent delegee = child.getDelegee(); |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| final int i = tabbedPane.indexOfComponent(delegee); |
| if (i == -1) { |
| throw new IllegalArgumentException("cannot find tab for " + child); |
| } |
| |
| final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(RadTabbedPane.this); |
| final LwTabbedPane.Constraints tabTitleConstraints = id2Constraints.get(child.getId()); |
| if (tabTitleConstraints != null) { |
| writer.writeStringDescriptor(tabTitleConstraints.myTitle, |
| UIFormXmlConstants.ATTRIBUTE_TITLE, |
| UIFormXmlConstants.ATTRIBUTE_TITLE_RESOURCE_BUNDLE, |
| UIFormXmlConstants.ATTRIBUTE_TITLE_KEY); |
| |
| if (tabTitleConstraints.myIcon != null) { |
| writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_ICON, tabTitleConstraints.myIcon.getIconPath()); |
| } |
| if (tabTitleConstraints.myDisabledIcon != null) { |
| writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_DISABLED_ICON, tabTitleConstraints.myDisabledIcon.getIconPath()); |
| } |
| if (!tabTitleConstraints.myEnabled) { |
| writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_ENABLED, false); |
| } |
| if (tabTitleConstraints.myToolTip != null) { |
| writer.startElement(UIFormXmlConstants.ELEMENT_TOOLTIP); |
| writer.writeStringDescriptor(tabTitleConstraints.myToolTip, |
| UIFormXmlConstants.ATTRIBUTE_VALUE, |
| UIFormXmlConstants.ATTRIBUTE_RESOURCE_BUNDLE, |
| UIFormXmlConstants.ATTRIBUTE_KEY); |
| writer.endElement(); |
| } |
| } |
| else { |
| final String title = tabbedPane.getTitleAt(i); |
| writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_TITLE, title != null ? title : ""); |
| } |
| } |
| finally{ |
| writer.endElement(); |
| } |
| } |
| |
| public void addComponentToContainer(final RadContainer container, final RadComponent component, final int index) { |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| LwTabbedPane.Constraints constraints = null; |
| if (component.getCustomLayoutConstraints() instanceof LwTabbedPane.Constraints) { |
| constraints = ((LwTabbedPane.Constraints)component.getCustomLayoutConstraints()); |
| } |
| component.setCustomLayoutConstraints(null); |
| final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(RadTabbedPane.this); |
| id2Constraints.put(component.getId(), constraints); |
| final String tabName = calcTabName(constraints == null ? null : constraints.myTitle); |
| String toolTip = null; |
| Icon icon = null; |
| if (constraints != null) { |
| toolTip = getDescriptorText(constraints.myToolTip); |
| if (constraints.myIcon != null) { |
| IntroIconProperty.ensureIconLoaded(getModule(), constraints.myIcon); |
| icon = constraints.myIcon.getIcon(); |
| } |
| } |
| tabbedPane.insertTab(tabName, icon, component.getDelegee(), toolTip, index); |
| if (constraints != null) { |
| if (constraints.myDisabledIcon != null) { |
| IntroIconProperty.ensureIconLoaded(getModule(), constraints.myDisabledIcon); |
| tabbedPane.setDisabledIconAt(index, constraints.myDisabledIcon.getIcon()); |
| } |
| tabbedPane.setEnabledAt(index, constraints.myEnabled); |
| } |
| } |
| |
| @Override public void removeComponentFromContainer(final RadContainer container, final RadComponent component) { |
| LOG.debug("Removing component with ID " + component.getId()); |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| |
| final JComponent delegee = component.getDelegee(); |
| final int i = tabbedPane.indexOfComponent(delegee); |
| if (i == -1) { |
| throw new IllegalArgumentException("cannot find tab for " + component); |
| } |
| final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(RadTabbedPane.this); |
| LwTabbedPane.Constraints constraints = id2Constraints.get(component.getId()); |
| if (constraints == null) { |
| LOG.debug("title of removed component is null"); |
| constraints = new LwTabbedPane.Constraints(StringDescriptor.create(tabbedPane.getTitleAt(i))); |
| } |
| else { |
| LOG.debug("title of removed component is " + constraints.myTitle.toString()); |
| } |
| component.setCustomLayoutConstraints(constraints); |
| id2Constraints.remove(component.getId()); |
| tabbedPane.removeTabAt(i); |
| } |
| |
| @Override public Property[] getComponentProperties(final Project project, final RadComponent component) { |
| final JComponent delegee = component.getDelegee(); |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| int index = tabbedPane.indexOfComponent(delegee); |
| if (index >= 0) { |
| return new Property[] { new MyTabGroupProperty(index) }; |
| } |
| return Property.EMPTY_ARRAY; |
| } |
| |
| @Override |
| public boolean isSwitchedToChild(RadContainer container, RadComponent child) { |
| return child == getSelectedTab(); |
| } |
| |
| @Override |
| public boolean switchContainerToChild(RadContainer container, RadComponent child) { |
| RadTabbedPane.this.selectTab(child); |
| return true; |
| } |
| |
| @Override |
| public boolean areChildrenExclusive() { |
| return true; |
| } |
| } |
| |
| private final class InsertTabDropLocation implements ComponentDropLocation { |
| private int myInsertIndex; |
| private String myInsertBeforeId; |
| private final Rectangle myFeedbackRect; |
| |
| public InsertTabDropLocation(final int insertIndex, final Rectangle feedbackRect) { |
| myInsertIndex = insertIndex; |
| if (myInsertIndex < getTabbedPane().getTabCount()) { |
| myInsertBeforeId = getRadComponent(myInsertIndex).getId(); |
| } |
| myFeedbackRect = feedbackRect; |
| } |
| |
| public RadContainer getContainer() { |
| return RadTabbedPane.this; |
| } |
| |
| public boolean canDrop(ComponentDragObject dragObject) { |
| return dragObject.getComponentCount() == 1; |
| } |
| |
| public void placeFeedback(FeedbackLayer feedbackLayer, ComponentDragObject dragObject) { |
| final String tooltipText = UIDesignerBundle.message("insert.feedback.add.tab", getDisplayName(), myInsertIndex); |
| if (myInsertIndex < getTabbedPane().getTabCount()) { |
| feedbackLayer.putFeedback(getDelegee(), myFeedbackRect, VertInsertFeedbackPainter.INSTANCE, tooltipText); |
| } |
| else { |
| Rectangle rcFeedback; |
| final JTabbedPane tabbedPane = getTabbedPane(); |
| final TabbedPaneUI ui = tabbedPane.getUI(); |
| if (tabbedPane.getTabCount() > 0) { |
| Rectangle rc = ui.getTabBounds(tabbedPane, tabbedPane.getTabCount()-1); |
| rcFeedback = new Rectangle(rc.x+rc.width, rc.y, 50, rc.height); |
| } |
| else { |
| // approximate |
| rcFeedback = new Rectangle(0, 0, 50, tabbedPane.getFontMetrics(tabbedPane.getFont()).getHeight() + 8); |
| } |
| feedbackLayer.putFeedback(getDelegee(), rcFeedback, tooltipText); |
| } |
| } |
| |
| public void processDrop(GuiEditor editor, |
| RadComponent[] components, |
| GridConstraints[] constraintsToAdjust, |
| ComponentDragObject dragObject) { |
| if (myInsertBeforeId != null) { |
| for(int i=0; i<getTabbedPane().getTabCount(); i++) { |
| if (getRadComponent(i).getId().equals(myInsertBeforeId)) { |
| myInsertIndex = i; |
| break; |
| } |
| } |
| } |
| if (myInsertIndex > getTabbedPane().getTabCount()) { |
| myInsertIndex = getTabbedPane().getTabCount(); |
| } |
| RadComponent componentToAdd = components [0]; |
| if (componentToAdd instanceof RadContainer) { |
| addComponent(componentToAdd, myInsertIndex); |
| } |
| else { |
| Palette palette = Palette.getInstance(editor.getProject()); |
| RadContainer panel = InsertComponentProcessor.createPanelComponent(editor); |
| addComponent(panel); |
| panel.getDropLocation(null).processDrop(editor, new RadComponent[] { componentToAdd }, null, |
| new ComponentItemDragObject(palette.getPanelItem())); |
| } |
| getTabbedPane().setSelectedIndex(myInsertIndex); |
| } |
| |
| @Nullable |
| public ComponentDropLocation getAdjacentLocation(Direction direction) { |
| return null; |
| } |
| } |
| } |