| /* |
| * Copyright 2000-2012 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.codeInsight.lookup.impl; |
| |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.util.Pair; |
| import com.intellij.ui.ClickListener; |
| import com.intellij.ui.JBColor; |
| import com.intellij.ui.components.panels.NonOpaquePanel; |
| import com.intellij.util.Function; |
| import com.intellij.util.containers.ContainerUtil; |
| import com.intellij.util.ui.GridBag; |
| import com.intellij.util.ui.UIUtil; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import java.awt.*; |
| import java.awt.event.MouseEvent; |
| import java.awt.font.TextAttribute; |
| import java.util.List; |
| import java.util.Random; |
| |
| /** |
| * @author peter |
| */ |
| public class Advertiser { |
| private final List<Pair<String, Color>> myTexts = ContainerUtil.createLockFreeCopyOnWriteList(); |
| private volatile Dimension myCachedPrefSize; |
| private final JPanel myComponent = new JPanel(new GridBagLayout()) { |
| private final JLabel mySample = createLabel(); |
| |
| @Override |
| public Dimension getPreferredSize() { |
| Dimension dimension = myCachedPrefSize; |
| if (dimension == null) { |
| dimension = myCachedPrefSize = calcPreferredSize(); |
| } |
| return dimension; |
| } |
| |
| private Dimension calcPreferredSize() { |
| if (myTexts.isEmpty()) { |
| return new Dimension(-1, 0); |
| } |
| |
| int maxSize = 0; |
| for (Pair<String, Color> label : myTexts) { |
| mySample.setText(prepareText(label.first)); |
| maxSize = Math.max(maxSize, mySample.getPreferredSize().width); |
| } |
| |
| Dimension sup = super.getPreferredSize(); |
| return new Dimension(maxSize + sup.width - myTextPanel.getPreferredSize().width, sup.height); |
| } |
| }; |
| private volatile int myCurrentItem = 0; |
| private final JLabel myTextPanel = createLabel(); |
| private final JLabel myNextLabel; |
| |
| public Advertiser() { |
| myNextLabel = new JLabel(">>"); |
| myNextLabel.setFont(adFont().deriveFont( |
| ContainerUtil.<TextAttribute, Object>immutableMapBuilder().put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON).build())); |
| myNextLabel.setForeground(JBColor.blue); |
| new ClickListener() { |
| @Override |
| public boolean onClick(@NotNull MouseEvent e, int clickCount) { |
| myCurrentItem++; |
| updateAdvertisements(); |
| return true; |
| } |
| }.installOn(myNextLabel); |
| |
| myNextLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
| |
| GridBag gb = new GridBag(); |
| myComponent.add(myTextPanel, gb.next()); |
| myComponent.add(myNextLabel, gb.next()); |
| myComponent.add(new NonOpaquePanel(), gb.next().fillCellHorizontally().weightx(1)); |
| } |
| |
| private void updateAdvertisements() { |
| myNextLabel.setVisible(myTexts.size() > 1); |
| if (!myTexts.isEmpty()) { |
| Pair<String, Color> pair = myTexts.get(myCurrentItem % myTexts.size()); |
| String text = pair.first; |
| myTextPanel.setText(prepareText(text)); |
| myComponent.setBackground(pair.second); |
| } |
| else { |
| myTextPanel.setText(""); |
| myComponent.setBackground(null); |
| } |
| myCachedPrefSize = null; |
| myComponent.revalidate(); |
| myComponent.repaint(); |
| } |
| |
| private static JLabel createLabel() { |
| JLabel label = new JLabel(); |
| label.setFont(adFont()); |
| return label; |
| } |
| |
| private static String prepareText(String text) { |
| return text + " "; |
| } |
| |
| public void showRandomText() { |
| int count = myTexts.size(); |
| myCurrentItem = count > 0 ? new Random().nextInt(count) : 0; |
| updateAdvertisements(); |
| } |
| |
| public void clearAdvertisements() { |
| ApplicationManager.getApplication().assertIsDispatchThread(); |
| myTexts.clear(); |
| myCurrentItem = 0; |
| updateAdvertisements(); |
| } |
| |
| private static Font adFont() { |
| Font font = UIUtil.getLabelFont(); |
| return font.deriveFont((float)(font.getSize() - 2)); |
| } |
| |
| public void addAdvertisement(@NotNull String text, @Nullable Color bgColor) { |
| ApplicationManager.getApplication().assertIsDispatchThread(); |
| myTexts.add(Pair.create(text, bgColor)); |
| updateAdvertisements(); |
| } |
| |
| public JComponent getAdComponent() { |
| return myComponent; |
| } |
| |
| public List<String> getAdvertisements() { |
| return ContainerUtil.map(myTexts, new Function<Pair<String, Color>, String>() { |
| @Override |
| public String fun(Pair<String, Color> pair) { |
| return pair.first; |
| } |
| }); |
| } |
| } |