From 2c941d424e2a4d3ec37b9f3a61c7ba81828d77b2 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 1 Sep 2014 10:11:12 +0200 Subject: [PATCH] Factored installer GUI code --- .../ui/ContributedLibraryTableCell.java | 10 +- .../ui/LibrariesIndexTableModel.java | 5 +- .../contributions/ui/LibraryManagerUI.java | 269 +++-------------- .../ui/ContributedPlatformTableCell.java | 10 +- .../ui/ContributionIndexTableModel.java | 5 +- .../ui/ContributionManagerUI.java | 263 +++------------- .../ui/FilteredAbstractTableModel.java | 37 +++ app/src/cc/arduino/ui/InstallerJDialog.java | 281 ++++++++++++++++++ app/src/cc/arduino/ui/InstallerTableCell.java | 42 +++ 9 files changed, 452 insertions(+), 470 deletions(-) create mode 100644 app/src/cc/arduino/ui/FilteredAbstractTableModel.java create mode 100644 app/src/cc/arduino/ui/InstallerJDialog.java create mode 100644 app/src/cc/arduino/ui/InstallerTableCell.java diff --git a/app/src/cc/arduino/libraries/contributions/ui/ContributedLibraryTableCell.java b/app/src/cc/arduino/libraries/contributions/ui/ContributedLibraryTableCell.java index 717d1e637..b0c500dae 100644 --- a/app/src/cc/arduino/libraries/contributions/ui/ContributedLibraryTableCell.java +++ b/app/src/cc/arduino/libraries/contributions/ui/ContributedLibraryTableCell.java @@ -39,7 +39,6 @@ import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import javax.swing.AbstractCellEditor; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -49,8 +48,6 @@ import javax.swing.JTextPane; import javax.swing.border.EmptyBorder; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableCellRenderer; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.html.HTMLDocument; @@ -59,10 +56,10 @@ import javax.swing.text.html.StyleSheet; import processing.app.Base; import cc.arduino.libraries.contributions.ContributedLibrary; import cc.arduino.libraries.contributions.ui.LibrariesIndexTableModel.ContributedLibraryReleases; +import cc.arduino.ui.InstallerTableCell; @SuppressWarnings("serial") -public class ContributedLibraryTableCell extends AbstractCellEditor implements - TableCellEditor, TableCellRenderer { +public class ContributedLibraryTableCell extends InstallerTableCell { private JPanel panel; private JTextPane description; @@ -281,7 +278,8 @@ public class ContributedLibraryTableCell extends AbstractCellEditor implements return panel; } - void setEnabled(boolean enabled) { + @Override + public void setEnabled(boolean enabled) { installButton.setEnabled(enabled); removeButton.setEnabled(enabled); } diff --git a/app/src/cc/arduino/libraries/contributions/ui/LibrariesIndexTableModel.java b/app/src/cc/arduino/libraries/contributions/ui/LibrariesIndexTableModel.java index 7ba736899..7293ccdce 100644 --- a/app/src/cc/arduino/libraries/contributions/ui/LibrariesIndexTableModel.java +++ b/app/src/cc/arduino/libraries/contributions/ui/LibrariesIndexTableModel.java @@ -34,15 +34,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import javax.swing.table.AbstractTableModel; - import cc.arduino.libraries.contributions.ContributedLibrary; import cc.arduino.libraries.contributions.LibrariesIndexer; import cc.arduino.packages.contributions.ContributedPackage; import cc.arduino.packages.contributions.ContributedPlatform; +import cc.arduino.ui.FilteredAbstractTableModel; @SuppressWarnings("serial") -public class LibrariesIndexTableModel extends AbstractTableModel { +public class LibrariesIndexTableModel extends FilteredAbstractTableModel { public final static int DESCRIPTION_COL = 0; diff --git a/app/src/cc/arduino/libraries/contributions/ui/LibraryManagerUI.java b/app/src/cc/arduino/libraries/contributions/ui/LibraryManagerUI.java index 75b0551c4..c0ebd2718 100644 --- a/app/src/cc/arduino/libraries/contributions/ui/LibraryManagerUI.java +++ b/app/src/cc/arduino/libraries/contributions/ui/LibraryManagerUI.java @@ -28,216 +28,65 @@ */ package cc.arduino.libraries.contributions.ui; -import static cc.arduino.packages.contributions.ui.ContributionIndexTableModel.DESCRIPTION_COL; -import static processing.app.I18n._; - -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Container; import java.awt.Dialog; -import java.awt.Dimension; import java.awt.Frame; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.Collection; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.ListSelectionModel; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingUtilities; -import javax.swing.border.EmptyBorder; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableCellRenderer; -import javax.swing.table.TableColumn; -import javax.swing.table.TableColumnModel; - -import processing.app.Theme; import cc.arduino.libraries.contributions.ContributedLibrary; import cc.arduino.libraries.contributions.LibrariesIndexer; -import cc.arduino.ui.FilterJTextField; -import cc.arduino.ui.ProgressJProgressBar; +import cc.arduino.ui.FilteredAbstractTableModel; +import cc.arduino.ui.InstallerJDialog; +import cc.arduino.ui.InstallerTableCell; import cc.arduino.utils.Progress; @SuppressWarnings("serial") -public class LibraryManagerUI extends JDialog { +public class LibraryManagerUI extends InstallerJDialog { - private FilterJTextField filterField; + @Override + protected FilteredAbstractTableModel createContribModel() { + return new LibrariesIndexTableModel(); + } + + private LibrariesIndexTableModel getContribModel() { + return (LibrariesIndexTableModel) contribModel; + } - private JLabel categoryLabel; - private JComboBox categoryChooser; - private Component categoryStrut1; - private Component categoryStrut2; - private Component categoryStrut3; + @Override + protected InstallerTableCell createCellRenderer() { + return new ContributedLibraryTableCell(); + } - private LibrariesIndexTableModel contribModel = new LibrariesIndexTableModel(); - private JTable contribTable; - private ProgressJProgressBar progressBar; + @Override + protected InstallerTableCell createCellEditor() { + return new ContributedLibraryTableCell() { + @Override + protected void onInstall(ContributedLibrary selectedPlatform) { + onInstallPressed(selectedPlatform); + } - private Box progressBox; - private Box updateBox; - - private ContributedLibraryTableCell cellEditor; - - // Currently selected category and filters - private String category; - private String[] filters; + @Override + protected void onRemove(ContributedLibrary installedPlatform) { + onRemovePressed(installedPlatform); + } + }; + } public LibraryManagerUI(Frame parent) { super(parent, "Library Manager", Dialog.ModalityType.APPLICATION_MODAL); - - setResizable(true); - - Container pane = getContentPane(); - pane.setLayout(new BorderLayout()); - - { - categoryStrut1 = Box.createHorizontalStrut(5); - categoryStrut2 = Box.createHorizontalStrut(5); - categoryStrut3 = Box.createHorizontalStrut(5); - - categoryLabel = new JLabel(_("Category:")); - - categoryChooser = new JComboBox(); - categoryChooser.setMaximumRowCount(20); - categoryChooser.setEnabled(false); - - filterField = new FilterJTextField(_("Filter your search...")) { - @Override - protected void onFilter(String[] _filters) { - filters = _filters; - cellEditor.stopCellEditing(); - contribModel.updateIndexFilter(category, filters); - } - }; - - JPanel panel = new JPanel(); - panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); - panel.add(categoryStrut1); - panel.add(categoryLabel); - panel.add(categoryStrut2); - panel.add(categoryChooser); - panel.add(categoryStrut3); - panel.add(filterField); - panel.setBorder(new EmptyBorder(7, 7, 7, 7)); - pane.add(panel, BorderLayout.NORTH); - } - - contribTable = new JTable(contribModel); - contribTable.setTableHeader(null); - contribTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - contribTable.setColumnSelectionAllowed(false); - contribTable.setDragEnabled(false); - contribTable.setIntercellSpacing(new Dimension(0, 1)); - contribTable.setShowVerticalLines(false); - contribTable.setSelectionBackground(Theme.getColor("status.notice.bgcolor")); - { - TableColumnModel tcm = contribTable.getColumnModel(); - TableColumn col = tcm.getColumn(DESCRIPTION_COL); - col.setCellRenderer(new ContributedLibraryTableCell()); - cellEditor = new ContributedLibraryTableCell() { - @Override - protected void onInstall(ContributedLibrary selectedPlatform) { - onInstallPressed(selectedPlatform); - } - - @Override - protected void onRemove(ContributedLibrary installedPlatform) { - onRemovePressed(installedPlatform); - } - }; - col.setCellEditor(cellEditor); - col.setResizable(true); - } - - { - JScrollPane s = new JScrollPane(); - s.setViewportView(contribTable); - s.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - s.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - pane.add(s, BorderLayout.CENTER); - } - - pane.add(Box.createHorizontalStrut(10), BorderLayout.WEST); - pane.add(Box.createHorizontalStrut(10), BorderLayout.EAST); - - { - progressBar = new ProgressJProgressBar(); - progressBar.setStringPainted(true); - progressBar.setString(" "); - progressBar.setVisible(true); - - JButton cancelButton = new JButton(_("Cancel")); - cancelButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - onCancelPressed(); - } - }); - - JButton updateButton = new JButton(_("Update list")); - updateButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - onUpdatePressed(); - } - }); - - { - progressBox = Box.createHorizontalBox(); - progressBox.add(progressBar); - progressBox.add(Box.createHorizontalStrut(5)); - progressBox.add(cancelButton); - - updateBox = Box.createHorizontalBox(); - updateBox.add(Box.createHorizontalGlue()); - updateBox.add(updateButton); - - JPanel progressPanel = new JPanel(); - progressPanel.setBorder(new EmptyBorder(7, 7, 7, 7)); - progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.Y_AXIS)); - progressPanel.add(progressBox); - progressPanel.add(updateBox); - pane.add(progressPanel, BorderLayout.SOUTH); - - setProgressVisible(false); - } - } - - setMinimumSize(new Dimension(600, 450)); } - private TableModelListener tableModelListener = new TableModelListener() { - @Override - public void tableChanged(final TableModelEvent arg0) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - updateCellsHeight(arg0); - } - }); - } - }; - public void setIndexer(LibrariesIndexer indexer) { - contribModel.removeTableModelListener(tableModelListener); + getContribModel().removeTableModelListener(tableModelListener); categoryChooser.removeActionListener(categoryChooserActionListener); - contribModel.setIndexer(indexer); + // TODO: Remove setIndexer and make getContribModel + // return a FilteredAbstractTableModel + getContribModel().setIndexer(indexer); category = null; categoryChooser.removeAllItems(); - contribModel.addTableModelListener(tableModelListener); + getContribModel().addTableModelListener(tableModelListener); categoryChooser.addActionListener(categoryChooserActionListener); // Load categories @@ -261,46 +110,6 @@ public class LibraryManagerUI extends JDialog { }; } - ActionListener categoryChooserActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - String selected = (String) categoryChooser.getSelectedItem(); - if (category == null || !category.equals(selected)) { - category = selected; - cellEditor.stopCellEditing(); - contribModel.updateIndexFilter(category, filters); - } - } - }; - - public void setProgressVisible(boolean visible) { - progressBox.setVisible(visible); - - filterField.setEnabled(!visible); - categoryChooser.setEnabled(!visible); - contribTable.setEnabled(!visible); - updateBox.setVisible(!visible); - updateBox.setEnabled(!visible); - cellEditor.setEnabled(!visible); - - if (visible && contribTable.isEditing()) { - TableCellEditor editor = contribTable.getCellEditor(); - if (editor != null) - editor.stopCellEditing(); - } - } - - private void updateCellsHeight(TableModelEvent e) { - int first = e.getFirstRow(); - int last = Math.min(e.getLastRow(), contribTable.getRowCount() - 1); - for (int row = first; row <= last; row++) { - TableCellRenderer editor = new ContributedLibraryTableCell(); - Component comp = contribTable.prepareRenderer(editor, row, 0); - int height = comp.getPreferredSize().height; - contribTable.setRowHeight(row, height); - } - } - public void setProgress(Progress progress) { progressBar.setValue(progress); } @@ -312,12 +121,14 @@ public class LibraryManagerUI extends JDialog { private LibraryInstaller installer; private Thread installerThread = null; - public void onCancelPressed() { + @Override + protected void onCancelPressed() { if (installerThread != null) installerThread.interrupt(); } - public void onUpdatePressed() { + @Override + protected void onUpdatePressed() { installerThread = new Thread(new Runnable() { @Override public void run() { @@ -343,7 +154,7 @@ public class LibraryManagerUI extends JDialog { try { setProgressVisible(true); installer.install(lib); - contribModel.updateLibrary(lib); + getContribModel().updateLibrary(lib); } catch (Exception e) { // TODO Show ERROR e.printStackTrace(); @@ -362,7 +173,7 @@ public class LibraryManagerUI extends JDialog { try { setProgressVisible(true); installer.remove(lib); - contribModel.updateLibrary(lib); + getContribModel().updateLibrary(lib); } catch (Exception e) { // TODO Show ERROR e.printStackTrace(); diff --git a/app/src/cc/arduino/packages/contributions/ui/ContributedPlatformTableCell.java b/app/src/cc/arduino/packages/contributions/ui/ContributedPlatformTableCell.java index 795615f7b..96e37ed0a 100644 --- a/app/src/cc/arduino/packages/contributions/ui/ContributedPlatformTableCell.java +++ b/app/src/cc/arduino/packages/contributions/ui/ContributedPlatformTableCell.java @@ -38,7 +38,6 @@ import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import javax.swing.AbstractCellEditor; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -48,8 +47,6 @@ import javax.swing.JTextPane; import javax.swing.border.EmptyBorder; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableCellRenderer; import javax.swing.text.Document; import javax.swing.text.html.HTMLDocument; import javax.swing.text.html.StyleSheet; @@ -58,10 +55,10 @@ import processing.app.Base; import cc.arduino.packages.contributions.ContributedBoard; import cc.arduino.packages.contributions.ContributedPlatform; import cc.arduino.packages.contributions.ui.ContributionIndexTableModel.ContributedPlatformReleases; +import cc.arduino.ui.InstallerTableCell; @SuppressWarnings("serial") -public class ContributedPlatformTableCell extends AbstractCellEditor implements - TableCellEditor, TableCellRenderer { +public class ContributedPlatformTableCell extends InstallerTableCell { private JPanel panel; private JTextPane description; @@ -225,7 +222,8 @@ public class ContributedPlatformTableCell extends AbstractCellEditor implements return panel; } - void setEnabled(boolean enabled) { + @Override + public void setEnabled(boolean enabled) { installButton.setEnabled(enabled); removeButton.setEnabled(enabled); } diff --git a/app/src/cc/arduino/packages/contributions/ui/ContributionIndexTableModel.java b/app/src/cc/arduino/packages/contributions/ui/ContributionIndexTableModel.java index aa106c2e3..e4332302c 100644 --- a/app/src/cc/arduino/packages/contributions/ui/ContributionIndexTableModel.java +++ b/app/src/cc/arduino/packages/contributions/ui/ContributionIndexTableModel.java @@ -31,14 +31,13 @@ package cc.arduino.packages.contributions.ui; import java.util.ArrayList; import java.util.List; -import javax.swing.table.AbstractTableModel; - import cc.arduino.packages.contributions.ContributedPackage; import cc.arduino.packages.contributions.ContributedPlatform; import cc.arduino.packages.contributions.ContributionsIndex; +import cc.arduino.ui.FilteredAbstractTableModel; @SuppressWarnings("serial") -public class ContributionIndexTableModel extends AbstractTableModel { +public class ContributionIndexTableModel extends FilteredAbstractTableModel { public final static int DESCRIPTION_COL = 0; diff --git a/app/src/cc/arduino/packages/contributions/ui/ContributionManagerUI.java b/app/src/cc/arduino/packages/contributions/ui/ContributionManagerUI.java index 6320e72f0..9deebf651 100644 --- a/app/src/cc/arduino/packages/contributions/ui/ContributionManagerUI.java +++ b/app/src/cc/arduino/packages/contributions/ui/ContributionManagerUI.java @@ -28,218 +28,68 @@ */ package cc.arduino.packages.contributions.ui; -import static cc.arduino.packages.contributions.ui.ContributionIndexTableModel.DESCRIPTION_COL; -import static processing.app.I18n._; - -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Container; import java.awt.Dialog; -import java.awt.Dimension; import java.awt.Frame; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.Collection; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.ListSelectionModel; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingUtilities; -import javax.swing.border.EmptyBorder; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableCellRenderer; -import javax.swing.table.TableColumn; -import javax.swing.table.TableColumnModel; - import cc.arduino.packages.contributions.ContributedPlatform; import cc.arduino.packages.contributions.ContributionInstaller; import cc.arduino.packages.contributions.ContributionsIndexer; -import cc.arduino.ui.FilterJTextField; -import cc.arduino.ui.ProgressJProgressBar; +import cc.arduino.ui.FilteredAbstractTableModel; +import cc.arduino.ui.InstallerJDialog; +import cc.arduino.ui.InstallerTableCell; import cc.arduino.utils.Progress; @SuppressWarnings("serial") -public class ContributionManagerUI extends JDialog { +public class ContributionManagerUI extends InstallerJDialog { - private FilterJTextField filterField; + // private ContributedPlatformTableCell cellEditor; - private JLabel categoryLabel; - private JComboBox categoryChooser; - private Component categoryStrut1; - private Component categoryStrut2; - private Component categoryStrut3; + @Override + protected FilteredAbstractTableModel createContribModel() { + return new ContributionIndexTableModel(); + } - private ContributionIndexTableModel contribModel = new ContributionIndexTableModel(); - private JTable contribTable; - private ProgressJProgressBar progressBar; + private ContributionIndexTableModel getContribModel() { + return (ContributionIndexTableModel) contribModel; + } - private Box progressBox; - private Box updateBox; + @Override + protected InstallerTableCell createCellRenderer() { + return new ContributedPlatformTableCell(); + } - private ContributedPlatformTableCell cellEditor; + @Override + protected InstallerTableCell createCellEditor() { + return new ContributedPlatformTableCell() { + @Override + protected void onInstall(ContributedPlatform selectedPlatform) { + onInstallPressed(selectedPlatform); + } - // Currently selected category and filters - private String category; - private String[] filters; + @Override + protected void onRemove(ContributedPlatform installedPlatform) { + onRemovePressed(installedPlatform); + } + }; + } public ContributionManagerUI(Frame parent) { super(parent, "Boards Manager", Dialog.ModalityType.APPLICATION_MODAL); - - setResizable(true); - - Container pane = getContentPane(); - pane.setLayout(new BorderLayout()); - - { - categoryStrut1 = Box.createHorizontalStrut(5); - categoryStrut2 = Box.createHorizontalStrut(5); - categoryStrut3 = Box.createHorizontalStrut(5); - - categoryLabel = new JLabel(_("Category:")); - - categoryChooser = new JComboBox(); - categoryChooser.setMaximumRowCount(20); - categoryChooser.setEnabled(false); - - filterField = new FilterJTextField(_("Filter your search...")) { - @Override - protected void onFilter(String[] _filters) { - filters = _filters; - cellEditor.stopCellEditing(); - contribModel.updateIndexFilter(category, filters); - } - }; - - JPanel panel = new JPanel(); - panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); - panel.add(categoryStrut1); - panel.add(categoryLabel); - panel.add(categoryStrut2); - panel.add(categoryChooser); - panel.add(categoryStrut3); - panel.add(filterField); - panel.setBorder(new EmptyBorder(7, 7, 7, 7)); - pane.add(panel, BorderLayout.NORTH); - } - - contribTable = new JTable(contribModel); - contribTable.setTableHeader(null); - contribTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - contribTable.setColumnSelectionAllowed(false); - contribTable.setDragEnabled(false); - contribTable.setIntercellSpacing(new Dimension(0, 1)); - contribTable.setShowVerticalLines(false); - - { - TableColumnModel tcm = contribTable.getColumnModel(); - TableColumn col = tcm.getColumn(DESCRIPTION_COL); - col.setCellRenderer(new ContributedPlatformTableCell()); - cellEditor = new ContributedPlatformTableCell() { - @Override - protected void onInstall(ContributedPlatform selectedPlatform) { - onInstallPressed(selectedPlatform); - } - - @Override - protected void onRemove(ContributedPlatform installedPlatform) { - onRemovePressed(installedPlatform); - } - }; - col.setCellEditor(cellEditor); - col.setResizable(true); - } - - { - JScrollPane s = new JScrollPane(); - s.setViewportView(contribTable); - s.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - s.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - pane.add(s, BorderLayout.CENTER); - } - - pane.add(Box.createHorizontalStrut(10), BorderLayout.WEST); - pane.add(Box.createHorizontalStrut(10), BorderLayout.EAST); - - { - progressBar = new ProgressJProgressBar(); - progressBar.setStringPainted(true); - progressBar.setString(" "); - progressBar.setVisible(true); - - JButton cancelButton = new JButton(_("Cancel")); - cancelButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - onCancelPressed(); - } - }); - - JButton updateButton = new JButton(_("Update list")); - updateButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - onUpdatePressed(); - } - }); - - { - progressBox = Box.createHorizontalBox(); - progressBox.add(progressBar); - progressBox.add(Box.createHorizontalStrut(5)); - progressBox.add(cancelButton); - - updateBox = Box.createHorizontalBox(); - updateBox.add(Box.createHorizontalGlue()); - updateBox.add(updateButton); - - JPanel progressPanel = new JPanel(); - progressPanel.setBorder(new EmptyBorder(7, 7, 7, 7)); - progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.Y_AXIS)); - progressPanel.add(progressBox); - progressPanel.add(updateBox); - pane.add(progressPanel, BorderLayout.SOUTH); - - setProgressVisible(false); - } - } - - setMinimumSize(new Dimension(600, 450)); } - private TableModelListener tableModelListener = new TableModelListener() { - @Override - public void tableChanged(final TableModelEvent arg0) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - updateCellsHeight(arg0); - } - }); - } - }; - public void setIndexer(ContributionsIndexer indexer) { - contribModel.removeTableModelListener(tableModelListener); + getContribModel().removeTableModelListener(tableModelListener); categoryChooser.removeActionListener(categoryChooserActionListener); - contribModel.setIndex(indexer.getIndex()); + getContribModel().setIndex(indexer.getIndex()); category = null; categoryChooser.removeAllItems(); - filterField.setEnabled(contribModel.getRowCount() > 0); + filterField.setEnabled(getContribModel().getRowCount() > 0); - contribModel.addTableModelListener(tableModelListener); + getContribModel().addTableModelListener(tableModelListener); categoryChooser.addActionListener(categoryChooserActionListener); // Enable categories combo only if there are two or more choices @@ -259,46 +109,6 @@ public class ContributionManagerUI extends JDialog { }; } - ActionListener categoryChooserActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - String selected = (String) categoryChooser.getSelectedItem(); - if (category == null || !category.equals(selected)) { - category = selected; - cellEditor.stopCellEditing(); - contribModel.updateIndexFilter(category, filters); - } - } - }; - - public void setProgressVisible(boolean visible) { - progressBox.setVisible(visible); - - filterField.setEnabled(!visible); - categoryChooser.setEnabled(!visible); - contribTable.setEnabled(!visible); - updateBox.setVisible(!visible); - updateBox.setEnabled(!visible); - cellEditor.setEnabled(!visible); - - if (visible && contribTable.isEditing()) { - TableCellEditor editor = contribTable.getCellEditor(); - if (editor != null) - editor.stopCellEditing(); - } - } - - private void updateCellsHeight(TableModelEvent e) { - int first = e.getFirstRow(); - int last = Math.min(e.getLastRow(), contribTable.getRowCount() - 1); - for (int row = first; row <= last; row++) { - TableCellRenderer editor = new ContributedPlatformTableCell(); - Component comp = contribTable.prepareRenderer(editor, row, 0); - int height = comp.getPreferredSize().height; - contribTable.setRowHeight(row, height); - } - } - public void setProgress(Progress progress) { progressBar.setValue(progress); } @@ -310,11 +120,13 @@ public class ContributionManagerUI extends JDialog { private ContributionInstaller installer; private Thread installerThread = null; + @Override public void onCancelPressed() { if (installerThread != null) installerThread.interrupt(); } + @Override public void onUpdatePressed() { installerThread = new Thread(new Runnable() { @Override @@ -370,6 +182,11 @@ public class ContributionManagerUI extends JDialog { installerThread.start(); } + /** + * Callback invoked when indexes are updated + * + * @throws Exception + */ protected void onIndexesUpdated() throws Exception { // Empty } diff --git a/app/src/cc/arduino/ui/FilteredAbstractTableModel.java b/app/src/cc/arduino/ui/FilteredAbstractTableModel.java new file mode 100644 index 000000000..98c0be35d --- /dev/null +++ b/app/src/cc/arduino/ui/FilteredAbstractTableModel.java @@ -0,0 +1,37 @@ +/* + * This file is part of Arduino. + * + * Copyright 2014 Arduino LLC (http://www.arduino.cc/) + * + * Arduino is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + */ +package cc.arduino.ui; + +import javax.swing.table.AbstractTableModel; + +public abstract class FilteredAbstractTableModel extends AbstractTableModel { + + abstract public void updateIndexFilter(String category, String[] filters); + +} diff --git a/app/src/cc/arduino/ui/InstallerJDialog.java b/app/src/cc/arduino/ui/InstallerJDialog.java new file mode 100644 index 000000000..3dd611972 --- /dev/null +++ b/app/src/cc/arduino/ui/InstallerJDialog.java @@ -0,0 +1,281 @@ +/* + * This file is part of Arduino. + * + * Copyright 2014 Arduino LLC (http://www.arduino.cc/) + * + * Arduino is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + */ +package cc.arduino.ui; + +import static cc.arduino.packages.contributions.ui.ContributionIndexTableModel.DESCRIPTION_COL; +import static processing.app.I18n._; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingUtilities; +import javax.swing.border.EmptyBorder; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; + +import processing.app.Theme; + +public abstract class InstallerJDialog extends JDialog { + + // Toolbar on top of the window: + // - Categories drop-down menu + protected JLabel categoryLabel; + protected JComboBox categoryChooser; + protected Component categoryStrut1; + protected Component categoryStrut2; + protected Component categoryStrut3; + // - Search text-field + protected FilterJTextField filterField; + // Currently selected category and filters + protected String category; + protected String[] filters; + + // Real contribution table + protected JTable contribTable; + // Model behind the table + protected FilteredAbstractTableModel contribModel; + // Default table model listener + protected TableModelListener tableModelListener = new TableModelListener() { + @Override + public void tableChanged(final TableModelEvent event) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + updateCellsHeight(event); + } + }); + } + }; + + abstract protected FilteredAbstractTableModel createContribModel(); + + abstract protected InstallerTableCell createCellRenderer(); + + abstract protected InstallerTableCell createCellEditor(); + + // Bottom: + // - Progress bar + protected ProgressJProgressBar progressBar; + protected Box progressBox; + protected Box updateBox; + + protected InstallerTableCell cellEditor; + + public InstallerJDialog(Frame parent, String title, + ModalityType applicationModal) { + super(parent, title, applicationModal); + + setResizable(true); + + Container pane = getContentPane(); + pane.setLayout(new BorderLayout()); + + { + categoryStrut1 = Box.createHorizontalStrut(5); + categoryStrut2 = Box.createHorizontalStrut(5); + categoryStrut3 = Box.createHorizontalStrut(5); + + categoryLabel = new JLabel(_("Category:")); + + categoryChooser = new JComboBox(); + categoryChooser.setMaximumRowCount(20); + categoryChooser.setEnabled(false); + + filterField = new FilterJTextField(_("Filter your search...")) { + @Override + protected void onFilter(String[] _filters) { + filters = _filters; + cellEditor.stopCellEditing(); + contribModel.updateIndexFilter(category, filters); + } + }; + + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); + panel.add(categoryStrut1); + panel.add(categoryLabel); + panel.add(categoryStrut2); + panel.add(categoryChooser); + panel.add(categoryStrut3); + panel.add(filterField); + panel.setBorder(new EmptyBorder(7, 7, 7, 7)); + pane.add(panel, BorderLayout.NORTH); + } + + contribModel = createContribModel(); + contribTable = new JTable(contribModel); + contribTable.setTableHeader(null); + contribTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + contribTable.setColumnSelectionAllowed(false); + contribTable.setDragEnabled(false); + contribTable.setIntercellSpacing(new Dimension(0, 1)); + contribTable.setShowVerticalLines(false); + contribTable + .setSelectionBackground(Theme.getColor("status.notice.bgcolor")); + + { + TableColumnModel tcm = contribTable.getColumnModel(); + TableColumn col = tcm.getColumn(DESCRIPTION_COL); + col.setCellRenderer(createCellRenderer()); + cellEditor = createCellEditor(); + col.setCellEditor(cellEditor); + col.setResizable(true); + } + + { + JScrollPane s = new JScrollPane(); + s.setViewportView(contribTable); + s.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + s.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + pane.add(s, BorderLayout.CENTER); + } + + pane.add(Box.createHorizontalStrut(10), BorderLayout.WEST); + pane.add(Box.createHorizontalStrut(10), BorderLayout.EAST); + + progressBar = new ProgressJProgressBar(); + progressBar.setStringPainted(true); + progressBar.setString(" "); + progressBar.setVisible(true); + + { + JButton cancelButton = new JButton(_("Cancel")); + cancelButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + onCancelPressed(); + } + }); + + JButton updateButton = new JButton(_("Update list")); + updateButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + onUpdatePressed(); + } + }); + + progressBox = Box.createHorizontalBox(); + progressBox.add(progressBar); + progressBox.add(Box.createHorizontalStrut(5)); + progressBox.add(cancelButton); + + updateBox = Box.createHorizontalBox(); + updateBox.add(Box.createHorizontalGlue()); + updateBox.add(updateButton); + } + + { + JPanel progressPanel = new JPanel(); + progressPanel.setBorder(new EmptyBorder(7, 7, 7, 7)); + progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.Y_AXIS)); + progressPanel.add(progressBox); + progressPanel.add(updateBox); + pane.add(progressPanel, BorderLayout.SOUTH); + } + setProgressVisible(false); + + setMinimumSize(new Dimension(600, 450)); + } + + public void setProgressVisible(boolean visible) { + progressBox.setVisible(visible); + + filterField.setEnabled(!visible); + categoryChooser.setEnabled(!visible); + contribTable.setEnabled(!visible); + updateBox.setVisible(!visible); + updateBox.setEnabled(!visible); + cellEditor.setEnabled(!visible); + + if (visible && contribTable.isEditing()) { + TableCellEditor editor = contribTable.getCellEditor(); + if (editor != null) + editor.stopCellEditing(); + } + } + + private void updateCellsHeight(TableModelEvent e) { + int first = e.getFirstRow(); + int last = Math.min(e.getLastRow(), contribTable.getRowCount() - 1); + for (int row = first; row <= last; row++) { + TableCellRenderer editor = createCellRenderer(); + Component comp = contribTable.prepareRenderer(editor, row, 0); + int height = comp.getPreferredSize().height; + contribTable.setRowHeight(row, height); + } + } + + protected ActionListener categoryChooserActionListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + String selected = (String) categoryChooser.getSelectedItem(); + if (category == null || !category.equals(selected)) { + category = selected; + cellEditor.stopCellEditing(); + contribModel.updateIndexFilter(category, filters); + } + } + }; + + /** + * Action performed when the Cancel button is pressed. + */ + protected void onCancelPressed() { + // Empty + } + + /** + * Action performed when the "Update List" button is pressed. + */ + protected void onUpdatePressed() { + // Empty + } + +} diff --git a/app/src/cc/arduino/ui/InstallerTableCell.java b/app/src/cc/arduino/ui/InstallerTableCell.java new file mode 100644 index 000000000..b400aa687 --- /dev/null +++ b/app/src/cc/arduino/ui/InstallerTableCell.java @@ -0,0 +1,42 @@ +/* + * This file is part of Arduino. + * + * Copyright 2014 Arduino LLC (http://www.arduino.cc/) + * + * Arduino is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + */ +package cc.arduino.ui; + +import javax.swing.AbstractCellEditor; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; + +public abstract class InstallerTableCell extends AbstractCellEditor implements + TableCellEditor, TableCellRenderer { + + public void setEnabled(boolean b) { + // Empty + } + +}