vcs: Refactored "AbstractRefreshablePanel" - removed "Ticket" logic
[idea/community.git] / platform / vcs-impl / src / com / intellij / openapi / vcs / changes / AbstractRefreshablePanel.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.openapi.vcs.changes;
17
18 import com.intellij.openapi.Disposable;
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.progress.BackgroundTaskQueue;
22 import com.intellij.openapi.progress.ProgressIndicator;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.ui.MessageType;
25 import com.intellij.openapi.vcs.VcsException;
26 import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
27 import com.intellij.ui.components.JBLoadingPanel;
28 import com.intellij.util.continuation.ModalityIgnorantBackgroundableTask;
29 import org.jetbrains.annotations.CalledInAwt;
30 import org.jetbrains.annotations.CalledInBackground;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
33
34 import javax.swing.*;
35 import java.awt.*;
36
37 import static com.intellij.openapi.util.Disposer.isDisposed;
38
39 public abstract class AbstractRefreshablePanel<T> implements Disposable {
40   private static final Logger LOG = Logger.getInstance(AbstractRefreshablePanel.class);
41
42   @NotNull private final Project myProject;
43   @NotNull private final String myLoadingTitle;
44   private final JBLoadingPanel myDetailsPanel;
45   private final BackgroundTaskQueue myQueue;
46
47   protected AbstractRefreshablePanel(@NotNull Project project, @NotNull String loadingTitle, @NotNull BackgroundTaskQueue queue) {
48     myProject = project;
49     myLoadingTitle = loadingTitle;
50     myQueue = queue;
51     myDetailsPanel = new JBLoadingPanel(new BorderLayout(), this);
52     myDetailsPanel.setLoadingText("Loading...");
53   }
54
55   @CalledInAwt
56   public void refresh() {
57     ApplicationManager.getApplication().assertIsDispatchThread();
58
59     myDetailsPanel.startLoading();
60     myQueue.run(new Loader(myProject, myLoadingTitle));
61   }
62
63   @CalledInBackground
64   protected abstract T loadImpl() throws VcsException;
65   @CalledInAwt
66   protected abstract JPanel dataToPresentation(final T t);
67
68   @CalledInAwt
69   private void acceptData(final T t) {
70     myDetailsPanel.add(dataToPresentation(t));
71     myDetailsPanel.stopLoading();
72   }
73
74   public JPanel getPanel() {
75     return myDetailsPanel;
76   }
77
78   private class Loader extends ModalityIgnorantBackgroundableTask {
79     private T myData;
80
81     private Loader(@Nullable Project project, @NotNull String title) {
82       super(project, title, false);
83     }
84
85     @Override
86     protected void doInAwtIfFail(@NotNull Exception e) {
87       final Exception cause;
88       if (e instanceof RuntimeException && e.getCause() != null) {
89         cause = (Exception) e.getCause();
90       } else {
91         cause = e;
92       }
93       LOG.info(e);
94       String message = cause.getMessage() == null ? e.getMessage() : cause.getMessage();
95       message = message == null ? "Unknown error" : message;
96       VcsBalloonProblemNotifier.showOverChangesView(myProject, message, MessageType.ERROR);
97     }
98
99     @Override
100     protected void doInAwtIfCancel() {
101     }
102
103     @Override
104     protected void doInAwtIfSuccess() {
105       if (!isDisposed(AbstractRefreshablePanel.this)) {
106         acceptData(myData);
107       }
108     }
109
110     @Override
111     protected void runImpl(@NotNull ProgressIndicator indicator) {
112       if (!isDisposed(AbstractRefreshablePanel.this)) {
113         try {
114           myData = loadImpl();
115         }
116         catch (VcsException e) {
117           throw new RuntimeException(e);
118         }
119       }
120     }
121   }
122
123   @Override
124   public void dispose() {
125   }
126 }