blob: 1e4d92c122df134767636b2607ae473c3f31bd47 [file] [log] [blame]
/*
* Copyright 2000-2013 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.ui.wizard;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.ex.MultiLineLabel;
import com.intellij.ui.SeparatorComponent;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
public class WizardDialog<T extends WizardModel> extends DialogWrapper implements WizardCallback {
protected final T myModel;
private final JButton myPrevious = new JButton();
private final JButton myNext = new JButton();
private final JButton myFinish = new JButton();
private final JButton myCancel = new JButton();
private final JButton myHelp = new JButton();
private final JLabel myIcon = new JLabel();
private final JLabel myHeader = new JLabel();
private final JLabel myExplanation = new MultiLineLabel();
private JPanel myStepContent;
private CardLayout myCardLayout;
private final Map<WizardStep, String> myStepCardNames = new HashMap<WizardStep, String>();
public WizardDialog(Project project, boolean canBeParent, T model) {
super(project, canBeParent);
myModel = model;
init();
}
public WizardDialog(boolean canBeParent, T model) {
super(canBeParent);
myModel = model;
init();
}
public WizardDialog(boolean canBeParent, boolean tryApplicationModal, T model) {
super(null, canBeParent, tryApplicationModal);
myModel = model;
init();
}
public WizardDialog(Component parent, boolean canBeParent, T model) {
super(parent, canBeParent);
myModel = model;
init();
}
protected JComponent createCenterPanel() {
JPanel result = new JPanel(new BorderLayout());
JPanel icon = new JPanel(new BorderLayout());
icon.add(myIcon, BorderLayout.NORTH);
result.add(icon, BorderLayout.WEST);
JPanel header = new JPanel();
header.setLayout(new BoxLayout(header, BoxLayout.Y_AXIS));
header.add(myHeader);
header.add(Box.createVerticalStrut(4));
header.add(myExplanation);
header.add(Box.createVerticalStrut(4));
header.add(new SeparatorComponent(0, Color.gray, null));
header.setBorder(BorderFactory.createEmptyBorder(4, 2, 4, 2));
JPanel content = new JPanel(new BorderLayout(12, 12));
content.add(header, BorderLayout.NORTH);
myCardLayout = new CardLayout();
myStepContent = new JPanel(myCardLayout) {
public Dimension getPreferredSize() {
Dimension custom = getWindowPreferredSize();
Dimension superSize = super.getPreferredSize();
if (custom != null) {
custom.width = custom.width > 0 ? custom.width : superSize.width;
custom.height = custom.height > 0 ? custom.height : superSize.height;
} else {
custom = superSize;
}
return custom;
}
};
content.add(header, BorderLayout.NORTH);
content.add(myStepContent, BorderLayout.CENTER);
result.add(content, BorderLayout.CENTER);
//myHeader.setFont(myHeader.getFont().deriveFont(Font.BOLD, 14));
//myHeader.setFont(myHeader.getFont().deriveFont(Font.PLAIN, 12));
return result;
}
protected void init() {
setTitle(myModel.getTitle());
initHelpButton();
myModel.setCallback(this);
super.init();
initCurrentStep();
}
private void initHelpButton() {
myHelp.setText("Help");
myHelp.setMnemonic('H');
myHelp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onHelp();
}
});
getRootPane().registerKeyboardAction(
new ActionListener() {
public void actionPerformed(final ActionEvent e) {
onHelp();
}
},
KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0),
JComponent.WHEN_IN_FOCUSED_WINDOW
);
getRootPane().registerKeyboardAction(
new ActionListener() {
public void actionPerformed(final ActionEvent e) {
onHelp();
}
},
KeyStroke.getKeyStroke(KeyEvent.VK_HELP, 0),
JComponent.WHEN_IN_FOCUSED_WINDOW
);
}
private void onHelp() {
HelpManager.getInstance().invokeHelp(myModel.getCurrentStep().getHelpId());
}
private void initCurrentStep() {
WizardStep current = myModel.getCurrentStep();
myIcon.setIcon(current.getIcon());
myHeader.setFont(myHeader.getFont().deriveFont(Font.BOLD, 14));
myHeader.setText(current.getTitle());
myExplanation.setText(current.getExplanation());
@NonNls String stepName = myStepCardNames.get(current);
if (stepName == null) {
stepName = "Step" + myStepCardNames.size();
myStepContent.add(myModel.getCurrentComponent(), stepName);
myStepCardNames.put(current, stepName);
}
myCardLayout.show(myStepContent, stepName);
WizardNavigationState state = myModel.getCurrentNavigationState();
myPrevious.setAction(state.PREVIOUS);
myNext.setAction(state.NEXT);
myFinish.setAction(state.FINISH);
myCancel.setAction(state.CANCEL);
if (myNext.isEnabled()) {
getRootPane().setDefaultButton(myNext);
}
else if (myFinish.isEnabled()) {
getRootPane().setDefaultButton(myFinish);
myFinish.requestFocusInWindow();
}
else if (myCancel.isEnabled()) {
getRootPane().setDefaultButton(myCancel);
}
else {
getRootPane().setDefaultButton(null);
}
JComponent focusComponent = current.getPreferredFocusedComponent();
if (focusComponent != null) {
focusComponent.requestFocusInWindow();
}
}
protected JComponent createSouthPanel() {
final JPanel southPanel = new JPanel(new BorderLayout());
final JPanel panel = new JPanel(new GridLayout(1, 0, 5, 0));
panel.add(myPrevious);
panel.add(myNext);
panel.add(myFinish);
panel.add(myCancel);
if (ApplicationManager.getApplication() != null) {
// we won't be able to show help if there's no HelpManager
panel.add(myHelp);
}
southPanel.add(panel, BorderLayout.EAST);
southPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
return southPanel;
}
public void onStepChanged() {
initCurrentStep();
}
public void onWizardGoalDropped() {
doCancelAction();
}
public void onWizardGoalAchieved() {
doOKAction();
}
public boolean isWizardGoalAchieved() {
return isOK();
}
protected Dimension getWindowPreferredSize() {
return null;
}
@Override
public JComponent getPreferredFocusedComponent() {
return myModel.getCurrentStep().getPreferredFocusedComponent();
}
}