package bluej.prefmgr;
import javax.swing.SwingUtilities;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import bluej.BlueJTheme;
import bluej.pkgmgr.Project;
import bluej.utility.Utility;
import bluej.utility.javafx.SwingNodeFixed;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.embed.swing.SwingNode;
import javafx.scene.Node;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import bluej.Config;
import bluej.classmgr.ClassMgrPrefPanel;
import bluej.editor.moe.EditorPrefPanel;
import bluej.editor.moe.KeyBindingsPanel;
import bluej.extmgr.ExtensionPrefManager;
import bluej.extmgr.ExtensionsManager;
import bluej.utility.javafx.FXPlatformRunnable;
import bluej.utility.javafx.JavaFXUtil;
import threadchecker.OnThread;
import threadchecker.Tag;
| A JDialog subclass to allow the user to interactively edit
| preferences.
|
| <p>A singleton.
|
| @author Andrew Patterson
| @author Michael Kolling
|
public class PrefMgrDialog
{
private static PrefMgrDialog dialog = null;
| Creating the preference panes requires thread-hopping. This property
| is set to true (on the FXPlatform thread) once they are ready.
|
@OnThread(Tag.FXPlatform)
private BooleanProperty prefPanesCreated = new SimpleBooleanProperty(false);
| Indicates whether the dialog has been prepared for display.
|
private boolean prepared = false;
private Project curProject;
| Show the preferences dialog when ready. The dialog
| may not be visible yet when this method returns.
|
public static void showDialog(Project project)
{
getInstance().prepareDialogThen(project, () -> {
dialog.window.show();
dialog.tabbedPane.getScene().getWindow().sizeToScene();
});
}
| Show the preferences dialog when ready. The dialog
| may not be visible yet when this method returns.
|
| @param paneNumber The index of the pane to show
|
public static void showDialog(Project project, int paneNumber)
{
getInstance().prepareDialogThen(project, () -> {
dialog.selectTab(paneNumber);
dialog.window.show();
dialog.tabbedPane.getScene().getWindow().sizeToScene();
});
}
| Prepare this dialog for display then run the given action.
|
@OnThread(Tag.FXPlatform)
private void prepareDialogThen(Project project, FXPlatformRunnable runnable)
{
if (!prepared)
{
if (prefPanesCreated.get())
makeDialog();
else
{
JavaFXUtil.addSelfRemovingListener(prefPanesCreated, b -> JavaFXUtil.runNowOrLater(() -> prepareDialogThen(project, runnable)));
return;
}
prepared = true;
}
dialog.startEditing(project);
runnable.run();
}
| Returns the current instance of the dialog, can be null.
| @return the current instance of the dialog, can be null.
|
public static final PrefMgrDialog getInstance()
{
if (dialog == null) {
dialog = new PrefMgrDialog();
}
return dialog;
}
private ArrayList<PrefPanelListener> listeners = new ArrayList<PrefPanelListener>();
private ArrayList<Node> tabs = new ArrayList<>();
private ArrayList<String> titles = new ArrayList<String>();
private Dialog<Void> window;
private TabPane tabbedPane = null;
| Setup the UI for the dialog and event handlers for the dialog's buttons.
|
| @param title the title of the dialog
|
private PrefMgrDialog()
{
createPrefPanes();
}
| Create all known preference panes.
|
private void createPrefPanes()
{
EditorPrefPanel panel = new EditorPrefPanel();
add(0, panel, Config.getString("prefmgr.edit.prefpaneltitle"), panel);
MiscPrefPanel panel2 = new MiscPrefPanel();
add(1, panel2, Config.getString("prefmgr.misc.prefpaneltitle"), panel2);
InterfacePanel panel3 = new InterfacePanel();
add(2, panel3, Config.getString("prefmgr.interface.title"), panel3);
ClassMgrPrefPanel userConfigLibPanel = new ClassMgrPrefPanel();
add(3, userConfigLibPanel, Config.getString("classmgr.prefpaneltitle"), userConfigLibPanel);
KeyBindingsPanel kbPanel = new KeyBindingsPanel(() -> window == null || window.getDialogPane().getScene() == null ? null : window.getDialogPane().getScene().getWindow());
add(1, kbPanel, Config.getString("prefmgr.edit.keybindingstitle"), kbPanel);
SwingUtilities.invokeLater(() -> {
if (!Config.isGreenfoot())
{
SwingNode extSwing = new SwingNodeFixed();
ExtensionPrefManager mgr = ExtensionsManager.getInstance().getPrefManager();
extSwing.setContent(mgr.getPanel());
Platform.runLater(() -> {
add(5, extSwing, Config.getString("extmgr.extensions"), mgr);
});
}
Platform.runLater(() -> prefPanesCreated.set(true));
});
}
| Register a panel to be shown in the preferences dialog
|
| @param panel the panel to add
| @param title a string describing the panel
| @param listener an object which will be notified of events concerning the
| preferences dialog
|
public void add(int index, Node panel, String title, PrefPanelListener listener)
{
tabs.add(index, panel);
listeners.add(index, listener);
titles.add(index, title);
}
private void startEditing(Project project)
{
curProject = project;
for (Iterator<PrefPanelListener> i = listeners.iterator(); i.hasNext(); ) {
PrefPanelListener ppl = i.next();
ppl.beginEditing(project);
}
}
private void selectTab(int tabNumber)
{
tabbedPane.getSelectionModel().select(tabNumber);
}
private void makeDialog()
{
window = new Dialog<>();
BlueJTheme.setWindowIconFX(window);
window.setTitle(Config.getApplicationName() + ": " + Config.getString("prefmgr.title"));
Config.addDialogStylesheets(window.getDialogPane());
JavaFXUtil.addStyleClass(window.getDialogPane(), "prefmgr-dialog-pane");
window.setOnShown(e -> Utility.bringToFrontFX(window.getDialogPane().getScene().getWindow()));
window.setResizable(true);
tabbedPane = new TabPane();
tabbedPane.setPrefHeight(550.0);
JavaFXUtil.addStyleClass(tabbedPane, "prefmgr-tab-pane");
for (ListIterator<Node> i = tabs.listIterator(); i.hasNext(); ) {
int index = i.nextIndex();
Node p = i.next();
Tab tab = new Tab(titles.get(index), p);
tab.setClosable(false);
tabbedPane.getTabs().add(tab);
}
window.setResultConverter(bt -> {
if (bt == ButtonType.OK)
{
for (Iterator<PrefPanelListener> i = listeners.iterator(); i.hasNext(); )
{
PrefPanelListener ppl = i.next();
ppl.commitEditing(curProject);
}
return null;
}
else
{
for (Iterator<PrefPanelListener> i = listeners.iterator(); i.hasNext(); ) {
PrefPanelListener ppl = i.next();
ppl.revertEditing(curProject);
}
}
return null;
});
window.getDialogPane().getButtonTypes().setAll(ButtonType.OK, ButtonType.CANCEL);
window.getDialogPane().setContent(tabbedPane);
}
public static Node headedVBox(String titleID, List<Node> contents)
{
return headedVBoxTranslated(Config.getString(titleID), contents);
}
public static Node headedVBoxTranslated(String title, List<Node> contents)
{
VBox body = new VBox();
body.getChildren().setAll(contents);
JavaFXUtil.addStyleClass(body, "prefmgr-titled-content");
TitledPane titledPane = new TitledPane(title, body);
return JavaFXUtil.withStyleClass(titledPane, "prefmgr-titled");
}
public static Node labelledItem(String labelID, Node item)
{
return labelledItem(new Label(Config.getString(labelID)), item);
}
public static Node labelledItem(Label label, Node item)
{
return JavaFXUtil.withStyleClass(new HBox(label, item), "prefmgr-label-hbox");
}
public static Node wrappedLabel(String content)
{
return new TextFlow(JavaFXUtil.withStyleClass(new Text(content), "prefmgr-text-wrapped"));
}
}
top,
use,
map,
class PrefMgrDialog
. showDialog
. showDialog
. prepareDialogThen
. getInstance
. PrefMgrDialog
. createPrefPanes
. add
. startEditing
. selectTab
. makeDialog
. headedVBox
. headedVBoxTranslated
. labelledItem
. labelledItem
. wrappedLabel
303 neLoCode
+ 24 LoComm