Skip to content

Commit 6370a74

Browse files
committed
Split TableCellRenderes from TableCellEditors
This rationalization helps to better follow the swing abstractions of table models and increase separation of concerns. (WIP: ContributedPlatforms needs a similar refactoring that will be done in the next commits)
1 parent fd04767 commit 6370a74

File tree

6 files changed

+501
-407
lines changed

6 files changed

+501
-407
lines changed
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
package cc.arduino.contributions.libraries.ui;
2+
3+
import static processing.app.I18n.format;
4+
import static processing.app.I18n.tr;
5+
6+
import java.awt.Color;
7+
import java.awt.Component;
8+
import java.awt.Dimension;
9+
import java.awt.Insets;
10+
11+
import javax.swing.Box;
12+
import javax.swing.BoxLayout;
13+
import javax.swing.JButton;
14+
import javax.swing.JComboBox;
15+
import javax.swing.JLabel;
16+
import javax.swing.JPanel;
17+
import javax.swing.JTable;
18+
import javax.swing.JTextPane;
19+
import javax.swing.border.EmptyBorder;
20+
import javax.swing.event.HyperlinkEvent;
21+
import javax.swing.text.Document;
22+
import javax.swing.text.html.HTMLDocument;
23+
import javax.swing.text.html.StyleSheet;
24+
25+
import cc.arduino.contributions.DownloadableContributionVersionComparator;
26+
import cc.arduino.contributions.libraries.ContributedLibrary;
27+
import cc.arduino.contributions.ui.InstallerTableCell;
28+
import processing.app.Base;
29+
30+
public class ContributedLibraryTableCell {
31+
32+
protected final JPanel panel;
33+
protected final JButton installButton;
34+
protected final Component installButtonPlaceholder;
35+
protected final JComboBox downgradeChooser;
36+
protected final JComboBox versionToInstallChooser;
37+
protected final JButton downgradeButton;
38+
protected final JPanel buttonsPanel;
39+
protected final JPanel inactiveButtonsPanel;
40+
protected final JLabel statusLabel;
41+
42+
public ContributedLibraryTableCell() {
43+
installButton = new JButton(tr("Install"));
44+
int width = installButton.getPreferredSize().width;
45+
installButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1));
46+
47+
downgradeButton = new JButton(tr("Install"));
48+
49+
downgradeChooser = new JComboBox();
50+
downgradeChooser.addItem("-");
51+
downgradeChooser.setMaximumSize(downgradeChooser.getPreferredSize());
52+
downgradeChooser.addItemListener(e -> {
53+
Object selectVersionItem = downgradeChooser.getItemAt(0);
54+
boolean disableDowngrade = (e.getItem() == selectVersionItem);
55+
downgradeButton.setEnabled(!disableDowngrade);
56+
});
57+
58+
versionToInstallChooser = new JComboBox();
59+
versionToInstallChooser.addItem("-");
60+
versionToInstallChooser
61+
.setMaximumSize(versionToInstallChooser.getPreferredSize());
62+
63+
panel = new JPanel();
64+
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
65+
66+
makeNewDescription(panel);
67+
68+
buttonsPanel = new JPanel();
69+
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
70+
buttonsPanel.setOpaque(false);
71+
72+
buttonsPanel.add(Box.createHorizontalStrut(7));
73+
buttonsPanel.add(downgradeChooser);
74+
buttonsPanel.add(Box.createHorizontalStrut(5));
75+
buttonsPanel.add(downgradeButton);
76+
77+
buttonsPanel.add(Box.createHorizontalGlue());
78+
79+
buttonsPanel.add(versionToInstallChooser);
80+
buttonsPanel.add(Box.createHorizontalStrut(5));
81+
buttonsPanel.add(installButton);
82+
buttonsPanel.add(Box.createHorizontalStrut(5));
83+
buttonsPanel.add(Box.createHorizontalStrut(15));
84+
85+
panel.add(buttonsPanel);
86+
87+
inactiveButtonsPanel = new JPanel();
88+
inactiveButtonsPanel
89+
.setLayout(new BoxLayout(inactiveButtonsPanel, BoxLayout.X_AXIS));
90+
inactiveButtonsPanel.setOpaque(false);
91+
92+
int height = installButton.getMinimumSize().height;
93+
inactiveButtonsPanel.add(Box.createVerticalStrut(height));
94+
inactiveButtonsPanel.add(Box.createGlue());
95+
96+
statusLabel = new JLabel(" ");
97+
inactiveButtonsPanel.add(statusLabel);
98+
inactiveButtonsPanel.add(Box.createHorizontalStrut(15));
99+
100+
panel.add(inactiveButtonsPanel);
101+
102+
panel.add(Box.createVerticalStrut(15));
103+
}
104+
105+
void update(JTable parentTable, Object value, boolean isSelected,
106+
int row, boolean hasBuiltInRelease) {
107+
ContributedLibraryReleases releases = (ContributedLibraryReleases) value;
108+
109+
JTextPane description = makeNewDescription(panel);
110+
111+
// FIXME: happens on macosx, don't know why
112+
if (releases == null)
113+
return;
114+
115+
ContributedLibrary selected = releases.getSelected();
116+
ContributedLibrary installed = releases.getInstalled();
117+
118+
boolean installable, upgradable;
119+
if (installed == null) {
120+
installable = true;
121+
upgradable = false;
122+
} else {
123+
installable = false;
124+
upgradable = new DownloadableContributionVersionComparator()
125+
.compare(selected, installed) > 0;
126+
}
127+
if (installable) {
128+
installButton.setText(tr("Install"));
129+
}
130+
if (upgradable) {
131+
installButton.setText(tr("Update"));
132+
}
133+
installButton.setVisible(installable || upgradable);
134+
installButtonPlaceholder.setVisible(!(installable || upgradable));
135+
136+
String name = selected.getName();
137+
String author = selected.getAuthor();
138+
// String maintainer = selectedLib.getMaintainer();
139+
String website = selected.getWebsite();
140+
String sentence = selected.getSentence();
141+
String paragraph = selected.getParagraph();
142+
// String availableVer = selectedLib.getVersion();
143+
// String url = selected.getUrl();
144+
145+
String midcolor = isSelected ? "#000000" : "#888888";
146+
147+
String desc = "<html><body>";
148+
149+
// Library name...
150+
desc += format("<b>{0}</b>", name);
151+
if (installed != null && installed.isReadOnly()) {
152+
desc += " Built-In ";
153+
}
154+
155+
// ...author...
156+
desc += format("<font color=\"{0}\">", midcolor);
157+
if (author != null && !author.isEmpty()) {
158+
desc += format(" by <b>{0}</b>", author);
159+
}
160+
161+
// ...version.
162+
if (installed != null) {
163+
String installedVer = installed.getParsedVersion();
164+
if (installedVer == null) {
165+
desc += " " + tr("Version unknown");
166+
} else {
167+
desc += " " + format(tr("Version <b>{0}</b>"), installedVer);
168+
}
169+
}
170+
desc += "</font>";
171+
172+
if (installed != null) {
173+
desc += " <strong><font color=\"#00979D\">INSTALLED</font></strong>";
174+
}
175+
176+
desc += "<br/>";
177+
178+
// Description
179+
if (sentence != null) {
180+
desc += format("<b>{0}</b> ", sentence);
181+
if (paragraph != null && !paragraph.isEmpty())
182+
desc += format("{0}", paragraph);
183+
desc += "<br />";
184+
}
185+
if (author != null && !author.isEmpty()) {
186+
desc += format("<a href=\"{0}\">More info</a>", website);
187+
}
188+
189+
desc += "</body></html>";
190+
description.setText(desc);
191+
description.setBackground(Color.WHITE);
192+
193+
// for modelToView to work, the text area has to be sized. It doesn't
194+
// matter if it's visible or not.
195+
196+
// See:
197+
// http://stackoverflow.com/questions/3081210/how-to-set-jtextarea-to-have-height-that-matches-the-size-of-a-text-it-contains
198+
int width = parentTable.getBounds().width;
199+
InstallerTableCell.setJTextPaneDimensionToFitContainedText(description, width);
200+
201+
if (isSelected) {
202+
panel.setBackground(parentTable.getSelectionBackground());
203+
panel.setForeground(parentTable.getSelectionForeground());
204+
} else {
205+
panel.setBackground(parentTable.getBackground());
206+
panel.setForeground(parentTable.getForeground());
207+
}
208+
}
209+
210+
private static JTextPane makeNewDescription(JPanel panel) {
211+
if (panel.getComponentCount() > 0) {
212+
panel.remove(0);
213+
}
214+
JTextPane description = new JTextPane();
215+
description.setInheritsPopupMenu(true);
216+
Insets margin = description.getMargin();
217+
margin.bottom = 0;
218+
description.setMargin(margin);
219+
description.setContentType("text/html");
220+
Document doc = description.getDocument();
221+
if (doc instanceof HTMLDocument) {
222+
HTMLDocument html = (HTMLDocument) doc;
223+
StyleSheet stylesheet = html.getStyleSheet();
224+
stylesheet.addRule("body { margin: 0; padding: 0;"
225+
+ "font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"
226+
+ "font-size: 100%;" + "font-size: 0.95em; }");
227+
}
228+
description.setOpaque(false);
229+
description.setBorder(new EmptyBorder(4, 7, 7, 7));
230+
description.setHighlighter(null);
231+
description.setEditable(false);
232+
description.addHyperlinkListener(e -> {
233+
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
234+
Base.openURL(e.getDescription());
235+
}
236+
});
237+
// description.addKeyListener(new DelegatingKeyListener(parentTable));
238+
panel.add(description, 0);
239+
return description;
240+
}
241+
242+
243+
}

0 commit comments

Comments
 (0)