Skip to content

Commit c69e592

Browse files
committed
Improve Organization- and CourseListWindows
1 parent d8e228e commit c69e592

File tree

6 files changed

+98
-60
lines changed

6 files changed

+98
-60
lines changed

tmc-plugin/src/fi/helsinki/cs/tmc/ui/CourseCard.form

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
66
<Color blue="ff" green="ff" red="ff" type="rgb"/>
77
</Property>
8+
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
9+
<Border info="org.netbeans.modules.form.compat2.border.MatteColorBorderInfo">
10+
<MatteColorBorder bottom="5" left="10" right="10" top="5">
11+
<Color PropertyName="color" blue="f0" green="f1" red="f2" type="rgb"/>
12+
</MatteColorBorder>
13+
</Border>
14+
</Property>
815
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
916
<Dimension value="[332, 73]"/>
1017
</Property>
@@ -35,7 +42,7 @@
3542
<Group type="103" groupAlignment="0" attributes="0">
3643
<Group type="102" alignment="0" attributes="0">
3744
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
38-
<EmptySpace pref="161" max="32767" attributes="0"/>
45+
<EmptySpace pref="155" max="32767" attributes="0"/>
3946
<Component id="nameLabel" min="-2" max="-2" attributes="0"/>
4047
</Group>
4148
<Component id="infoScrollPane" alignment="0" max="32767" attributes="0"/>

tmc-plugin/src/fi/helsinki/cs/tmc/ui/CourseCard.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import fi.helsinki.cs.tmc.core.domain.Course;
44
import java.awt.Color;
55

6-
import javax.swing.text.DefaultCaret;
7-
86
public class CourseCard extends javax.swing.JPanel {
97

108
private Course course;
@@ -17,9 +15,6 @@ public CourseCard(Course course) {
1715

1816
this.course = course;
1917

20-
DefaultCaret caret = (DefaultCaret)this.informationLabel.getCaret();
21-
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
22-
2318
this.titleLabel.setText(course.getTitle());
2419
String information = course.getDescription();
2520
if (information == null || information.isEmpty()) {
@@ -60,6 +55,7 @@ private void initComponents() {
6055
informationLabel = new javax.swing.JTextArea();
6156

6257
setBackground(new java.awt.Color(255, 255, 255));
58+
setBorder(javax.swing.BorderFactory.createMatteBorder(5, 10, 5, 10, new java.awt.Color(242, 241, 240)));
6359
setMaximumSize(new java.awt.Dimension(332, 73));
6460
setMinimumSize(new java.awt.Dimension(332, 73));
6561
setPreferredSize(new java.awt.Dimension(346, 107));
@@ -97,7 +93,7 @@ private void initComponents() {
9793
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
9894
.addGroup(layout.createSequentialGroup()
9995
.addComponent(titleLabel)
100-
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 161, Short.MAX_VALUE)
96+
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 155, Short.MAX_VALUE)
10197
.addComponent(nameLabel))
10298
.addComponent(infoScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
10399
.addContainerGap())

tmc-plugin/src/fi/helsinki/cs/tmc/ui/CourseListWindow.java

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,36 @@
1010
import java.awt.Component;
1111
import java.awt.Dimension;
1212
import java.awt.Font;
13+
import java.awt.Insets;
1314
import java.awt.event.ActionEvent;
1415
import java.awt.event.ActionListener;
1516
import java.awt.event.MouseAdapter;
1617
import java.awt.event.MouseEvent;
1718
import java.awt.event.ComponentEvent;
1819
import java.awt.event.ComponentListener;
20+
import java.util.HashMap;
1921
import java.util.List;
22+
import java.util.Map;
2023

2124
import javax.swing.BoxLayout;
25+
import javax.swing.DefaultListCellRenderer;
2226
import javax.swing.JButton;
2327
import javax.swing.JFrame;
2428
import javax.swing.JLabel;
2529
import javax.swing.JList;
2630
import javax.swing.JOptionPane;
2731
import javax.swing.JPanel;
2832
import javax.swing.JScrollPane;
29-
import javax.swing.ListCellRenderer;
3033
import javax.swing.ListModel;
3134
import javax.swing.ListSelectionModel;
3235
import javax.swing.border.EmptyBorder;
36+
import javax.swing.border.MatteBorder;
3337

3438
public class CourseListWindow extends JPanel {
3539

3640
private static JFrame frame;
3741
private final JLabel title;
38-
private final JList<CourseCard> courses;
42+
private final JList<Course> courses;
3943
private PreferencesPanel prefPanel;
4044
private static JButton button;
4145

@@ -44,11 +48,11 @@ public CourseListWindow(List<Course> courses, PreferencesPanel prefPanel) {
4448
this.title = new JLabel("Select a course:");
4549
Font titleFont = this.title.getFont();
4650
this.title.setFont(new Font(titleFont.getName(), Font.BOLD, 20));
47-
CourseCard[] courseCards = new CourseCard[courses.size()];
48-
for (int i = 0; i < courses.size(); i++) {
49-
courseCards[i] = new CourseCard(courses.get(i));
50-
}
51-
this.courses = new JList<>(courseCards);
51+
this.title.setBorder(new MatteBorder(new Insets(10, 10, 5, 10), new Color(242, 241, 240)));
52+
Course[] courseArray = courses.toArray(new Course[courses.size()]);
53+
this.courses = new JList<>(courseArray);
54+
this.courses.setFixedCellHeight(107);
55+
this.courses.setFixedCellWidth(346);
5256
this.courses.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
5357
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
5458
this.button = new JButton("Select");
@@ -59,8 +63,11 @@ public CourseListWindow(List<Course> courses, PreferencesPanel prefPanel) {
5963
JScrollPane pane = new JScrollPane(this.courses);
6064
Dimension d = pane.getPreferredSize();
6165
d.width = 800;
66+
d.height = (int) (d.height * 1.12);
6267
pane.setPreferredSize(d);
63-
pane.setBorder(new EmptyBorder(5,0,5,0));
68+
pane.setBorder(new EmptyBorder(5, 0, 5, 0));
69+
pane.setViewportBorder(new EmptyBorder(0, 0, 0, 0));
70+
pane.getVerticalScrollBar().setUnitIncrement(10);
6471
this.courses.setBackground(new Color(242, 241, 240));
6572

6673
this.courses.setSelectedIndex(setDefaultSelectedIndex());
@@ -145,9 +152,9 @@ private int setDefaultSelectedIndex() {
145152
}
146153
String selectedCourseName = currentCourse.get().getName();
147154

148-
final ListModel<CourseCard> list = courses.getModel();
155+
final ListModel<Course> list = courses.getModel();
149156
for (int i = 0; i < list.getSize(); i++) {
150-
if (list.getElementAt(i).getCourse().getName().equals(selectedCourseName)) {
157+
if (list.getElementAt(i).getName().equals(selectedCourseName)) {
151158
return i;
152159
}
153160
}
@@ -162,31 +169,38 @@ public SelectCourseListener(CourseListWindow window) {
162169

163170
@Override
164171
public void actionPerformed(ActionEvent e) {
165-
prefPanel.setSelectedCourse(courses.getSelectedValue().getCourse());
172+
prefPanel.setSelectedCourse(courses.getSelectedValue());
166173
frame.setVisible(false);
167174
frame.dispose();
168175
new ShowSettingsAction().run();
169176
}
170177
}
171178
}
172179

173-
class CourseCellRenderer extends JLabel implements ListCellRenderer {
180+
class CourseCellRenderer extends DefaultListCellRenderer {
174181

175182
private static final Color HIGHLIGHT_COLOR = new Color(240, 119, 70);
176183

184+
private final Map<Course, CourseCard> cachedCourses;
185+
177186
public CourseCellRenderer() {
187+
this.cachedCourses = new HashMap<>();
178188
}
179189

180190
@Override
181191
public Component getListCellRendererComponent(final JList list,
182192
final Object value, final int index, final boolean isSelected,
183193
final boolean hasFocus) {
184-
CourseCard course = (CourseCard) value;
194+
final Course course = (Course)value;
195+
if (!this.cachedCourses.containsKey(course)) {
196+
this.cachedCourses.put(course, new CourseCard(course));
197+
}
198+
CourseCard courseCard = this.cachedCourses.get(course);
185199
if (isSelected) {
186-
course.setColors(Color.white, HIGHLIGHT_COLOR);
200+
courseCard.setColors(Color.white, HIGHLIGHT_COLOR);
187201
} else {
188-
course.setColors(new Color(76, 76, 76), Color.white);
202+
courseCard.setColors(new Color(76, 76, 76), Color.white);
189203
}
190-
return course;
204+
return courseCard;
191205
}
192206
}

tmc-plugin/src/fi/helsinki/cs/tmc/ui/OrganizationCard.java

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@
77
import java.net.MalformedURLException;
88
import java.net.URL;
99
import javax.swing.ImageIcon;
10-
import javax.swing.text.DefaultCaret;
10+
import javax.swing.JList;
1111

1212
public class OrganizationCard extends javax.swing.JPanel {
1313

1414
private final Organization organization;
15+
private ImageIcon image;
16+
private JList parent;
1517

16-
public OrganizationCard(Organization organization) {
18+
public OrganizationCard(Organization organization, JList parent) {
1719
initComponents();
1820

1921
this.organization = organization;
20-
21-
DefaultCaret caret = (DefaultCaret)this.organizationInformation.getCaret();
22-
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
22+
this.parent = parent;
2323

2424
this.organizationName.setText(organization.getName());
2525
String information = organization.getInformation();
@@ -28,12 +28,25 @@ public OrganizationCard(Organization organization) {
2828
}
2929
this.organizationInformation.setText(information);
3030
this.organizationSlug.setText("/" + organization.getSlug());
31-
ImageIcon image = new ImageIcon(getClass().getResource("placeholderLogo.png"));
32-
if (!organization.getLogoPath().contains("missing")) {
33-
image = new ImageIcon(logoUrl(organization.getLogoPath()));
31+
32+
setLogo();
33+
}
34+
35+
private void setLogo() {
36+
setLogo(getClass().getResource("placeholderLogo.png"));
37+
final String logoPath = organization.getLogoPath();
38+
if (!logoPath.contains("missing")) {
39+
new Thread(() -> {
40+
setLogo(logoUrl(logoPath));
41+
this.parent.repaint();
42+
}).start();
3443
}
35-
image.setImage(image.getImage().getScaledInstance(49, 49, java.awt.Image.SCALE_SMOOTH));
36-
this.logo.setIcon(image);
44+
}
45+
46+
private void setLogo(URL logoUrl) {
47+
this.image = new ImageIcon(logoUrl);
48+
this.image.setImage(this.image.getImage().getScaledInstance(49, 49, java.awt.Image.SCALE_SMOOTH));
49+
this.logo.setIcon(this.image);
3750
}
3851

3952
public Organization getOrganization() {

tmc-plugin/src/fi/helsinki/cs/tmc/ui/OrganizationListWindow.java

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.awt.Component;
1212
import java.awt.Dimension;
1313
import java.awt.Font;
14+
import java.awt.Insets;
1415
import java.awt.event.ActionEvent;
1516
import java.awt.event.ActionListener;
1617
import java.awt.event.MouseAdapter;
@@ -19,33 +20,36 @@
1920
import java.awt.event.ComponentListener;
2021
import java.io.IOException;
2122
import java.util.Collections;
23+
import java.util.HashMap;
2224
import java.util.List;
25+
import java.util.Map;
2326

2427
import javax.swing.BoxLayout;
28+
import javax.swing.DefaultListCellRenderer;
2529
import javax.swing.JButton;
2630
import javax.swing.JFrame;
2731
import javax.swing.JLabel;
2832
import javax.swing.JList;
2933
import javax.swing.JPanel;
3034
import javax.swing.JScrollPane;
31-
import javax.swing.ListCellRenderer;
3235
import javax.swing.ListModel;
3336
import javax.swing.ListSelectionModel;
3437
import javax.swing.border.EmptyBorder;
38+
import javax.swing.border.MatteBorder;
3539
import org.openide.util.Exceptions;
3640

3741
public class OrganizationListWindow extends JPanel {
3842

3943
private static JFrame frame;
4044
private final JLabel title;
41-
private final JList<OrganizationCard> organizations;
45+
private final JList<Organization> organizations;
4246
private static JButton button;
4347

4448
public OrganizationListWindow(List<Organization> organizations) {
4549
this.title = new JLabel("Select an organization:");
4650
Font titleFont = this.title.getFont();
4751
this.title.setFont(new Font(titleFont.getName(), Font.BOLD, 20));
48-
OrganizationCard[] organizationCards = new OrganizationCard[organizations.size()];
52+
this.title.setBorder(new MatteBorder(new Insets(10, 10, 5, 10), new Color(242, 241, 240)));
4953
Collections.sort(organizations, (a, b) -> {
5054
if (a.isPinned() && b.isPinned()) {
5155
return a.getName().compareTo(b.getName());
@@ -58,22 +62,25 @@ public OrganizationListWindow(List<Organization> organizations) {
5862
}
5963
return a.getName().compareTo(b.getName());
6064
});
61-
for (int i = 0; i < organizations.size(); i++) {
62-
organizationCards[i] = new OrganizationCard(organizations.get(i));
63-
}
64-
this.organizations = new JList<>(organizationCards);
65+
Organization[] orgArray = organizations.toArray(new Organization[organizations.size()]);
66+
this.organizations = new JList<>(orgArray);
67+
this.organizations.setFixedCellHeight(107);
68+
this.organizations.setFixedCellWidth(346);
6569
this.organizations.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
6670
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
6771
this.button = new JButton("Select");
6872
button.addActionListener(new SelectOrganizationListener(this));
6973

70-
this.organizations.setCellRenderer(new OrganizationCellRenderer());
74+
this.organizations.setCellRenderer(new OrganizationCellRenderer(this.organizations));
7175
this.organizations.setVisibleRowCount(4);
7276
JScrollPane pane = new JScrollPane(this.organizations);
7377
Dimension d = pane.getPreferredSize();
7478
d.width = 800;
79+
d.height = (int) (d.height * 1.12);
7580
pane.setPreferredSize(d);
7681
pane.setBorder(new EmptyBorder(5, 0, 5, 0));
82+
pane.setViewportBorder(new EmptyBorder(0, 0, 0, 0));
83+
pane.getVerticalScrollBar().setUnitIncrement(10);
7784
this.organizations.setBackground(new Color(242, 241, 240));
7885

7986
this.organizations.setSelectedIndex(setDefaultSelectedIndex());
@@ -138,9 +145,9 @@ private int setDefaultSelectedIndex() {
138145
if (!selectedOrganization.isPresent()) {
139146
return 0;
140147
}
141-
final ListModel<OrganizationCard> list = organizations.getModel();
148+
final ListModel<Organization> list = organizations.getModel();
142149
for (int i = 0; i < list.getSize(); i++) {
143-
if (list.getElementAt(i).getOrganization().getName().equals(selectedOrganization.get().getName())) {
150+
if (list.getElementAt(i).getName().equals(selectedOrganization.get().getName())) {
144151
return i;
145152
}
146153
}
@@ -154,8 +161,7 @@ public SelectOrganizationListener(OrganizationListWindow window) {
154161

155162
@Override
156163
public void actionPerformed(ActionEvent e) {
157-
final OrganizationCard organization = organizations.getSelectedValue();
158-
setColors(organization, Color.white, Color.black);
164+
final Organization organization = organizations.getSelectedValue();
159165
frame.setVisible(false);
160166
frame.dispose();
161167
try {
@@ -176,32 +182,34 @@ public void actionPerformed(ActionEvent e) {
176182
}
177183
}
178184
}
179-
180-
private void setColors(OrganizationCard organization, Color background, Color foreground) {
181-
organization.setBackground(background);
182-
for (Component c : organization.getComponents()) {
183-
c.setForeground(foreground);
184-
}
185-
}
186185
}
187186

188-
class OrganizationCellRenderer extends JLabel implements ListCellRenderer {
187+
class OrganizationCellRenderer extends DefaultListCellRenderer {
189188

190189
private static final Color HIGHLIGHT_COLOR = new Color(240, 119, 70);
190+
private final JList parent;
191+
private final Map<Organization, OrganizationCard> cachedOrgs;
191192

192-
public OrganizationCellRenderer() {
193+
public OrganizationCellRenderer(JList parent) {
194+
this.parent = parent;
195+
this.cachedOrgs = new HashMap<>();
193196
}
194197

195198
@Override
196199
public Component getListCellRendererComponent(final JList list,
197200
final Object value, final int index, final boolean isSelected,
198201
final boolean hasFocus) {
199-
OrganizationCard organization = (OrganizationCard) value;
202+
final Organization org = (Organization)value;
203+
if (!this.cachedOrgs.containsKey(org)) {
204+
OrganizationCard organization = new OrganizationCard(org, parent);
205+
this.cachedOrgs.put(org, organization);
206+
}
207+
OrganizationCard organizationCard = this.cachedOrgs.get(org);
200208
if (isSelected) {
201-
organization.setColors(Color.white, HIGHLIGHT_COLOR);
209+
organizationCard.setColors(Color.white, HIGHLIGHT_COLOR);
202210
} else {
203-
organization.setColors(new Color(76, 76, 76), Color.white);
211+
organizationCard.setColors(new Color(76, 76, 76), Color.white);
204212
}
205-
return organization;
213+
return organizationCard;
206214
}
207215
}

0 commit comments

Comments
 (0)