📄 abstractpluggableguiapplication.java
字号:
}
public Dimension getMinimumSize() {
// So we don't keep "plugin" panels from getting small.
Dimension d = getPreferredSize();
d.width = 32;
return d;
}
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 20;
return d;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
GradientPaint paint = new GradientPaint(
0, 0, pluginTitlePanelBG1,
getWidth(), 0, pluginTitlePanelBG2);
Paint oldPaint = g2d.getPaint();
g2d.setPaint(paint);
Rectangle bounds = getBounds();
g2d.fillRect(0, 0, bounds.width, bounds.height);
g2d.setPaint(oldPaint);
}
public void setTitle(String title) {
label.setText(title);
}
public void stateChanged(ChangeEvent e) {
JTabbedPane source = (JTabbedPane) e.getSource();
int index = source.getSelectedIndex();
if (index > -1) {
setTitle(source.getTitleAt(index));
}
}
}
/*****************************************************************************/
/**
* A panel capable of using split panes to add "GUI plugins" to the
* top, left, bottom, and right of some main content.
*/
private final class MainContentPanel
extends JPanel
implements GUIPluginListener, PropertyChangeListener {
/**
*
*/
private static final long serialVersionUID = 4580232152233988702L;
public static final int LARGE_ON_SIDES = 0;
public static final int LARGE_ON_TOP_AND_BOTTOM = 1;
private ContentPanel[] panels;
private JFrame[] floatingPlugins;
private int dockingStyle;
private List pluginList;
private int[] panelToLocationMap = {
0, 2, 1, 3,
1, 3, 0, 2};
/**
* A panel containing either a single child or a split pane
* containing a tabbed pane of plugin panels and one other
* child. <code>MainContentPanel</code> contains
* 4 of these embedded in each other.
*/
private final class ContentPanel
extends JPanel {
/**
*
*/
private static final long serialVersionUID = -4847683840113658267L;
private JSplitPane splitPane;
private PluginPanel pluginPanel;
private int pluginsLocation;
public ContentPanel(LayoutManager lm) {
super(lm);
}
public boolean addPlugin(GUIPlugin plugin) {
// If this is our first plugin...
if (splitPane == null) {
pluginPanel = new PluginPanel();
pluginPanel.addPlugin(plugin);
int split;
Component comp1, comp2;
switch (pluginsLocation) {
case TOP:
split = JSplitPane.VERTICAL_SPLIT;
comp1 = pluginPanel;
comp2 = getComponent(0);
break;
case LEFT:
split = JSplitPane.HORIZONTAL_SPLIT;
comp1 = pluginPanel;
comp2 = getComponent(0);
break;
case BOTTOM:
split = JSplitPane.VERTICAL_SPLIT;
comp1 = getComponent(0);
comp2 = pluginPanel;
break;
default: // RIGHT:
split = JSplitPane.HORIZONTAL_SPLIT;
comp1 = getComponent(0);
comp2 = pluginPanel;
break;
}
remove(0); // Remove the original contents.
splitPane = new JSplitPane(split, comp1, comp2);
add(splitPane);
validate();
return true;
}
// We already have some plugin panels...
else {
return pluginPanel.addPlugin(plugin);
}
}
public boolean containsPlugin(GUIPlugin plugin) {
return (pluginPanel != null &&
pluginPanel.containsPlugin(plugin) > -1);
}
public int getDividerLocation() {
return splitPane != null ? splitPane.getDividerLocation() :
-1;
}
public int getPluginCount() {
return pluginPanel == null ? 0 :
pluginPanel.getPluginCount();
}
public int getPluginPanelsLocation() {
return pluginsLocation;
}
public Plugin[] getPlugins() {
return pluginPanel == null ? null :
pluginPanel.getPlugins();
}
// Returns the non-plugin panel this panel contains.
public JPanel getRegularContent() {
if (splitPane == null) {
return (JPanel) getComponent(0);
}
else {
switch (pluginsLocation) {
case TOP:
case LEFT:
return (JPanel) splitPane.getRightComponent();
case BOTTOM:
case RIGHT:
return (JPanel) splitPane.getLeftComponent();
}
}
// Shouldn't ever get here.
throw new InternalError("Invalid state in getRegularContent");
}
public boolean getSplit() {
return splitPane != null;
}
public boolean removePlugin(GUIPlugin plugin) {
if (pluginPanel != null) {
boolean rc = pluginPanel.removePlugin(plugin);
if (pluginPanel.getPluginCount() == 0) {
Component content = getRegularContent();
this.remove(splitPane);
splitPane = null;
pluginPanel = null;
add(content);
validate();
}
return rc;
}
// We don't have a plugin panel => no plugins.
return false;
}
public void setDividerLocation(int location) {
if (splitPane != null) {
splitPane.setDividerLocation(location);
}
}
public void setPluginPanelsLocation(int location) {
pluginsLocation = location;
}
}
public MainContentPanel() {
panels = new ContentPanel[4];
for (int i = 0; i < 4; i++) {
panels[i] = new ContentPanel(new GridLayout(1, 1));
panels[i].setPluginPanelsLocation(panelToLocationMap[i]);
}
for (int i = 0; i < 4 - 1; i++) {
panels[i + 1].add(panels[i]);
//panels[i+1].addPlugin(new TempPlugin());
}
setDockingStyle(LARGE_ON_SIDES);
// Add all of these panels under us.
setLayout(new GridLayout(1, 1));
add(panels[3]);
}
private void addListeners(GUIPlugin plugin) {
plugin.addGUIPluginListener(this);
plugin.addPropertyChangeListener(this);
}
public boolean addPlugin(GUIPlugin plugin) {
int pos = plugin.getPosition();
if (!GUIPlugin.isValidPosition(pos)) {
throw new IllegalArgumentException("Invalid position");
}
//plugin.setPosition(pos);
addPluginToList(plugin);
if (!plugin.isActive()) {
// Don't add him to a side yet.
addListeners(plugin);
return true;
}
switch (pos) {
case FLOATING:
if (floatingPlugins == null) {
floatingPlugins = new JFrame[1];
}
else {
JFrame[] temp = new JFrame[floatingPlugins.length + 1];
System.arraycopy(floatingPlugins, 0, temp, 0,
floatingPlugins.length);
floatingPlugins = temp;
}
int current = floatingPlugins.length - 1;
floatingPlugins[current] = createFloatingPluginFrame(plugin);
floatingPlugins[current].setVisible(true);
addListeners(plugin);
return true;
default: // TOP, LEFT, BOTTOM or RIGHT.
for (int p = 0; p < 4; p++) {
if (panelToLocationMap[p] == pos) {
ContentPanel cp = panels[p];
boolean rc = cp.addPlugin(plugin);
if (rc) {
addListeners(plugin);
}
return rc;
}
}
} // End of switch (pos).
// Shouldn't get here, but if we do, it's an error.
return false;
}
private synchronized void addPluginToList(GUIPlugin plugin) {
if (pluginList == null) {
pluginList = new ArrayList();
}
pluginList.add(plugin);
}
private JFrame createFloatingPluginFrame(GUIPlugin plugin) {
JFrame temp = new JFrame(plugin.getName());
temp.setIconImage(AbstractPluggableGUIApplication.this.
getIconImage());
JPanel contentPane = new JPanel(new GridLayout(1, 1));
contentPane.add(plugin);
temp.setContentPane(contentPane);
temp.pack();
return temp;
}
public JPanel getContentPanel() {
return panels[0].getRegularContent();
}
/**
* @param splitPane The position of the split pane for which to get
* its divider location; one of
* <code>GUIApplicationConstants.TOP</code>,
* <code>LEFT</code>, <code>BOTTOM</code> or
* <code>RIGHT</code>.
*/
public int getDividerLocation(int splitPane) {
return panels[panelToLocationMap[splitPane]].getDividerLocation();
}
/**
* Returns all installed plugins. This will return the actual
* plugins, not deep copies, so any changes made to the returned
* array will affect the actual Plugins themselves.
*
* @return All installed plugins. If no plugins are installed, a
* zero-length array is returned.
* @see #addPlugin
* @see #removePlugin
*/
public Plugin[] getPlugins() {
Plugin[] plugins = new Plugin[pluginList.size()];
plugins = (Plugin[]) pluginList.toArray(plugins);
return plugins;
}
/**
* Called whenever a GUI plugin changed its preferred position.
* This method removes the plugin from its old location and adds
* it to its new location.
*
* @param e The GUI plugin event.
*/
public void guiPluginPositionChanged(GUIPluginEvent e) {
GUIPlugin plugin = (GUIPlugin) e.getSource();
// Remove plugin from old position. Note that we should not
// check the return value here, as the plugin may not currently
// be active (thus removePlugin returns false), but is about to
// be moved.
removePlugin(plugin);
// And add in the new position.
if (!addPlugin(plugin)) {
throw new InternalError("Couldn't add plugin");
}
}
public void guiPluginPositionWillChange(GUIPluginEvent e) {
}
/**
* The only property we care about is a GUI plugin becoming
* active or inactive (i.e., visible or not visible).
*
* @param e The property change event.
*/
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if (propertyName.equals(GUIPlugin.ACTIVE_PROPERTY)) {
GUIPlugin p = (GUIPlugin) e.getSource();
if (!pluginList.contains(p)) {
throw new InternalError("Plugin list does not " +
"contain plugin: " + p);
}
boolean active = p.isActive();
// FIXME: Add plugin properly. Removing, then readding
// the plugin is an inefficient yet simple way to ensure
// that the plugin becomes active/inactive as appropriate.
removePlugin(p);
addPlugin(p);
}
}
public boolean removeContentPanel(Container contentPanel) {
// Should only be two.
Component[] comps = panels[0].getComponents();
for (int i = 0; i < comps.length; i++) {
if (comps[i].equals(contentPanel)) {
panels[0].remove(contentPanel);
return true;
}
}
return false;
}
private void removeListeners(GUIPlugin plugin) {
plugin.removeGUIPluginListener(this);
plugin.removePropertyChangeListener(this);
}
public boolean removePlugin(GUIPlugin plugin) {
if (!removePluginFromList(plugin)) {
return false; // Not in master list => just quit.
}
removeListeners(plugin);
// NOTE: We can't bail early even if the plugin isn't active,
// as isActive() may be set to false before the plugin is
// removed from the GUI. In other words, isActive() is set to
// false, then this method is called to physically remove the
// plugin.
//if (!plugin.isActive())
// return true;
// See if plugin is docked on one of our 4 sides.
for (int p = 0; p < 4; p++) {
if (panels[p].removePlugin(plugin)) {
return true;
}
}
// If it wasn't, see if it was a floating plugin.
int numFloating = floatingPlugins == null ?
0 : floatingPlugins.length;
for (int p = 0; p < numFloating; p++) {
Component possiblePlugin = floatingPlugins[p].getContentPane().
getComponent(0);
if (possiblePlugin.equals(plugin)) {
floatingPlugins[p].remove(0);
floatingPlugins[p].setVisible(false);
floatingPlugins[p].dispose();
JFrame[] temp = new JFrame[numFloating - 1];
System.arraycopy(floatingPlugins, 0, temp, 0, p);
System.arraycopy(floatingPlugins, p + 1, temp, p, numFloating - p - 1);
floatingPlugins = temp;
plugin.removeGUIPluginListener(this);
return true;
}
}
// Getting here means the plugin was hidden (rignt?).
return false;
}
private boolean removePluginFromList(GUIPlugin plugin) {
return pluginList.remove(plugin);
}
public void setContentPanel(Container contentPanel) {
panels[0].add(contentPanel);
}
/**
* @param splitPane The split pane for which to set the divider
* location; one of <code>GUIApplicationConstants.TOP</code>,
* <code>LEFT</code>, <code>BOTTOM</code> or
* <code>RIGHT</code>.
* @param pos The position of the divider.
*/
public void setDividerLocation(int splitPane, int pos) {
panels[panelToLocationMap[splitPane]].setDividerLocation(pos);
}
public void setDockingStyle(int style) {
if (dockingStyle != style &&
(style == LARGE_ON_SIDES || style == LARGE_ON_TOP_AND_BOTTOM)) {
dockingStyle = style;
// Switch necessary panels.
}
}
}
/*****************************************************************************/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -