Skip to content

Commit 1fbed83

Browse files
cmaglielmihalkovic
authored andcommitted
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 34cac1f commit 1fbed83

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)