This is an automated email from the git hooks/post-receive script. New commit to branch sync-timebundle in repository jtimer. See https://gitlab.nuiton.org/chorem/jtimer.git commit fa131fdf539352df0e7ebf2f85d9e5332c58acd8 Author: Eric Chatellier <chatellier@codelutin.com> Date: Tue Mar 7 14:10:03 2017 +0100 Refactoring of checkbox cell renderer and editor --- .../chorem/jtimer/plugins/timebundle/SyncView.java | 20 ++- .../org/chorem/jtimer/ui/report/ReportView.java | 10 +- ...Editor.java => CheckBoxCellEditorRenderer.java} | 135 +++++++++++++++++---- .../jtimer/ui/tree/CheckBoxTreeCellComponent.java | 112 ----------------- .../jtimer/ui/tree/CheckBoxTreeCellRenderer.java | 71 ----------- 5 files changed, 128 insertions(+), 220 deletions(-) diff --git a/src/main/java/org/chorem/jtimer/plugins/timebundle/SyncView.java b/src/main/java/org/chorem/jtimer/plugins/timebundle/SyncView.java index b8e32c2..e923067 100644 --- a/src/main/java/org/chorem/jtimer/plugins/timebundle/SyncView.java +++ b/src/main/java/org/chorem/jtimer/plugins/timebundle/SyncView.java @@ -24,13 +24,11 @@ package org.chorem.jtimer.plugins.timebundle; import org.chorem.jtimer.JTimerService; import org.chorem.jtimer.entities.TimerProject; -import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.plugins.timebundle.data.RemoteProject; import org.chorem.jtimer.plugins.timebundle.data.RemoteTask; import org.chorem.jtimer.plugins.timebundle.model.RemoteTaskTreeModel; import org.chorem.jtimer.plugins.timebundle.model.RemoveTaskCellRenderer; -import org.chorem.jtimer.ui.tree.CheckBoxTreeCellEditor; -import org.chorem.jtimer.ui.tree.CheckBoxTreeCellRenderer; +import org.chorem.jtimer.ui.tree.CheckBoxCellEditorRenderer; import org.chorem.jtimer.ui.tree.TaskTreeModel; import org.jdesktop.application.Application; import org.jdesktop.application.FrameView; @@ -53,8 +51,6 @@ import java.awt.event.WindowListener; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Set; -import java.util.TreeSet; public class SyncView extends FrameView implements TreeSelectionListener, WindowListener { @@ -128,9 +124,9 @@ public class SyncView extends FrameView implements TreeSelectionListener, Window projectsTree.setEditable(true); projectsTree.setShowsRootHandles(true); projectsTree.setModel(treeModel); - TreeSet<TimerTask> selection = new TreeSet<>(); - projectsTree.setCellRenderer(new CheckBoxTreeCellRenderer(service, projectsTree, selection, false)); - projectsTree.setCellEditor(new CheckBoxTreeCellEditor(service, projectsTree, selection, false)); + CheckBoxCellEditorRenderer checkBoxCellEditorRenderer = new CheckBoxCellEditorRenderer(service, projectsTree); + projectsTree.setCellRenderer(checkBoxCellEditorRenderer); + projectsTree.setCellEditor(checkBoxCellEditorRenderer); projectsTree.expandPath(new TreePath(treeModel.getRoot()).pathByAddingChild(timerProject)); JScrollPane treeScroll = new JScrollPane(projectsTree); mainPanel.add(treeScroll, new GridBagConstraints(2, 1, 1, 1, 1, 1, @@ -164,9 +160,11 @@ public class SyncView extends FrameView implements TreeSelectionListener, Window @Override public void valueChanged(TreeSelectionEvent treeSelectionEvent) { RemoteTask task = (RemoteTask)treeSelectionEvent.getPath().getLastPathComponent(); - Set<TimerTask> selection = task.getSyncTasks(); - projectsTree.setCellRenderer(new CheckBoxTreeCellRenderer(service, projectsTree, selection, false)); - projectsTree.setCellEditor(new CheckBoxTreeCellEditor(service, projectsTree, selection, false)); + CheckBoxCellEditorRenderer checkBoxCellEditorRenderer = new CheckBoxCellEditorRenderer(service, projectsTree); + checkBoxCellEditorRenderer.setCheckedTaskSet(task.getSyncTasks()); + checkBoxCellEditorRenderer.setDisableSubChecked(true); + projectsTree.setCellRenderer(checkBoxCellEditorRenderer); + projectsTree.setCellEditor(checkBoxCellEditorRenderer); projectsTree.validate(); } diff --git a/src/main/java/org/chorem/jtimer/ui/report/ReportView.java b/src/main/java/org/chorem/jtimer/ui/report/ReportView.java index 79469fc..2ae6c45 100644 --- a/src/main/java/org/chorem/jtimer/ui/report/ReportView.java +++ b/src/main/java/org/chorem/jtimer/ui/report/ReportView.java @@ -29,8 +29,7 @@ import org.chorem.jtimer.JTimerService; import org.chorem.jtimer.entities.TimerProject; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.ui.report.ReportGenerator.Type; -import org.chorem.jtimer.ui.tree.CheckBoxTreeCellEditor; -import org.chorem.jtimer.ui.tree.CheckBoxTreeCellRenderer; +import org.chorem.jtimer.ui.tree.CheckBoxCellEditorRenderer; import org.chorem.jtimer.ui.tree.TaskTreeModel; import org.jdesktop.application.Action; import org.jdesktop.application.Application; @@ -268,8 +267,11 @@ public class ReportView extends FrameView implements DocumentListener { projectsTree.setShowsRootHandles(true); projectsTree.setEditable(true); projectsTree.setModel(new TaskTreeModel(service)); - projectsTree.setCellEditor(new CheckBoxTreeCellEditor(service, projectsTree, uncheckedTaskSet, true)); - projectsTree.setCellRenderer(new CheckBoxTreeCellRenderer(service, projectsTree, uncheckedTaskSet, true)); + CheckBoxCellEditorRenderer checkBoxCellEditorRenderer = new CheckBoxCellEditorRenderer(service, projectsTree); + checkBoxCellEditorRenderer.setCheckedTaskSet(uncheckedTaskSet); + checkBoxCellEditorRenderer.setUncheck(true); + projectsTree.setCellEditor(checkBoxCellEditorRenderer); + projectsTree.setCellRenderer(checkBoxCellEditorRenderer); JScrollPane jspTable = new JScrollPane(projectsTree); panelProjects.add(jspTable, new GridBagConstraints(0, 1, 1, 1, 1, 1, diff --git a/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxTreeCellEditor.java b/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxCellEditorRenderer.java similarity index 55% rename from src/main/java/org/chorem/jtimer/ui/tree/CheckBoxTreeCellEditor.java rename to src/main/java/org/chorem/jtimer/ui/tree/CheckBoxCellEditorRenderer.java index b950161..25114af 100644 --- a/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxTreeCellEditor.java +++ b/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxCellEditorRenderer.java @@ -33,17 +33,20 @@ import javax.swing.JTree; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.tree.TreeCellEditor; +import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreePath; +import java.awt.Color; import java.awt.Component; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.Collection; import java.util.EventObject; +import java.util.HashSet; import java.util.Set; /** - * JCheckBox tree node cell editor. + * JCheckBox tree node cell component. * * @author chatellier * @version $Revision$ @@ -51,14 +54,28 @@ import java.util.Set; * Last update : $Date$ * By : $Author$ */ -public class CheckBoxTreeCellEditor extends CheckBoxTreeCellComponent implements - TreeCellEditor, ItemListener { +public class CheckBoxCellEditorRenderer extends JCheckBox implements TreeCellRenderer, TreeCellEditor, ItemListener { + + /** log */ + private static Log log = LogFactory.getLog(CheckBoxCellEditorRenderer.class); /** serialVersionUID */ private static final long serialVersionUID = 2497464481840318274L; - /** log */ - private static Log log = LogFactory.getLog(CheckBoxTreeCellEditor.class); + /** Timer service. */ + protected JTimerService service; + + /** Parent tree. */ + protected JTree parentTree; + + /** Unchecked task set. */ + protected Set<TimerTask> checkedTaskSet; + + /** To uncheck instead of checking. */ + protected boolean uncheck; + + /** Disable sub elements if parent is checked. */ + protected boolean disableSubChecked; /** {@link CellEditorListener}s */ protected Collection<CellEditorListener> cellEditorListeners; @@ -66,18 +83,68 @@ public class CheckBoxTreeCellEditor extends CheckBoxTreeCellComponent implements /** * Constructor. * - * @param service service - * @param parentTree tree - * @param checkedTaskSet common unselected tasks list - * @param uncheck to uncheck instead of check by default + * @param service service reference + * @param parentTree tree reference */ - public CheckBoxTreeCellEditor(JTimerService service, JTree parentTree, Set<TimerTask> checkedTaskSet, boolean uncheck) { - super(service, parentTree, checkedTaskSet, uncheck); - addItemListener(this); + public CheckBoxCellEditorRenderer(JTimerService service, JTree parentTree) { + this.service = service; + this.parentTree = parentTree; + this.checkedTaskSet = new HashSet<>(); + addItemListener(this); cellEditorListeners = new ArrayList<>(); } + public void setCheckedTaskSet(Set<TimerTask> checkedTaskSet) { + this.checkedTaskSet = checkedTaskSet; + } + + public void setUncheck(boolean uncheck) { + this.uncheck = uncheck; + } + + public void setDisableSubChecked(boolean disableSubChecked) { + this.disableSubChecked = disableSubChecked; + } + + /** + * Generic check box component. + * + * @param tree tree + * @param value value + * @param selected selected + * @param expanded expanded + * @param leaf leaf + * @param row row + * @return check box component + */ + protected Component getCheckBoxComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) { + + // if this is a task + if (value instanceof TimerTask) { + TimerTask task = (TimerTask) value; + + // task name should not be "null" + this.setText(task.getName()); + + // add color if task is closed + if (task.isClosed()) { + this.setForeground(Color.GRAY); + } else { + this.setForeground(Color.BLACK); + } + + // set checked ? + if (checkedTaskSet.contains(task) == uncheck) { + this.setSelected(false); + } else { + this.setSelected(true); + } + } + + return this; + } + @Override public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) { @@ -146,9 +213,9 @@ public class CheckBoxTreeCellEditor extends CheckBoxTreeCellComponent implements if (log.isDebugEnabled()) { log.debug("Current edition = " + editingPath); } - updateChildren(editingPath, checkbox.isSelected()); + updateChildren(editingPath, checkbox.isSelected(), false); - // too refresh selected/unselected checkbox + // to refresh selected/unselected checkbox parentTree.repaint(); } @@ -162,16 +229,14 @@ public class CheckBoxTreeCellEditor extends CheckBoxTreeCellComponent implements * @param treePath current tree path * @param select select (true) or deselect */ - protected void updateChildren(TreePath treePath, boolean select) { - TimerTask lastPathComponent = (TimerTask) treePath - .getLastPathComponent(); + protected void updateChildren(TreePath treePath, boolean select, boolean disableCurrent) { + TimerTask lastPathComponent = (TimerTask) treePath.getLastPathComponent(); if (log.isDebugEnabled()) { - log.debug("Recursive modification of = " - + lastPathComponent.getName()); + log.debug("Recursive modification of = " + lastPathComponent.getName()); } - if (select == uncheck) { + if (select == uncheck || disableCurrent) { checkedTaskSet.remove(lastPathComponent); } else { checkedTaskSet.add(lastPathComponent); @@ -181,13 +246,39 @@ public class CheckBoxTreeCellEditor extends CheckBoxTreeCellComponent implements if (parentTree.getModel().getRoot() == lastPathComponent) { for (TimerProject project : service.getData().getProjectsList()) { TreePath subTreePath = treePath.pathByAddingChild(project); - updateChildren(subTreePath, select); + updateChildren(subTreePath, select, disableSubChecked); } } else { for (TimerTask subtask : lastPathComponent.getSubTasks()) { TreePath subTreePath = treePath.pathByAddingChild(subtask); - updateChildren(subTreePath, select); + updateChildren(subTreePath, select, disableSubChecked); } } } + + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, + boolean leaf, int row, boolean hasFocus) { + boolean enable = true; + if (disableSubChecked && value instanceof TimerTask) { + TimerTask timerTask = (TimerTask)value; + + do { + timerTask = timerTask.getParent(); + if (timerTask != null) { + enable = !checkedTaskSet.contains(timerTask); + } + } while (timerTask != null && enable); + } + + Component c = getCheckBoxComponent(tree, value, selected, expanded, leaf, row); + + + // fix a strange bug where checkbox does have a "gray" background + c.setBackground(tree.getBackground()); + c.setFocusable(false); + c.setEnabled(enable); + + return c; + } } diff --git a/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxTreeCellComponent.java b/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxTreeCellComponent.java deleted file mode 100644 index 0a08e49..0000000 --- a/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxTreeCellComponent.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * #%L - * jTimer - * %% - * Copyright (C) 2009 - 2016 CodeLutin - * %% - * This program 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. - * - * 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, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -package org.chorem.jtimer.ui.tree; - -import org.chorem.jtimer.JTimerService; -import org.chorem.jtimer.entities.TimerTask; - -import javax.swing.JCheckBox; -import javax.swing.JTree; -import java.awt.Color; -import java.awt.Component; -import java.util.Set; - -/** - * JCheckBox tree node cell component. - * - * @author chatellier - * @version $Revision$ - * - * Last update : $Date$ - * By : $Author$ - */ -public abstract class CheckBoxTreeCellComponent extends JCheckBox { - - /** serialVersionUID */ - private static final long serialVersionUID = 2497464481840318274L; - - /** Timer service. */ - protected JTimerService service; - - /** Parent tree. */ - protected JTree parentTree; - - /** Unchecked task set. */ - protected Set<TimerTask> checkedTaskSet; - - /** To uncheck instead of checking. */ - protected boolean uncheck; - - /** - * Constructor. - * - * @param service service reference - * @param parentTree tree reference - * @param checkedTaskSet common unselected tasks list - * @param uncheck to uncheck instead of check by default - */ - protected CheckBoxTreeCellComponent(JTimerService service, JTree parentTree, Set<TimerTask> checkedTaskSet, boolean uncheck) { - this.service = service; - this.parentTree = parentTree; - this.checkedTaskSet = checkedTaskSet; - this.uncheck = uncheck; - } - - /** - * Generic check box component. - * - * @param tree tree - * @param value value - * @param selected selected - * @param expanded expanded - * @param leaf leaf - * @param row row - * @return check box component - */ - protected Component getCheckBoxComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) { - - // if this is a task - if (value instanceof TimerTask) { - TimerTask task = (TimerTask) value; - - // task name should not be "null" - this.setText(task.getName()); - - // add color if task is closed - if (task.isClosed()) { - this.setForeground(Color.GRAY); - } else { - this.setForeground(Color.BLACK); - } - - // set checked ? - if (checkedTaskSet.contains(task) == uncheck) { - this.setSelected(false); - } else { - this.setSelected(true); - } - } - - return this; - } -} diff --git a/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxTreeCellRenderer.java b/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxTreeCellRenderer.java deleted file mode 100644 index 93f07ee..0000000 --- a/src/main/java/org/chorem/jtimer/ui/tree/CheckBoxTreeCellRenderer.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * #%L - * jTimer - * %% - * Copyright (C) 2009 - 2011 CodeLutin - * %% - * This program 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. - * - * 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, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -package org.chorem.jtimer.ui.tree; - -import org.chorem.jtimer.JTimerService; -import org.chorem.jtimer.entities.TimerTask; - -import javax.swing.JTree; -import javax.swing.tree.TreeCellRenderer; -import java.awt.Component; -import java.util.Set; - -/** - * JCheckBox tree node cell renderer. - * - * @author chatellier - * @version $Revision$ - * - * Last update : $Date$ - * By : $Author$ - */ -public class CheckBoxTreeCellRenderer extends CheckBoxTreeCellComponent - implements TreeCellRenderer { - - /** serialVersionUID */ - private static final long serialVersionUID = 2497464481840318274L; - - /** - * Constructor. - * - * @param service service - * @param parentTree tree - * @param checkedTaskList common unselected tasks list - * @param uncheck to uncheck instead of check by default - */ - public CheckBoxTreeCellRenderer(JTimerService service, JTree parentTree, - Set<TimerTask> checkedTaskList, boolean uncheck) { - super(service, parentTree, checkedTaskList, uncheck); - } - - @Override - public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, - boolean leaf, int row, boolean hasFocus) { - Component c = getCheckBoxComponent(tree, value, selected, expanded, leaf, row); - - // fix a strange bug where checkbox does have a "gray" background - c.setBackground(tree.getBackground()); - - return c; - } -} -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.