|
Re: Why is composites like Table not intended to be subclassed? [message #464998 is a reply to message #464974] |
Fri, 02 December 2005 16:12 |
Jeremy Dowdall Messages: 48 Registered: July 2009 |
Member |
|
|
to answer your question bluntly - I have no idea :)
but I did run into the same problem with my own application and rigged
up the following hack that may be helpful until someone can offer better
insight. basically I just keep track of the selection with a mouse
listener:
private Table table;
private List selection = new ArrayList();
table.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent e) {
if(e.button == 1) {
TableItem newItem = viewer.getTable().getItem(new Point(e.x,e.y));
if(selection.contains(newItem)) {
selection.remove(newItem);
} else {
selection.add(newItem);
}
viewer.getTable().setSelection((TableItem[])
selection.toArray(new TableItem[selection.size()]));
}
}
});
naturally, I'd love to hear better ways of doing this, but I needed
something running!
Robert Bjervås wrote:
> Hi,
>
> I'm working with an application intended for use with a touch screen. Each
> time a row in a table is "picked" should it be selected or deselected
> depending on the previous state, but all other rows should be as is. This is
> the behavior if CTRL is pressed at the same time as the row is "picked". So
> what we want to do is to handle every select event as if CTRL is pressed.
> After some elaboration is our conclusion that the best way to a achieve such
> behavior is to subclass Table and override all methods handling selection
> and deselection. You can see our first implementation at the end of the
> mail. It's not tested that much so it may contain errors. Anyway the reason
> for this mail and my question is why is Table (and other composites) not
> intended to be subclassed?
>
> "IMPORTANT: This class is <em>not</em> intended to be subclassed."
>
> I can't see the reason and this seams to be the best (and probably only)
> solution to our issue.
>
> Sincerely
>
> /Robert
>
> package my.viewer;
>
> import org.eclipse.swt.widgets.Table;
> import org.eclipse.swt.widgets.Composite;
> import org.eclipse.swt.widgets.TableItem;
> import org.eclipse.swt.SWT;
> import java.util.List;
> import java.util.ArrayList;
>
> /**
> * MultiSelectTable implement a table acting as if CTRL is pressed each time
> * a row is selected in the table making it easier to work with a touch
> screen.
> */
> public class MultiSelectTable extends Table {
>
> public final static int COLOR_NORMAL_BACKGROUND =
> SWT.COLOR_LIST_BACKGROUND;
> public final static int COLOR_NORMAL_TEXT = SWT.COLOR_LIST_FOREGROUND;
> public final static int COLOR_SELECTED_BACKGROUND =
> SWT.COLOR_LIST_SELECTION;
> public final static int COLOR_SELCTED_TEXT =
> SWT.COLOR_LIST_SELECTION_TEXT;
>
> public MultiSelectTable(Composite composite, int i) {
> super(composite, i);
> }
> public void deselect(int index) {
> if (index>=0 && index<getItemCount())
> deselectTableItem(getItem(index));
> }
> public void deselect(TableItem tableItem) {
> deselectTableItem(tableItem);
> }
> publi c void deselect(int start, int end) {
> for(int i=start;i<=end;i++) {
> deselect(i);
> }
> }
> public void deselect(int[] indices) {
> for (int i = 0; i < indices.length; i++) {
> int index = indices[i];
> deselect(index);
> }
> }
> public void deselectAll() {
> TableItem[] tableItems =this.getItems();
> for (int i = 0; i < tableItems.length; i++) {
> TableItem tableItem = tableItems[i];
> if
> (tableItem.getBackground().equals(this.getDisplay().getSyste mColor(COLOR_SELECTED_BACKGROUND)))
> deselectTableItem(tableItem);
> }
> super.deselectAll();
> }
> public TableItem[] getSelection() {
> TableItem[] allTableItems =this.getItems();
> ArrayList tableItems=new ArrayList();
> int cnt=0;
> for (int i = 0; i < allTableItems.length; i++) {
> TableItem tableItem = allTableItems[i];
> if (isSelected(tableItem))
> tableItems.add(tableItem);
> }
> return (TableItem[]) tableItems.toArray(new TableItem[0]);
> }
> public int getSelectionCount() {
> TableItem[] tableItems =this.getItems();
> int cnt=0;
> for (int i = 0; i < tableItems.length; i++) {
> TableItem tableItem = tableItems[i];
> if (isSelected(tableItem))
> cnt++;
> }
> return cnt;
> }
> public int[] getSelectionIndices() {
> return super.getSelectionIndices();
> }
> public int getSelectionIndex() {
> return super.getSelectionIndex();
> }
> public void selectAll() {
> TableItem[] tableItems = getItems();
> select(tableItems);
> }
> public void select(TableItem[] tableItems) {
> for (int i = 0; i < tableItems.length; i++) {
> TableItem tableItem = tableItems[i];
> selectTableItem(tableItem);
> }
> }
> public void select(int index) {
> if (index>=0 && index<getItemCount())
> selectTableItem(getItem(index));
> }
> public void select(TableItem tableItem) {
> selectTableItem(tableItem);
> }
> public void select(int start, int end) {
> for(int i=start;i<=end;i++){
> select(i);
> }
> }
> public void select(int [] indices) {
> for (int i = 0; i < indices.length; i++) {
> int index = indices[i];
> select(index);
> }
> }
> public boolean isSelected(int i) {
> return isSelected(getItem(i));
> }
> public void setSelection(int index) {
> deselectAll();
> select(index);
> }
> public void setSelection(int start, int end) {
> deselectAll();
> select(start,end);
> }
> public void setSelection(int[] indices) {
> deselectAll();
> select(indices);
> }
> public void setSelection(TableItem[] tableItems) {
> deselectAll();
> select(tableItems);
> }
> public void showSelection() {
> TableItem tableItem= getFirstSelectedItem();
> if (tableItem!=null)
> showItem(tableItem);
> }
> private TableItem getFirstSelectedItem(){
> TableItem firstItem=null;
> TableItem[] tableItems =this.getItems();
> int cnt=0;
> for (int i = 0; i < tableItems.length; i++) {
> TableItem tableItem = tableItems[i];
> if (isSelected(tableItem)){
> firstItem=tableItem;
> break;
> }
> }
> return firstItem;
> }
> public boolean isSelected(TableItem tableItem){
> return
> tableItem.getBackground().equals(this.getDisplay().getSystem Color(COLOR_SELECTED_BACKGROUND));
> }
> private void selectTableItem(TableItem tableItem){
> tableItem.setBackground(tableItem.getDisplay().getSystemColo r(COLOR_SELECTED_BACKGROUND));
> tableItem.setForeground(tableItem.getDisplay().getSystemColo r(COLOR_SELCTED_TEXT));
> super.deselectAll();
> }
> private void deselectTableItem(TableItem tableItem){
> tableItem.setBackground(tableItem.getDisplay().getSystemColo r(COLOR_NORMAL_BACKGROUND));
> tableItem.setForeground(tableItem.getDisplay().getSystemColo r(COLOR_NORMAL_TEXT));
> super.deselectAll();
> }
> // To shortcircuit the check done in the super class
> protected void checkSubclass () {
> }
> }
>
>
>
>
|
|
|
Re: Why is composites like Table not intended to be subclassed? [message #465008 is a reply to message #464974] |
Fri, 02 December 2005 17:17 |
Alex Blewitt Messages: 946 Registered: July 2009 |
Senior Member |
|
|
I believe that the reason most SWT widgets have that warning is because most of the classes are pseduo-final. That is, they've been developed without any consideration for subclassing, and thus anyone who does subclass may have to change the subclass for each release (especially the internal ones). However, rather than making it final (which would prevent anyone subclassing, whether they had a legitimate need to or not -- such as yourself), a strongly worded comment indicates that if you do subclass it, it's up to you to fix it when they change the superclass without telling you.
It's mentioned briefly in the API Rules of engagement:
http://help.eclipse.org/help30/index.jsp?topic=/org.eclipse. platform.doc.isv/reference/misc/api-usage-rules.html
There are also some classes which call 'checkSubclass()' and throw an error if this.getClass() doesn't match the expected value. You might have to override this method if you are subclassing Widgets.
http://help.eclipse.org/help31/nftopic/org.eclipse.platform. doc.isv/reference/api/org/eclipse/swt/widgets/Widget.html
http://help.eclipse.org/help31/nftopic/org.eclipse.platform. doc.isv/reference/api/org/eclipse/swt/widgets/Widget.html#ch eckSubclass()
"Checks that this class can be subclassed.
The SWT class library is intended to be subclassed only at specific, controlled points (most notably, Composite and Canvas when implementing new widgets). This method enforces this rule unless it is overridden.
IMPORTANT: By providing an implementation of this method that allows a subclass of a class which does not normally allow subclassing to be created, the implementer agrees to be fully responsible for the fact that any such subclass will likely fail between SWT releases and will be strongly platform specific. No support is provided for user-written classes which are implemented in this fashion.
The ability to subclass outside of the allowed SWT classes is intended purely to enable those not on the SWT development team to implement patches in order to get around specific limitations in advance of when those limitations can be addressed by the team. Subclassing should not be attempted without an intimate and detailed understanding of the hierarchy. "
Alex.
|
|
|
Re: Why is composites like Table not intended to be subclassed? [message #465009 is a reply to message #464998] |
Fri, 02 December 2005 17:19 |
Stefan Langer Messages: 236 Registered: July 2009 |
Senior Member |
|
|
http://www.eclipse.org/swt/faq.php#subclassing
Jeremy Dowdall wrote:
> to answer your question bluntly - I have no idea :)
>
> but I did run into the same problem with my own application and rigged
> up the following hack that may be helpful until someone can offer better
> insight. basically I just keep track of the selection with a mouse
> listener:
>
>
> private Table table;
> private List selection = new ArrayList();
>
> table.addMouseListener(new MouseAdapter() {
> public void mouseDown(MouseEvent e) {
> if(e.button == 1) {
> TableItem newItem = viewer.getTable().getItem(new Point(e.x,e.y));
> if(selection.contains(newItem)) {
> selection.remove(newItem);
> } else {
> selection.add(newItem);
> }
> viewer.getTable().setSelection((TableItem[]) selection.toArray(new
> TableItem[selection.size()]));
> }
> }
> });
>
>
> naturally, I'd love to hear better ways of doing this, but I needed
> something running!
>
> Robert Bjervås wrote:
>
>> Hi,
>>
>> I'm working with an application intended for use with a touch screen.
>> Each time a row in a table is "picked" should it be selected or
>> deselected depending on the previous state, but all other rows should
>> be as is. This is the behavior if CTRL is pressed at the same time as
>> the row is "picked". So what we want to do is to handle every select
>> event as if CTRL is pressed. After some elaboration is our conclusion
>> that the best way to a achieve such behavior is to subclass Table and
>> override all methods handling selection and deselection. You can see
>> our first implementation at the end of the mail. It's not tested that
>> much so it may contain errors. Anyway the reason for this mail and my
>> question is why is Table (and other composites) not intended to be
>> subclassed?
>>
>> "IMPORTANT: This class is <em>not</em> intended to be subclassed."
>>
>> I can't see the reason and this seams to be the best (and probably
>> only) solution to our issue.
>>
>> Sincerely
>>
>> /Robert
>>
>> package my.viewer;
>>
>> import org.eclipse.swt.widgets.Table;
>> import org.eclipse.swt.widgets.Composite;
>> import org.eclipse.swt.widgets.TableItem;
>> import org.eclipse.swt.SWT;
>> import java.util.List;
>> import java.util.ArrayList;
>>
>> /**
>> * MultiSelectTable implement a table acting as if CTRL is pressed
>> each time
>> * a row is selected in the table making it easier to work with a
>> touch screen.
>> */
>> public class MultiSelectTable extends Table {
>>
>> public final static int COLOR_NORMAL_BACKGROUND =
>> SWT.COLOR_LIST_BACKGROUND;
>> public final static int COLOR_NORMAL_TEXT = SWT.COLOR_LIST_FOREGROUND;
>> public final static int COLOR_SELECTED_BACKGROUND =
>> SWT.COLOR_LIST_SELECTION;
>> public final static int COLOR_SELCTED_TEXT =
>> SWT.COLOR_LIST_SELECTION_TEXT;
>>
>> public MultiSelectTable(Composite composite, int i) {
>> super(composite, i);
>> }
>> public void deselect(int index) {
>> if (index>=0 && index<getItemCount())
>> deselectTableItem(getItem(index));
>> }
>> public void deselect(TableItem tableItem) {
>> deselectTableItem(tableItem);
>> }
>> publi c void deselect(int start, int end) {
>> for(int i=start;i<=end;i++) {
>> deselect(i);
>> }
>> }
>> public void deselect(int[] indices) {
>> for (int i = 0; i < indices.length; i++) {
>> int index = indices[i];
>> deselect(index);
>> }
>> }
>> public void deselectAll() {
>> TableItem[] tableItems =this.getItems();
>> for (int i = 0; i < tableItems.length; i++) {
>> TableItem tableItem = tableItems[i];
>> if
>> (tableItem.getBackground().equals(this.getDisplay().getSyste mColor(COLOR_SELECTED_BACKGROUND)))
>>
>> deselectTableItem(tableItem);
>> }
>> super.deselectAll();
>> }
>> public TableItem[] getSelection() {
>> TableItem[] allTableItems =this.getItems();
>> ArrayList tableItems=new ArrayList();
>> int cnt=0;
>> for (int i = 0; i < allTableItems.length; i++) {
>> TableItem tableItem = allTableItems[i];
>> if (isSelected(tableItem))
>> tableItems.add(tableItem);
>> }
>> return (TableItem[]) tableItems.toArray(new TableItem[0]);
>> }
>> public int getSelectionCount() {
>> TableItem[] tableItems =this.getItems();
>> int cnt=0;
>> for (int i = 0; i < tableItems.length; i++) {
>> TableItem tableItem = tableItems[i];
>> if (isSelected(tableItem))
>> cnt++;
>> }
>> return cnt;
>> }
>> public int[] getSelectionIndices() {
>> return super.getSelectionIndices();
>> }
>> public int getSelectionIndex() {
>> return super.getSelectionIndex();
>> }
>> public void selectAll() {
>> TableItem[] tableItems = getItems();
>> select(tableItems);
>> }
>> public void select(TableItem[] tableItems) {
>> for (int i = 0; i < tableItems.length; i++) {
>> TableItem tableItem = tableItems[i];
>> selectTableItem(tableItem);
>> }
>> }
>> public void select(int index) {
>> if (index>=0 && index<getItemCount())
>> selectTableItem(getItem(index));
>> }
>> public void select(TableItem tableItem) {
>> selectTableItem(tableItem);
>> }
>> public void select(int start, int end) {
>> for(int i=start;i<=end;i++){
>> select(i);
>> }
>> }
>> public void select(int [] indices) {
>> for (int i = 0; i < indices.length; i++) {
>> int index = indices[i];
>> select(index);
>> }
>> }
>> public boolean isSelected(int i) {
>> return isSelected(getItem(i));
>> }
>> public void setSelection(int index) {
>> deselectAll();
>> select(index);
>> }
>> public void setSelection(int start, int end) {
>> deselectAll();
>> select(start,end);
>> }
>> public void setSelection(int[] indices) {
>> deselectAll();
>> select(indices);
>> }
>> public void setSelection(TableItem[] tableItems) {
>> deselectAll();
>> select(tableItems);
>> }
>> public void showSelection() {
>> TableItem tableItem= getFirstSelectedItem();
>> if (tableItem!=null)
>> showItem(tableItem);
>> }
>> private TableItem getFirstSelectedItem(){
>> TableItem firstItem=null;
>> TableItem[] tableItems =this.getItems();
>> int cnt=0;
>> for (int i = 0; i < tableItems.length; i++) {
>> TableItem tableItem = tableItems[i];
>> if (isSelected(tableItem)){
>> firstItem=tableItem;
>> break;
>> }
>> }
>> return firstItem;
>> }
>> public boolean isSelected(TableItem tableItem){
>> return
>> tableItem.getBackground().equals(this.getDisplay().getSystem Color(COLOR_SELECTED_BACKGROUND));
>>
>> }
>> private void selectTableItem(TableItem tableItem){
>>
>> tableItem.setBackground(tableItem.getDisplay().getSystemColo r(COLOR_SELECTED_BACKGROUND));
>>
>>
>> tableItem.setForeground(tableItem.getDisplay().getSystemColo r(COLOR_SELCTED_TEXT));
>>
>> super.deselectAll();
>> }
>> private void deselectTableItem(TableItem tableItem){
>>
>> tableItem.setBackground(tableItem.getDisplay().getSystemColo r(COLOR_NORMAL_BACKGROUND));
>>
>>
>> tableItem.setForeground(tableItem.getDisplay().getSystemColo r(COLOR_NORMAL_TEXT));
>>
>> super.deselectAll();
>> }
>> // To shortcircuit the check done in the super class
>> protected void checkSubclass () {
>> }
>> }
>>
>>
>>
>>
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04018 seconds