changedUpdate exception
[fedora-idea.git] / platform / platform-impl / src / com / intellij / ui / BalloonLayout.java
blob9d8cdddf10cd6c4f7d1a17d24d0d3d53b1a04c55
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.ui;
18 import com.intellij.openapi.Disposable;
19 import com.intellij.openapi.ui.popup.Balloon;
20 import com.intellij.openapi.util.Disposer;
21 import com.intellij.util.Alarm;
22 import org.jetbrains.annotations.NotNull;
24 import javax.swing.*;
25 import java.awt.*;
26 import java.awt.event.ComponentAdapter;
27 import java.awt.event.ComponentEvent;
28 import java.util.ArrayList;
29 import java.util.List;
31 public class BalloonLayout {
33 private final JLayeredPane myParent;
34 private final Insets myInsets;
36 private final List<Balloon> myBalloons = new ArrayList<Balloon>();
38 private final Alarm myRelayoutAlarm = new Alarm();
39 private final Runnable myRelayoutRunnable = new Runnable() {
40 public void run() {
41 relayout();
45 public BalloonLayout(@NotNull JLayeredPane parent, @NotNull Insets insets) {
46 myParent = parent;
47 myInsets = insets;
48 myParent.addComponentListener(new ComponentAdapter() {
49 @Override
50 public void componentResized(ComponentEvent e) {
51 queueRelayout();
53 });
56 public void add(final Balloon balloon) {
57 myBalloons.add(balloon);
58 Disposer.register(balloon, new Disposable() {
59 public void dispose() {
60 myBalloons.remove(balloon);
61 queueRelayout();
63 });
65 relayout();
66 balloon.show(myParent);
70 private void queueRelayout() {
71 myRelayoutAlarm.cancelAllRequests();
72 myRelayoutAlarm.addRequest(myRelayoutRunnable, 200);
75 private void relayout() {
76 final Dimension size = myParent.getSize();
78 size.width -= myInsets.left + myInsets.right;
79 size.height -= myInsets.top + myInsets.bottom;
81 final Rectangle layoutRec = new Rectangle(new Point(myInsets.left, myInsets.top), size);
83 List<ArrayList<Balloon>> columns = createColumns(layoutRec);
84 List<Integer> columnWidths = computeWidths(columns);
86 int eachCoumnX = (int)layoutRec.getMaxX();
87 for (int i = 0; i < columns.size(); i++) {
88 final ArrayList<Balloon> eachColumn = columns.get(i);
89 final Integer eachWidth = columnWidths.get(i);
90 eachCoumnX -= eachWidth.intValue();
91 int eachY = layoutRec.y;
92 for (Balloon eachBalloon : eachColumn) {
93 final Rectangle eachRec = new Rectangle();
94 final Dimension eachPrefSize = eachBalloon.getPreferredSize();
95 eachRec.setSize(eachPrefSize);
96 eachRec.setLocation(eachCoumnX + eachWidth.intValue() - eachRec.width, eachY);
97 eachBalloon.setBounds(eachRec);
98 eachY += eachRec.height;
105 private static List<Integer> computeWidths(List<ArrayList<Balloon>> columns) {
106 List<Integer> columnWidths = new ArrayList<Integer>();
107 for (ArrayList<Balloon> eachColumn : columns) {
108 int maxWidth = 0;
109 for (Balloon each : eachColumn) {
110 maxWidth = Math.max(each.getPreferredSize().width, maxWidth);
112 columnWidths.add(maxWidth);
114 return columnWidths;
117 private List<ArrayList<Balloon>> createColumns(Rectangle layoutRec) {
118 List<ArrayList<Balloon>> columns = new ArrayList<ArrayList<Balloon>>();
120 ArrayList<Balloon> eachColumn = new ArrayList<Balloon>();
121 columns.add(eachColumn);
123 int eachColumnHeight = 0;
124 for (Balloon each : myBalloons) {
125 final Dimension eachSize = each.getPreferredSize();
126 if (eachColumnHeight + eachSize.height > layoutRec.getHeight()) {
127 eachColumn = new ArrayList<Balloon>();
128 columns.add(eachColumn);
129 eachColumnHeight = 0;
131 eachColumn.add(each);
132 eachColumnHeight += eachSize.height;
134 return columns;