/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy 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 3 of the License, or * (at your option) any later version. * * Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.gui.preferences; import icy.gui.component.IcyTable; import icy.gui.component.IcyTextField; import icy.gui.component.IcyTextField.TextChangeListener; import icy.gui.util.ComponentUtil; import icy.preferences.RepositoryPreferences; import icy.preferences.RepositoryPreferences.RepositoryInfo; import icy.system.thread.ThreadUtil; import icy.util.StringUtil; import icy.workspace.Workspace; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; /** * @author Stephane */ public abstract class WorkspaceListPreferencePanel extends PreferencePanel implements TextChangeListener, ListSelectionListener { /** * */ private static final long serialVersionUID = -264986966623111155L; private static final String BOTTOM_MESS = "*Workspace modification need application restart to take effect"; static final String[] columnNames = {"Name", "Description", "", "Enabled"}; // protected final Preferences preferences; List<Workspace> workspaces; final AbstractTableModel tableModel; final JTable table; final JComboBox repository; final JPanel repositoryPanel; final IcyTextField filter; final JButton refreshButton; final JButton action1Button; private final Runnable buttonsStateUpdater; private final Runnable tableDataRefresher; private final Runnable workspaceListRefresher; private final Runnable repositoriesUpdater; final ActionListener repositoryActionListener; WorkspaceListPreferencePanel(PreferenceFrame parent, String nodeName) { super(parent, nodeName, WorkspacePreferencePanel.NODE_NAME); // preferences = Preferences.userRoot().node(preferencesId); workspaces = new ArrayList<Workspace>(); buttonsStateUpdater = new Runnable() { @Override public void run() { // need to be done on EDT ThreadUtil.invokeNow(new Runnable() { @Override public void run() { updateButtonsStateInternal(); } }); } }; tableDataRefresher = new Runnable() { @Override public void run() { // need to be done on EDT ThreadUtil.invokeNow(new Runnable() { @Override public void run() { refreshTableDataInternal(); } }); } }; workspaceListRefresher = new Runnable() { @Override public void run() { refreshWorkspacesInternal(); } }; repositoriesUpdater = new Runnable() { @Override public void run() { // need to be done on EDT ThreadUtil.invokeNow(new Runnable() { @Override public void run() { updateRepositoriesInternal(); } }); } }; repositoryActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { repositoryChanged(); } }; // build repository comboBox repository = new JComboBox(); repository.setToolTipText("Select a repository"); repository.addActionListener(repositoryActionListener); repositoryPanel = new JPanel(); repositoryPanel.setLayout(new BoxLayout(repositoryPanel, BoxLayout.PAGE_AXIS)); repositoryPanel.setVisible(false); final JPanel internalRepPanel = new JPanel(); internalRepPanel.setLayout(new BoxLayout(internalRepPanel, BoxLayout.LINE_AXIS)); internalRepPanel.add(new JLabel("Repository :")); internalRepPanel.add(Box.createHorizontalStrut(8)); internalRepPanel.add(repository); internalRepPanel.add(Box.createHorizontalGlue()); repositoryPanel.add(internalRepPanel); repositoryPanel.add(Box.createVerticalStrut(8)); // need filter before load() filter = new IcyTextField(); filter.addTextChangeListener(this); load(); // build buttons panel final Dimension buttonsDim = new Dimension(100, 24); refreshButton = new JButton("Reload list"); refreshButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { reloadWorkspaces(); } }); ComponentUtil.setFixedSize(refreshButton, buttonsDim); action1Button = new JButton("null"); action1Button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { doAction1(getSelectedWorkspace()); } }); action1Button.setVisible(false); ComponentUtil.setFixedSize(action1Button, buttonsDim); final JPanel buttonsPanel = new JPanel(); buttonsPanel.setBorder(BorderFactory.createEmptyBorder(4, 8, 8, 8)); buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.PAGE_AXIS)); buttonsPanel.add(refreshButton); buttonsPanel.add(Box.createVerticalStrut(64)); buttonsPanel.add(action1Button); buttonsPanel.add(Box.createVerticalStrut(8)); buttonsPanel.add(Box.createVerticalGlue()); // build table tableModel = new AbstractTableModel() { /** * */ private static final long serialVersionUID = -8573364273165723214L; @Override public int getColumnCount() { return WorkspaceListPreferencePanel.this.getColumnCount(); } @Override public String getColumnName(int column) { return columnNames[column]; } @Override public int getRowCount() { return workspaces.size(); } @Override public Object getValueAt(int row, int column) { final Workspace workspace = workspaces.get(row); switch (column) { case 0: return workspace.getName(); case 1: return workspace.getDescription(); case 2: return getStateValue(workspace); case 3: return isWorkspaceEnable(workspace); } return ""; } @Override public boolean isCellEditable(int row, int column) { return (column == 3); } @Override public Class<?> getColumnClass(int columnIndex) { if (columnIndex == 3) return Boolean.class; return String.class; } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { final Workspace workspace = workspaces.get(rowIndex); if ((columnIndex == 3) && (aValue instanceof Boolean)) setWorkspaceEnable(workspace, (Boolean) aValue); // workspace setting changed, restart needed getPreferenceFrame().setNeedRestart(); } }; table = new IcyTable(tableModel); final TableColumnModel colModel = table.getColumnModel(); TableColumn col; // columns setting col = colModel.getColumn(0); col.setMinWidth(80); col.setPreferredWidth(100); col.setMaxWidth(120); col = colModel.getColumn(1); col.setMinWidth(160); col.setPreferredWidth(240); col.setMaxWidth(500); col = colModel.getColumn(2); col.setMinWidth(60); col.setPreferredWidth(70); col.setMaxWidth(80); if (colModel.getColumnCount() > 3) { col = colModel.getColumn(3); col.setMinWidth(60); col.setPreferredWidth(60); col.setMaxWidth(60); } table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.getSelectionModel().addListSelectionListener(this); table.setColumnSelectionAllowed(false); table.setRowSelectionAllowed(true); table.setRowHeight(24); table.setShowVerticalLines(false); table.setAutoCreateRowSorter(true); table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); final JPanel tableTopPanel = new JPanel(); tableTopPanel.setLayout(new BoxLayout(tableTopPanel, BoxLayout.PAGE_AXIS)); tableTopPanel.add(Box.createVerticalStrut(2)); tableTopPanel.add(repositoryPanel); tableTopPanel.add(filter); tableTopPanel.add(Box.createVerticalStrut(8)); tableTopPanel.add(table.getTableHeader()); final JPanel tablePanel = new JPanel(); tablePanel.setLayout(new BorderLayout()); tablePanel.add(tableTopPanel, BorderLayout.NORTH); tablePanel.add(new JScrollPane(table), BorderLayout.CENTER); mainPanel.setLayout(new BorderLayout()); mainPanel.add(tablePanel, BorderLayout.CENTER); mainPanel.add(buttonsPanel, BorderLayout.EAST); mainPanel.add(new JLabel(BOTTOM_MESS), BorderLayout.SOUTH); mainPanel.validate(); } @Override protected void closed() { super.closed(); // do not retains workspaces when frame is closed workspaces.clear(); } private List<Workspace> filterList(List<Workspace> list, String filter) { final List<Workspace> result = new ArrayList<Workspace>(); final boolean empty = StringUtil.isEmpty(filter, true); final String filterUp; if (!empty) filterUp = filter.toUpperCase(); else filterUp = ""; for (Workspace workspace : list) { final String name = workspace.getName().toUpperCase(); final String desc = workspace.getDescription().toUpperCase(); // search in name and description if (empty || (name.indexOf(filterUp) != -1) || (desc.indexOf(filterUp) != -1)) result.add(workspace); } return result; } protected abstract void doAction1(Workspace workspace); protected abstract void repositoryChanged(); protected abstract void reloadWorkspaces(); protected abstract String getStateValue(Workspace workspace); protected abstract int getColumnCount(); protected abstract List<Workspace> getWorkspaces(); protected abstract void updateButtonsStateInternal(); protected final void updateButtonsState() { ThreadUtil.runSingle(buttonsStateUpdater); } protected void updateRepositoriesInternal() { // final RepositoryPreferencePanel panel = (RepositoryPreferencePanel) // getPreferencePanel(RepositoryPreferencePanel.class); // // refresh repositories list (use list from GUI) // final ArrayList<RepositoryInfo> repositeries = panel.repositories; // refresh repositories list final ArrayList<RepositoryInfo> repositeries = RepositoryPreferences.getRepositeries(); final RepositoryInfo savedRepository = (RepositoryInfo) repository.getSelectedItem(); // needed to disable events during update time repository.removeActionListener(repositoryActionListener); repository.removeAllItems(); for (RepositoryInfo repos : repositeries) if (repos.isEnabled()) repository.addItem(repos); repository.setEnabled(true); repository.addActionListener(repositoryActionListener); boolean selected = false; // try to set back the old selected repository if (savedRepository != null) { final String repositoryName = savedRepository.getName(); for (int ind = 0; ind < repository.getItemCount(); ind++) { final RepositoryInfo repo = (RepositoryInfo) repository.getItemAt(ind); if ((repo != null) && (repo.getName().equals(repositoryName))) { repository.setSelectedIndex(ind); selected = true; break; } } } // manually launch the action if (!selected) repository.setSelectedIndex((repository.getItemCount() > 0) ? 0 : -1); // avoid automatic minimum size here repository.setMinimumSize(new Dimension(48, 18)); } protected final void updateRepositories() { ThreadUtil.runSingle(repositoriesUpdater); } protected Boolean isWorkspaceEnable(Workspace workspace) { return Boolean.FALSE; } protected void setWorkspaceEnable(Workspace workspace, Boolean value) { // ignore } protected void refreshWorkspacesInternal() { workspaces = filterList(getWorkspaces(), filter.getText()); // refresh table data refreshTableData(); } protected final void refreshWorkspaces() { ThreadUtil.runSingle(workspaceListRefresher); } protected int getWorkspaceIndex(Workspace workspace) { return workspaces.indexOf(workspace); } protected int getWorkspaceModelIndex(Workspace workspace) { return getWorkspaceIndex(workspace); } protected int getWorkspaceTableIndex(Workspace workspace) { final int ind = getWorkspaceModelIndex(workspace); if (ind == -1) return ind; try { return table.convertRowIndexToView(ind); } catch (IndexOutOfBoundsException e) { return -1; } } Workspace getSelectedWorkspace() { int index; index = table.getSelectedRow(); if (index == -1) return null; try { index = table.convertRowIndexToModel(index); } catch (IndexOutOfBoundsException e) { index = -1; } if ((index < 0) || (index >= workspaces.size())) return null; return workspaces.get(index); } void setSelectedWorkspace(Workspace workspace) { final int index = getWorkspaceTableIndex(workspace); if (index > -1) { table.clearSelection(); table.getSelectionModel().setSelectionInterval(index, index); } } @Override protected void load() { } @Override protected void save() { // reload repositories as some parameter as beta flag can have changed updateRepositories(); } protected void refreshTableDataInternal() { final Workspace workspace = getSelectedWorkspace(); tableModel.fireTableDataChanged(); // restore previous selected workspace if possible setSelectedWorkspace(workspace); // update buttons state updateButtonsState(); } protected final void refreshTableData() { ThreadUtil.runSingle(tableDataRefresher); } protected void workspacesChanged() { refreshWorkspaces(); } @Override public void textChanged(IcyTextField source, boolean validate) { workspacesChanged(); } @Override public void valueChanged(ListSelectionEvent e) { updateButtonsState(); } }