List for displaying available libraries added to library manager.

List of available libraries is currently a placeholder.
This commit is contained in:
pesckal
2011-06-17 07:22:33 +00:00
parent 574513b926
commit c2cd09d0f2
2 changed files with 387 additions and 43 deletions

View File

@@ -0,0 +1,312 @@
package processing.app;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.*;
import java.text.*;
import java.util.*;
import processing.app.LibraryManager.*;
public class LibraryListPanel extends JPanel {
/**
* Panel that expands and gives a brief overview of a library when clicked.
*/
class LibraryPanel extends JPanel {
final String unclickedCardId = "unclicked";
final String clickedCardId = "clicked";
final int topAndBottomBorder = 2;
LibraryInfo libInfo;
JPanel headerPanel;
JLabel nameLabel;
JPanel infoPanel;
JPanel unclickedCard;
JPanel clickedCard;
JTextArea briefText;
JButton installOrRemove;
boolean isInfoShown;
private LibraryPanel(LibraryInfo libInfo) {
this.libInfo = libInfo;
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBorder(BorderFactory.createEmptyBorder(topAndBottomBorder, 2, topAndBottomBorder, 2));
configureHeaderPane();
configureInfoPane();
setShowInfo(false);
updateLibraryListSize();
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
for (Component c : LibraryListPanel.this.getComponents()) {
if (c != LibraryPanel.this && c instanceof LibraryPanel) {
LibraryPanel lp = (LibraryPanel) c;
lp.setShowInfo(false);
}
}
setShowInfo(true);
updateLibraryListSize();
}
});
}
/**
* Create the widgets for the header panel which is visible when the library
* panel is not clicked
*/
private void configureHeaderPane() {
headerPanel = new JPanel();
headerPanel.setOpaque(false);
headerPanel.setLayout(new BoxLayout(headerPanel, BoxLayout.X_AXIS));
nameLabel = new JLabel(libInfo.name);
headerPanel.add(this.nameLabel);
headerPanel.add(Box.createHorizontalGlue());
add(headerPanel);
}
/**
* Create the widgets for the info panel which is visible when the library
* panel is clicked
*/
private void configureInfoPane() {
infoPanel = new JPanel();
infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.Y_AXIS));
infoPanel.setLayout(new CardLayout());
unclickedCard = new JPanel();
clickedCard = new JPanel();
infoPanel.setOpaque(false);
unclickedCard.setOpaque(false);
clickedCard.setOpaque(false);
briefText = new JTextArea(libInfo.briefOverview);
installOrRemove = new JButton();
// installOrRemove = new JButton("Install");
// ActionListener installLibAction = new ActionListener() {
//
// public void actionPerformed(ActionEvent arg) {
// try {
// URL url = new URL(libraryUri.getText());
// // System.out.println("Installing library: " + url);
// File libFile = downloadLibrary(url);
// if (libFile != null) {
// installLibrary(libFile);
// }
// } catch (MalformedURLException e) {
// System.err.println("Malformed URL");
// }
// libraryUri.setText("");
// }
// };
// installOrRemove.addActionListener(installLibAction);
clickedCard.setLayout(new BoxLayout(clickedCard, BoxLayout.X_AXIS));
briefText.setHighlighter(null);
briefText.setOpaque(false);
briefText.setEditable(false);
briefText.setLineWrap(true);
briefText.setWrapStyleWord(true);
Font font = this.briefText.getFont();
font = font.deriveFont(font.getSize() * 0.9f);
briefText.setFont(font);
clickedCard.add(briefText);
clickedCard.add(Box.createHorizontalGlue());
clickedCard.add(installOrRemove);
installOrRemove.setAlignmentY(Component.BOTTOM_ALIGNMENT);
briefText.setAlignmentY(Component.BOTTOM_ALIGNMENT);
installOrRemove.setText("Install");
Dimension installButtonDimensions = installOrRemove.getPreferredSize();
installButtonDimensions.width = 100;
installOrRemove.setPreferredSize(installButtonDimensions);
infoPanel.add(unclickedCard, unclickedCardId);
infoPanel.add(clickedCard, clickedCardId);
add(infoPanel);
}
/**
* Turns on/off the info panel which contains a brief description of the
* library and a button to Install/Remove a library.
*/
public void setShowInfo(boolean doShow) {
isInfoShown = doShow;
CardLayout cardLayout = (CardLayout) infoPanel.getLayout();
if (isInfoShown) {
setBackground(UIManager.getColor("List.selectionBackground"));
cascadeForgroundColor(this, UIManager.getColor("List.selectionForeground"));
cardLayout.show(infoPanel, clickedCardId);
} else {
setBackground(UIManager.getColor("List.background"));
cascadeForgroundColor(this, UIManager.getColor("List.foreground"));
cardLayout.show(infoPanel, unclickedCardId);
}
int width = getSize().width;
updateSize(width > 0 ? width : 100);
}
/**
* Updates the sizes of components in this panel given width as a constraint
*/
public void updateSize(int width) {
Dimension textDimentions = briefText.getPreferredSize();
textDimentions.width = width - installOrRemove.getPreferredSize().width;
textDimentions.height = calculateHeight(briefText, textDimentions.width);
briefText.setMaximumSize(textDimentions);
briefText.setMinimumSize(textDimentions);
briefText.setPreferredSize(textDimentions);
//briefText.setSize(textDimentions);
Dimension d;
if (isInfoShown) {
d = headerPanel.getPreferredSize();
d.width = width;
d.height += clickedCard.getPreferredSize().height + 2 * topAndBottomBorder;
} else {
d = headerPanel.getPreferredSize();
d.width = width;
d.height += 2 * topAndBottomBorder;
}
setMaximumSize(d);
setMinimumSize(d);
setPreferredSize(d);
//setSize(d);
revalidate();
}
}
public LibraryListPanel(ArrayList<LibraryInfo> libraries) {
super();
setLayout(new GridBagLayout());
int row = 0;
for (LibraryInfo libInfo : libraries) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 0;
c.gridy = row++;
add(new LibraryPanel(libInfo), c);
}
GridBagConstraints verticalFill = new GridBagConstraints();
verticalFill.fill = GridBagConstraints.VERTICAL;
verticalFill.weighty = 1;
verticalFill.gridx = 0;
verticalFill.gridy = row++;
add(Box.createVerticalGlue(), verticalFill);
}
/**
* Updates the widths of all library panels in this library list.
*/
public void setWidth(int newWidth) {
for (Component c : getComponents()) {
if (c instanceof LibraryPanel) {
((LibraryPanel) c).updateSize(newWidth);
}
}
updateLibraryListSize();
}
/**
* Updates the width and height of this library list based on the sizes of
* the library panes it contains.
*/
private void updateLibraryListSize() {
int height = 0;
int width = 0;
for (Component c : getComponents()) {
if (c.isVisible()) {
if (c instanceof LibraryListPanel) {
Dimension d = c.getSize();
if (d.width > width) {
width = d.width;
}
height += d.height;
}
}
}
setPreferredSize(new Dimension(width, height));
}
/**
* Sets the foreground color for a component and all of its subcompenents
* recursively.
*/
private static void cascadeForgroundColor(Component component, Color color) {
if (component instanceof Container) {
for (Component c : ((Container) component).getComponents()) {
cascadeForgroundColor(c, color);
}
}
if (component instanceof JLabel || component instanceof JTextComponent) {
component.setForeground(color);
}
}
/**
* Counts the numbers of lines needed to display the text in a JTextArea given
* a width as a contained. This assumed that both word wrap and wrap-style
* word are enabled for the JTextArea.
*/
private static int lineCount(JTextArea textArea, int width) {
AttributedString text = new AttributedString(textArea.getText());
FontRenderContext frc = textArea.getFontMetrics(textArea.getFont())
.getFontRenderContext();
AttributedCharacterIterator charIt = text.getIterator();
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc);
lineMeasurer.setPosition(charIt.getBeginIndex());
// Get lines from lineMeasurer until the entire
// paragraph has been displayed.
int noLines = 0;
while (lineMeasurer.getPosition() < charIt.getEndIndex()) {
lineMeasurer.nextLayout(width);
noLines++;
}
return noLines;
}
/**
* Calculates the height in pixels of the text in a JTextArea given a width
* as a contained. This assumed that both word wrap and wrap-style word are
* enabled for the JTextArea.
*/
private static int calculateHeight(JTextArea textArea, int width) {
Font font = textArea.getFont();
FontMetrics fontMetrics = textArea.getFontMetrics(font);
int lineHeight = fontMetrics.getAscent() + fontMetrics.getDescent();
return lineHeight * lineCount(textArea, width);
}
}

View File

@@ -32,6 +32,10 @@ import java.util.Iterator;
import java.util.zip.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import processing.app.LibraryListPanel.LibraryPanel;
/**
*
@@ -40,12 +44,8 @@ public class LibraryManager {
JFrame dialog;
JLabel uriLabel;
JTextField libraryUri;
JButton installButton;
LibraryListPanel libraryListPane;
// the calling editor, so updates can be applied
Editor editor;
@@ -60,44 +60,29 @@ public class LibraryManager {
Base.setIcon(dialog);
uriLabel = new JLabel("Library URI:");
libraryUri = new JTextField(40);
installButton = new JButton("Install");
ActionListener installLibAction = new ActionListener() {
public void actionPerformed(ActionEvent arg) {
try {
URL url = new URL(libraryUri.getText());
// System.out.println("Installing library: " + url);
File libFile = downloadLibrary(url);
if (libFile != null) {
installLibrary(libFile);
}
} catch (MalformedURLException e) {
System.err.println("Malformed URL");
}
libraryUri.setText("");
}
};
libraryUri.addActionListener(installLibAction);
installButton.addActionListener(installLibAction);
Container pane = dialog.getContentPane();
BoxLayout boxLayout = new BoxLayout(pane, BoxLayout.Y_AXIS);
pane.setLayout(boxLayout);
Box horizontal = Box.createHorizontalBox();
horizontal.add(Box.createVerticalStrut(2));
horizontal.add(uriLabel);
uriLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
horizontal.add(Box.createVerticalStrut(5));
horizontal.add(libraryUri);
horizontal.add(installButton);
pane.add(horizontal);
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
pane.setBackground(Color.red);
libraryListPane = new LibraryListPanel(fetchLibraryInfo());
final JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(libraryListPane);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
pane.add(scrollPane);
scrollPane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.getViewport().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent ce) {
int width = scrollPane.getViewportBorderBounds().width;
libraryListPane.setWidth(width);
}
});
dialog.setMinimumSize(new Dimension(400, 400));
dialog.pack();
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
dialog.setLocation((screen.width - dialog.getWidth()) / 2,
@@ -284,5 +269,52 @@ public class LibraryManager {
return 0;
}
/**
* Placeholder function which returns a list of information on libraries.
*/
public ArrayList<LibraryInfo> fetchLibraryInfo() {
ArrayList<LibraryInfo> libInfos = new ArrayList<LibraryInfo>();
LibraryInfo libInfo = new LibraryInfo();
libInfo.name = "BlobDetection";
libInfo.briefOverview = "Performs the computer vision technique of finding \"blobs\" in an image.";
libInfo.isInstalled = true;
libInfo.tags.add("blob");
libInfo.tags.add("vision");
libInfo.tags.add("image");
libInfos.add(libInfo);
libInfo = new LibraryInfo();
libInfo.name = "OpenCV";
libInfo.briefOverview = "An OpenCV implementation for processing including blob detection, face recognition and more. This library is highly recommended.";
libInfo.isInstalled = false;
libInfo.tags.add("face");
libInfo.tags.add("vision");
libInfo.tags.add("image");
libInfos.add(libInfo);
libInfo = new LibraryInfo();
libInfo.name = "SQLibrary";
libInfo.briefOverview = "A library to facilitate communication with MySQL or SQLite databases.";
libInfo.isInstalled = false;
libInfo.tags.add("database");
libInfos.add(libInfo);
return libInfos;
}
static class LibraryInfo {
String name;
String briefOverview;
String version;
String url;
ArrayList<String> tags;
boolean isInstalled;
public LibraryInfo() {
tags = new ArrayList<String>();
isInstalled = false;
}
}
}