I have tableview with checkbox in each row and I have an action button. My problem is that, how can I get selected checkbox from tableview to apply an action when the button is pressed?
This is how I add the checkbox to the tableview
public void addCeckBoxToTableView() {
/** define a simple boolean cell value for the action column so that the column will only be shown for non-empty rows. */
tcCb.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Object, Boolean>,
ObservableValue<Boolean>>() {
#Override
public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Object, Boolean> p) {
return new SimpleBooleanProperty(p.getValue() != null);
}
});
/** create a cell value factory with an add button for each row in the table. */
tcCb.setCellFactory(new Callback<TableColumn<Object, Boolean>, TableCell<Object, Boolean>>() {
#Override
public TableCell<Object, Boolean> call(TableColumn<Object, Boolean> p) {
return new CheckBoxCell();
}
});
}
private class CheckBoxCell extends TableCell<Object, Boolean> {
CheckBox checkBox = new CheckBox();
HBox hb = new HBox(checkBox);
/**
* places button in the row only if the row is not empty.
*/
#Override
protected void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
setGraphic(hb);
} else {
setGraphic(null);
}
}
}
cordially.
I'm of the same opinion as James: "with that setup you can't"
But you could do it this way
private TableView<Record> table;
private TableColumn<Record, Boolean> tcCb;
private Button actionButton;
public class Record {
private SimpleBooleanProperty selected = new SimpleBooleanProperty();
public SimpleBooleanProperty selectedProperty() {
return selected;
}
}
#Override
public void start(Stage primaryStage) throws Exception {
table = new TableView<Record>(FXCollections.observableArrayList(new Record(), new Record(), new Record()));
table.setEditable(true);
// Create "CheckBox" - Column
tcCb = new TableColumn<Record, Boolean>("Boolean-Column");
tcCb.setCellValueFactory(new PropertyValueFactory<Record, Boolean>("selected"));
tcCb.setCellFactory(CheckBoxTableCell.forTableColumn(tcCb));
tcCb.setEditable(true);
table.getColumns().add(tcCb);
// Create actionButton for retrieving cellData
actionButton = new Button("action");
actionButton.setOnAction(actionEvent -> {
for (int row = 0; row < table.getItems().size(); row++) {
System.out.println(tcCb.getCellData(row));
}
});
// The uninteresting stuff...
primaryStage.setScene(new Scene(new VBox(table, actionButton)));
primaryStage.show();
}
The UI elements should associate them with the object. In your example, you wanted to apply the action on items which are selected(Selected CheckBox).
The Object associated with the table can be like this
public class TableData{
private Boolean selected=Boolean.False;
public void setSelected(Boolean isSelected){
this.isSelected = isSelected;
}
public boolean isSelected(){
return this.selected;
}
}
So In TableCell,
When the checkBox is selected, update 'selected' Boolean value of TableData,by adding a selection action listener to the CheckBox.
then you can iterate through the TableData which you can get it from the TableView, to apply the actions upon Button selection.
Related
I am trying to change the color of the items on click when the action mode is active. The problem is that e.g if there are five items in a recyclerview and you click one, scroll down and select sixth item and destroy the action mode. The next time you start selecting, that sixth item has automatically changed its color without you selecting it. I don't know why it is happening.
public static List<ModelClass> items = new ArrayList<>();
boolean isSelectMode = false;
boolean isActionModeEnabled = false;
public static List<ModelClass> selectList = new ArrayList<>();
#Override
public void onBindViewHolder(#NonNull MyAdapter.MyViewHolder holder, int
position) {
holder.bind(items.get(position));
ModelClass modelClass = items.get(position);
if (modelClass.isChecked() && isActionModeEnabled){
holder.row.setBackgroundColor(Color.GREEN);
modelClass.setChecked(true);
} else {
holder.row.setBackgroundColor(Color.TRANSPARENT);
modelClass.setChecked(false);
}
}
public class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(#NonNull View itemView) {
super(itemView);
row = itemView.findViewById(R.id.row);
public void bind(ModelClass model) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isActionModeEnabled) {
isSelectMode = true;
s = items.get(getAdapterPosition());
if (!selectList.contains(s)){
selectList.add(s);
row.setBackgroundColor(Color.GREEN);
model.setChecked(true);
} else {
selectList.remove(s);
row.setBackgroundColor(Color.TRANSPARENT);
model.setChecked(false);
}
}
});
}
The problem is going to be in your view holder binding:
if (modelClass.isChecked() && isActionModeEnabled){
holder.row.setBackgroundColor(Color.GREEN);
modelClass.setChecked(true);
} else {
holder.row.setBackgroundColor(Color.TRANSPARENT);
modelClass.setChecked(false);
}
Remember that view holders are reused. That means that they will retain their internal state unless you change them. Your item list will also remember its state. Make sure you cover all the possible states of the item list and the reused view holders in the code above: You are probably missing a combination.
I recommend that you set a break point in the code above to make sure it is doing what you want. It should become obvious to you once you take a closer look.
I have a view where I have two tree viewers. In the createPartControl() how I can set the selectionProviders for both the views. It takes either one of them.
Here is my snippet.
The View code:
IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
IWorkbenchPartSite activePartSite = workbenchWindow.getActivePage().getActivePart().getSite();
activePartSite.setSelectionProvider(inputTreeViewer);
activePartSite.setSelectionProvider(compositeTreeViewer);
// Here the last line the selection provider code for the top one.
// Hence I only get selections from the second tree.
How can we solve the problem? I tried with inheriting the view class from ISelectionProvider and overriding getSelection() method. But that was not of any help.
Can someone suggest something?
I suggest to add a focus listener to each of the trees and call partSite.setSelectionProvider() with the currently focused tree viewer. For example:
treeViewer1.getTree().addListener( SWT.FocusIn, event -> site.setSelectionProvider( treeViewer1 ) );
treeViewer2.getTree().addListener( SWT.FocusIn, event -> site.setSelectionProvider( treeViewer2 ) );
I'll leave it as an exercise to the reader to remove the listener-duplication.
Alternatively, you can create a proxy selection provider that listens for selection changes in both tree viewers and propagates the most recent selection. Something along these lines:
public class ProxySelectionProvider implements ISelectionProvider {
private ISelection selection;
private final Collection<ISelectionChangedListener> listeners;
public ProxySelectionProvider( StructuredViewer... viewers ) {
listeners = new ArrayList<>();
selection = StructuredSelection.EMPTY;
for( StructuredViewer viewer : viewers ) {
ISelectionChangedListener selectionListener = this::selectionChanged;
viewer.addSelectionChangedListener( selectionListener );
viewer.getControl().addDisposeListener( event -> viewer.removeSelectionChangedListener( selectionListener ) );
}
}
#Override
public void addSelectionChangedListener( ISelectionChangedListener listener ) {
listeners.add( listener );
}
#Override
public void removeSelectionChangedListener( ISelectionChangedListener listener ) {
listeners.remove( listener );
}
#Override
public ISelection getSelection() {
return selection;
}
#Override
public void setSelection( ISelection selection ) {
this.selection = selection;
}
private void selectionChanged( SelectionChangedEvent event ) {
selection = event.getSelection();
notifyListeners();
}
private void notifyListeners() {
SelectionChangedEvent event = new SelectionChangedEvent( this, selection );
new ArrayList<>( listeners ).forEach( listener -> listener.selectionChanged( event ) );
}
}
Use the selection provider like this:
ISelectionProvider selectionProvider = new ProxySelectionProvider( treeViewer1, treeViewer2 );
IWorkbenchPartSite partSite = workbenchWindow.getActivePage().getActivePart().getSite();
partSite.setSelectionProvider( selectionProvider );
I solved this problem using this approach.
public class SelectionProviderAdapater implements IPostSelectionProvider {
public class InternalListener implements ISelectionChangedListener, FocusListener {
#Override
public void focusGained(FocusEvent e) {
doFocusChanged(e.widget);
}
#Override
public void focusLost(FocusEvent e) {
}
#Override
public void selectionChanged(SelectionChangedEvent event) {
doSelectionChanged(event);
}
}
/**
* The array of viewers.
*/
private StructuredViewer[] viewers;
/**
* The current viewer in focus.
*/
private StructuredViewer viewerInFocus;
/**
* The list of selection changed listeners.
*/
private final ListenerList selectionChangedListeners = new ListenerList();
/**
* The list of post selection changed listeners.
*/
private final ListenerList postSelectionChangedListeners = new ListenerList();
/**
* The internal listener instance.
*/
private final InternalListener internalListener = new InternalListener();
/**
* The internal post selection listener instance.
*/
private final ISelectionChangedListener internalPostSelectionListener = new ISelectionChangedListener() {
#Override
public void selectionChanged(SelectionChangedEvent event) {
doPostSelectionChanged(event);
}
};
#Override
public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
postSelectionChangedListeners.add(listener);
}
#Override
public void addSelectionChangedListener(ISelectionChangedListener listener) {
selectionChangedListeners.add(listener);
}
/**
* Sets the viewer in focus and fires selection change events.
*
* #param control
* The {#link Widget} that has gained focus.
*/
private void doFocusChanged(Widget control) {
for (StructuredViewer viewer : viewers) {
if (viewer.getControl() == control) {
propagateFocusChanged(viewer);
return;
}
}
}
/**
* Fires post selection changed events if the {#link SelectionChangedEvent}
* 's selection provider is the current viewer in focus.
*
* #param event
* The selection changed event.
*/
private void doPostSelectionChanged(SelectionChangedEvent event) {
ISelectionProvider provider = event.getSelectionProvider();
if (provider == viewerInFocus) {
firePostSelectionChanged();
}
}
/**
* Fires selection changed events if the {#link SelectionChangedEvent}'s
* selection provider is the current viewer in focus.
*
* #param event
* The selection changed event.
*/
private void doSelectionChanged(SelectionChangedEvent event) {
ISelectionProvider provider = event.getSelectionProvider();
if (provider == viewerInFocus) {
fireSelectionChanged();
}
}
/**
* Notifies post selection changed listeners of a selection changed event.
*/
private void firePostSelectionChanged() {
if (postSelectionChangedListeners != null) {
SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());
Object[] listeners = postSelectionChangedListeners.getListeners();
for (Object listener : listeners) {
ISelectionChangedListener selectionChangedListener = (ISelectionChangedListener) listener;
selectionChangedListener.selectionChanged(event);
}
}
}
/**
* Notifies selection changed listeners of a selection changed event.
*/
private void fireSelectionChanged() {
if (selectionChangedListeners != null) {
SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());
Object[] listeners = selectionChangedListeners.getListeners();
for (Object listener : listeners) {
ISelectionChangedListener selectionChangedListener = (ISelectionChangedListener) listener;
selectionChangedListener.selectionChanged(event);
}
}
}
#Override
public ISelection getSelection() {
if (viewerInFocus != null) {
return viewerInFocus.getSelection();
}
return StructuredSelection.EMPTY;
}
public StructuredViewer getViewerInFocus() {
return viewerInFocus;
}
/**
* Sets the viewer as the viewer in focus and fires selection changed
* events.
*
* #param viewer
* The new viewer in focus.
*/
private void propagateFocusChanged(StructuredViewer viewer) {
if (viewer != viewerInFocus) {
viewerInFocus = viewer;
fireSelectionChanged();
firePostSelectionChanged();
}
}
#Override
public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
postSelectionChangedListeners.remove(listener);
}
#Override
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
selectionChangedListeners.remove(listener);
}
#Override
public void setSelection(ISelection selection) {
if (viewerInFocus != null) {
viewerInFocus.setSelection(selection);
}
}
/**
* Sets the selection on the current viewer in focus.
*
* #param selection
* The selection to set.
* #param reveal
* true if the selection is to be made visible, and false
* otherwise
*/
public void setSelection(ISelection selection, boolean reveal) {
if (viewerInFocus != null) {
viewerInFocus.setSelection(selection, reveal);
}
}
/**
* Sets the collection of viewers to be monitored by this mediator.
*
* #param newViewers
* The collection of viewers.
*/
public void setViewers(Collection<? extends StructuredViewer> newViewers) {
// Remove listeners from any previous viewers.
if (viewers != null) {
for (StructuredViewer viewer : viewers) {
viewer.removeSelectionChangedListener(internalListener);
viewer.removePostSelectionChangedListener(internalPostSelectionListener);
Control control = viewer.getControl();
if (!control.isDisposed()) {
control.removeFocusListener(internalListener);
}
}
}
viewers = null;
viewerInFocus = null;
if (newViewers != null) {
viewers = newViewers.toArray(new StructuredViewer[newViewers.size()]);
for (StructuredViewer viewer : viewers) {
viewer.addSelectionChangedListener(internalListener);
viewer.addPostSelectionChangedListener(internalPostSelectionListener);
Control control = viewer.getControl();
control.addFocusListener(internalListener);
if (control.isFocusControl()) {
propagateFocusChanged(viewer);
}
}
}
}
}
Create an instance of this class in your view.Set the viewers using setViewers() method which are needed to be listened for selection.Then set it as the selection provider.It should start working.
I am trying to resize a slider inside a jtable cell. But when resizing the column header, I do pass in the concerned code (method getTableCellRendererComponent for column one), but nothing happens (the slider is not resized??).
below is the code of my renderer :
public class NavigationDataModelRenderer extends JLabel implements TableCellRenderer {
private JSlider slider = null;
public NavigationDataModelRenderer()
{
super();
}
public NavigationDataModelRenderer(int tolerance)
{
super();
slider = new JSlider(tolerance * -3,tolerance *3);
slider.setPaintTicks(true);
slider.setMajorTickSpacing(tolerance);
slider.setUI(new SpreadSliderUI(slider));
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column)
{
Component comp = null;
if (table.getModel()!= null && table.getModel() instanceof NavigationDataModel)
{
NavigationDataModel model = (NavigationDataModel) table.getModel();
Object o = table.getModel().getValueAt(row, column);
this.setText(o.toString());
if (column == 1)
{//slider
if (model.getList() != null && model.getList().get(0)!= null && model.getList().get(row) != null)
{
slider.setValue((Integer)o);
}
comp = slider;
slider.setSize(table.getCellRect(row, column, false).getSize());
}
else if (column == 2)
{
if (((Integer)o) == Integer.MAX_VALUE)
{
this.setText("Invalid");
}
}
else
{
comp = this;
}
}
return comp;
}
}
thanks for your help.
I encounter this problem because I use a BasicSliderUI for my slider. Now in my renderer, I set a new BasicSliderUI for my slider each time I enter getTableCellRendererComponent(...) and the slider is resized.
public class GrowingCellRenderer extends DefaultTableCellRenderer
{
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
Component renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
//renderer.setBackground(Color.red);
renderer.setSize(getMinimumSize());
table.setRowHeight(row, renderer.getHeight());
return renderer;
}
}
public static void main(String[] args)
{
GrowingCellRenderer testInstance = new GrowingCellRenderer();
final Date dateProjectStart = new Date(); //Start the "project" today
final JTable jtab = new JTable(TableTools.createTestData(dateProjectStart));
jtab.setDefaultRenderer(String.class, testInstance);
}
I am making an application which contains 2 views. The first one contains a tree viewer which displays the folders from my system and the second one contains a table viewer which displays the content of a directory selected in the first view. Long story short: a file explorer.
//initialization of the table viewer
tableViewer = new TableViewer(parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
tableViewer.setContentProvider(new FileTableContentProvider());
tableViewer.setLabelProvider(new FileTableLabelProvider());
//from within the implementation of any view or editor
/*
* getSite() - Returns the site for this workbench part (a workbench part can be a view (IViewPart) or an editor (IEditorPart))
* this view is a selection provider; the view sends the event to all the views registered to the selection service
*/
getSite().setSelectionProvider(tableViewer);
//the table column "Name" is added to the table viewer
TableColumn columnName = new TableColumn(tableViewer.getTable(), SWT.LEFT);
columnName.setText("Name");
columnName.setResizable(true);
columnName.setWidth(200);
//the table column "Date modified" is added to the table viewer
TableColumn columnDateModified = new TableColumn(tableViewer.getTable(), SWT.LEFT);
columnDateModified.setText("Date modified");
columnDateModified.setResizable(true);
columnDateModified.setWidth(200);
//the table column "Type" is added to the table viewer
TableColumn columnType = new TableColumn(tableViewer.getTable(), SWT.LEFT);
columnType.setText("Type");
columnType.setResizable(true);
columnType.setWidth(200);
//make the header of the table visible
tableViewer.getTable().setHeaderVisible(true);
/*
* getSite().getPage() - gets the active workbench page.
*/
getSite().getPage().addSelectionListener("com.awebofcode.fileexplorer.view.filetree",(ISelectionListener)this);
/*
* add a doubleClickListener for:
* 1) if the object selected is a file, then the file will be opened with the associated program
* 2) if the object selected is a directory, then enter the folder and update the tree viewer
*/
tableViewer.addDoubleClickListener(new IDoubleClickListener(){
#Override
public void doubleClick(DoubleClickEvent event) {
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
File itemSelected = (File) selection.getFirstElement();
//if the selected item is a file a double click will launch the associated program
if (itemSelected.isFile() && itemSelected.exists()){
Program.launch(itemSelected.getAbsolutePath());
}else if (itemSelected.isDirectory()){
/*
* Update the tree viewer;
* PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(FileTreeView.ID) --> returns the view with the specified ID
* setSelection() will send an event and the setSelectionChanged will run
*/
((FileTreeView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(FileTreeView.ID)).getTreeViewer().setSelection(selection);
}
}
});
//create the cell editor
CellEditor[] editors = new CellEditor[1];
editors[0] = new TextCellEditor(tableViewer.getTable());
tableViewer.setColumnProperties(new String[]{"Name", "Date modified", "Type"});
//assign the cell editors to the table viewer
tableViewer.setCellEditors(editors);
//set the cell modifier to the table viewer
tableViewer.setCellModifier(new NameCellModifier(tableViewer));
I created an action that will rename the selected file or folder from the second view.
When I click on the name of the file I don't want to enter in the editing mode.I want to stay in the selection mode and only after I click File -> Rename (action rename) the editing mode has to be enabled.
The problem is that I cannot find how to enable/disable the TextCellEditor.
I didn't find a clean solution. I will explain you what I have done so far. I have modified the code that I have posted. I use TableViewerColumn instead of TableColumn.
Class FileTableView:
public class FileTableView extends ViewPart implements ISelectionListener{
private TableViewer tableViewer;
private boolean cellEditable = false;
private FirstColumnEditingSupport obj;
public FileTableView() {
super();
}
#Override
public void createPartControl(Composite parent) {
//initialization of the table viewer
tableViewer = new TableViewer(parent, SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.MULTI); //SWT.MULTI - for multiple selection; SWT.FULL_SELECTION - for selection of an entire row
tableViewer.setContentProvider(new FileTableContentProvider());
//it is not necessary to add a label provider for the table viewer because we will set a label provider for every column of the table
//tableViewer.setLabelProvider(new FileTableLabelProvider());
//extract the table widget of the table viewer
final Table table = tableViewer.getTable();
//make the header of the table visible
table.setHeaderVisible(true);
//hide the lines of the table
table.setLinesVisible(false);
//create the columns of the table
createColumns(parent, tableViewer);
//set the sorter to the table viewer
tableComparator = new TableViewerComparator();
tableViewer.setComparator(tableComparator);
//from within the implementation of any view or editor
/*
* getSite() - Returns the site for this workbench part (a workbench part can be a view (IViewPart) or an editor (IEditorPart))
* this view is a selection provider; the view sends the event to all the views registered to the selection service
*/
getSite().setSelectionProvider(tableViewer);
tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent event){
setCellEditable(false);
}
});
}
/*
* method used to update the viewer from outside
*/
public void refresh(){
tableViewer.refresh();
}
#Override
public void setFocus() {
tableViewer.getControl().setFocus();
}
//method that returns the table viewer
public TableViewer getTableViewer(){
return tableViewer;
}
/*
* get the value of the cellEditable
*/
public boolean getCellEditable(){
return cellEditable;
}
/*
* set the value of the cellEditable
*/
public void setCellEditable(boolean cellEditable){
this.cellEditable = cellEditable;
}
public FirstColumnEditingSupport getEditingSupport(){
return obj;
}
/*
* method that creates columns of the table
*/
private void createColumns(final Composite parent, final TableViewer viewer){
String[] titles = {"Name", "Date Modified", "Size"};
int[] width = {200, 200, 200};
//first column is for the name of the file
TableViewerColumn col = createTableViewerColumn(titles[0], width[0], 0);
col.setLabelProvider(new ColumnLabelProvider(){
public String getText(Object element){
return ((File) element).getName();
}
public Image getImage(Object element){
return getFirsColumnImage((File) element);
}
});
obj = new FirstColumnEditingSupport(tableViewer,this);
col.setEditingSupport(obj);
//second column is for the last date modified
col = createTableViewerColumn(titles[1], width[1], 1);
col.setLabelProvider(new ColumnLabelProvider(){
public String getText(Object element){
return formatLastModifiedDate((File) element);
}
});
//third column is for size
col = createTableViewerColumn(titles[2], width[2], 2);
col.setLabelProvider(new ColumnLabelProvider(){
public String getText(Object element){
return formatLength((File) element);
}
});
}
private TableViewerColumn createTableViewerColumn(String title, int width, final int columnNumber){
final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(title);
column.setWidth(width);
column.setResizable(true);
column.setMoveable(false);
column.addSelectionListener(getSelectionAdapter(column, columnNumber));
return viewerColumn;
}
private SelectionAdapter getSelectionAdapter(final TableColumn column, final int index){
SelectionAdapter selectionAdapter = new SelectionAdapter(){
public void widgetSelected(SelectionEvent e){
tableComparator.setColumn(index);
int direction = tableComparator.getDirection();
tableViewer.getTable().setSortDirection(direction);
tableViewer.getTable().setSortColumn(column);
tableViewer.refresh();
}
};
return selectionAdapter;
}
/*
* method used to return the last modified date in "dd-MM-yyyy hh:mm:ss" format
*/
private String formatLastModifiedDate(File file){
Date d = new Date(file.lastModified());
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
return sdf.format(d);
}
/*
* method used to return the length of the file in KB
*/
private String formatLength(File file){
long size = file.length()/1024;
NumberFormat f = new DecimalFormat("#,###,### KB");
return f.format(size);
}
}
FirstColumnEditingSupport.java file:
/*
* The EditingSupport implementation defines how the content can be changed.
*/
public class FirstColumnEditingSupport extends EditingSupport {
private TableViewer tableViewer;
private FileTableView view;
private TextCellEditor textEditor;
public FirstColumnEditingSupport(TableViewer viewer, FileTableView view) {
super(viewer);
this.tableViewer = viewer;
this.view = view;
textEditor = new TextCellEditor(tableViewer.getTable());
}
#Override
/*
* (non-Javadoc)
* #see org.eclipse.jface.viewers.EditingSupport#getCellEditor(java.lang.Object)
* EditingSupport returns in his getCellEditor() method an object of type CellEditor. This object creates the controls to change the data.
*/
protected CellEditor getCellEditor(Object element) {
return textEditor;
}
#Override
/*
* (non-Javadoc)
* #see org.eclipse.jface.viewers.EditingSupport#canEdit(java.lang.Object)
* The canEdit() method defines, if the cell can be edited.
*/
protected boolean canEdit(Object element) {
return view.getCellEditable();
}
#Override
/*
* (non-Javadoc)
* #see org.eclipse.jface.viewers.EditingSupport#getValue(java.lang.Object)
* The getValue() method receives the current object and returns the value which should be displayed.
*/
protected Object getValue(Object element) {
return ((File) element).getName();
}
#Override
/*
* (non-Javadoc)
* #see org.eclipse.jface.viewers.EditingSupport#setValue(java.lang.Object, java.lang.Object)
* The method setValue() in EditingSupport receives the changed value based on the user input. In this method you assign the value to your data object.
*/
protected void setValue(Object element, Object value) {
//value is the user input
File oldFile = (File) element;
//String path = oldFile.getAbsolutePath().substring(oldFile.getAbsolutePath().lastIndexOf(File.pathSeparatorChar));
//System.out.println(oldFile.getParent());
oldFile.renameTo(new File(oldFile.getParent() + "\\" + (String) value));
tableViewer.refresh();
}
public TextCellEditor getTextCellEditor(){
return textEditor;
}
}
My RenameAction file:
public class RenameAction extends Action implements ISelectionListener, ActionFactory.IWorkbenchAction {
private final IWorkbenchWindow window;
private IStructuredSelection itemSelected;
public final static String ID = PlatformUI.PLUGIN_ID + ".RenameAction";
public RenameAction(IWorkbenchWindow window){
this.window = window;
setId(ID);
setText("&Rename");
setToolTipText("Rename the file or directory selected");
window.getSelectionService().addSelectionListener(this);
}
#Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
if(selection.isEmpty() || !(selection instanceof IStructuredSelection)){
return;
}else {
itemSelected = (IStructuredSelection)selection;
}
}
public void dispose(){
window.getSelectionService().removeSelectionListener(this);
}
public void run(){
Object firstElement = itemSelected.getFirstElement();
File item = (File) firstElement;
if(item != null){
FileTableView myTreeView= (FileTableView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(FileTableView.ID);
myTreeView.setCellEditable(true);
}
}
}
My idea was:
by default: the cell editor of the first column is disabled
when the rename action is triggered (press the menu button), the cell editor of the column is enabled (myTreeView.setCellEditable(true))
the table line selected is in editing mode and you can change the name of the file. This part is not working quite well, because after you press the rename menu button, you can't see that the editing mode is enabled. After you click on the table line, the editing mode is activated. Also, the editing mode is enabled for all the table lines and I wanted to be enabled only for the selected one. For this problem I haven't got a solution.
after you finish typing the new name of the file, and change the selection (click on a different table line), the editing mode is disabled:
tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent event){
setCellEditable(false);
}
});
I hope my solution can help you.
I have a Page with an Pivot-control and in some cases I don't want to show a particular PivotItem.
Setting the Visibility to collapsed doesn't seem to affect it at all.
Any suggestions?
you should be able to remove or add PivotItems dynamically in your Pivot by using the respective collection methods on Pivot.Items .
Let me know if this doesn't work for your scenario.
I've created a custom behavior for showing/hiding pivot item
Usage:
< i:Interaction.Behaviors>
< common:HideablePivotItemBehavior Visible="{Binding variable}" />
</ i:Interaction.Behaviors >
Code:
/// <summary>
/// Behavior which enables showing/hiding of a pivot item`
/// </summary>
public class HideablePivotItemBehavior : Behavior<PivotItem>
{
#region Static Fields
public static readonly DependencyProperty VisibleProperty = DependencyProperty.Register(
"Visible",
typeof(bool),
typeof(HideablePivotItemBehavior),
new PropertyMetadata(true, VisiblePropertyChanged));
#endregion
#region Fields
private Pivot _parentPivot;
private PivotItem _pivotItem;
private int _previousPivotItemIndex;
private int _lastPivotItemsCount;
#endregion
#region Public Properties
public bool Visible
{
get
{
return (bool)this.GetValue(VisibleProperty);
}
set
{
this.SetValue(VisibleProperty, value);
}
}
#endregion
#region Methods
protected override void OnAttached()
{
base.OnAttached();
this._pivotItem = AssociatedObject;
}
private static void VisiblePropertyChanged(DependencyObject dpObj, DependencyPropertyChangedEventArgs change)
{
if (change.NewValue.GetType() != typeof(bool) || dpObj.GetType() != typeof(HideablePivotItemBehavior))
{
return;
}
var behavior = (HideablePivotItemBehavior)dpObj;
var pivotItem = behavior._pivotItem;
// Parent pivot has to be assigned after the visual tree is initialized
if (behavior._parentPivot == null)
{
behavior._parentPivot = (Pivot)behavior._pivotItem.Parent;
// if the parent is null return
if (behavior._parentPivot == null)
{
return;
}
}
var parentPivot = behavior._parentPivot;
if (!(bool)change.NewValue)
{
if (parentPivot.Items.Contains(behavior._pivotItem))
{
behavior._previousPivotItemIndex = parentPivot.Items.IndexOf(pivotItem);
parentPivot.Items.Remove(pivotItem);
behavior._lastPivotItemsCount = parentPivot.Items.Count;
}
}
else
{
if (!parentPivot.Items.Contains(pivotItem))
{
if (behavior._lastPivotItemsCount >= parentPivot.Items.Count)
{
parentPivot.Items.Insert(behavior._previousPivotItemIndex, pivotItem);
}
else
{
parentPivot.Items.Add(pivotItem);
}
}
}
}
#endregion
}
You can remove the pivot item from the parent pivot control
parentPivotControl.Items.Remove(pivotItemToBeRemoved);
Removing PivotItems is easy, but if you want to put them back afterwards I've found that the headers get messed up and start overlapping each other. This also happens if you set the Visibility of a header to Collapsed and then later make it Visible again.
So I solved my particular problem by setting the opacity of each unwanted PivotItem (and its header) to 0.
PivotItem p = (PivotItem)MainPivot.Items.ToList()[indexToHide];
p.Opacity = 0;
((UIElement)p.Header).Opacity = 0;
However, this leaves gaps where the missing PivotItems are.
For me, the gaps were not a problem because I only want to remove items at the end of my PivotItemList, so I get some whitespace between the last and first PivotItems. The problem was, I was still able to swipe to a hidden PivotItem. In order to fix this, I overrode Pivot.SelectionChanged() so that whenever the user swipes to a hidden PivotItem, the code moves on to the next item instead. I had to use a DispatchTimer from within SelectionChanged() and actually move to the next PivotItem from the DispatchTimer callback, since you have to be in the UI thread to change PivotItem.SelectedIndex.
private void MainPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
t.Stop(); //t is my DispatchTimer, set to 100ms
if (MainPivot.SelectedIndex >= mFirstHiddenPivotItemIndex)
{
//move to the first or last PivotItem, depending on the current index
if (mCurrentSelectedPivotItemIndex == 0)
mPivotItemToMoveTo = mFirstHiddenPivotItemIndex - 1;
else
mPivotItemToMoveTo = 0;
t.Start();
}
mCurrentSelectedPivotItemIndex = MainPivot.SelectedIndex;
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
MainPivot.SelectedIndex = mPivotItemToMoveTo;
t.Stop();
}
foreach (PivotItem item in MyPivot.Items.ToList())
{
if (item.Visibility == Visibility.Collapsed)
MyPivot.Items.Remove(item);
}
Setting IsLocked property to true will make all other Pivot items to disappear except the current pivot item.
But this will not hide one particular pivot item of our choice.
To elaborate on the solution of adding/removing pivotItems, rather than hiding them.
Let's say we want the pivotItem to be initially invisible, and appear only on a certain event.
mainPivot.Items.Remove(someTab);
Then to add it again,
if (!mainPivot.Items.Cast<PivotItem>().Any(p => p.Name == "someTab"))
{
mainPivot.Items.Insert(1,someTab);
}
I've used Insert rather than add to control the position where the tab appears.
You have to ensure you don't add the same tab twice, which is the reason for the if statement.
I've modified the Bajena behavior to improve it, solving the issue with losing the original position of the PivotItem when showing/hiding repeteadly and the issue when parentpivot control is null (not initialized yet).
Notice that this behavior must be attached to the Pivot, not to the PivotItem.
Code:
public class PivotItemHideableBehavior : Behavior<Pivot>
{
private Dictionary<PivotItem, int> DictionaryIndexes { get; set; }
public static readonly DependencyProperty VisibleProperty = DependencyProperty.Register(
"Visible",
typeof(bool),
typeof(PivotItemHideableBehavior),
new PropertyMetadata(true, VisiblePropertyChanged));
public static readonly DependencyProperty PivotItemProperty = DependencyProperty.Register(
"PivotItem",
typeof(PivotItem),
typeof(PivotItemHideableBehavior),
new PropertyMetadata(null));
public bool Visible
{
get { return (bool)GetValue(VisibleProperty); }
set { SetValue(VisibleProperty, value); }
}
public PivotItem PivotItem
{
get { return (PivotItem)GetValue(PivotItemProperty); }
set { SetValue(PivotItemProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += AssociatedObject_Loaded;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Loaded -= AssociatedObject_Loaded;
}
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
DictionaryIndexes = new Dictionary<PivotItem, int>();
int index = 0;
foreach (PivotItem item in AssociatedObject.Items)
DictionaryIndexes.Add(item, index++);
}
private static void VisiblePropertyChanged(DependencyObject dpObj, DependencyPropertyChangedEventArgs change)
{
var behavior = (PivotItemHideableBehavior)dpObj;
var pivot = behavior.AssociatedObject;
if (!behavior.Visible)
{
if (pivot.Items.Contains(behavior.PivotItem))
pivot.Items.Remove(behavior.PivotItem);
}
else if (!pivot.Items.Contains(behavior.PivotItem))
{
int index = 0;
foreach (var item in behavior.DictionaryIndexes)
{
if (item.Key == behavior.PivotItem)
pivot.Items.Insert(index, behavior.PivotItem);
else if (pivot.Items.Contains(item.Key))
index++;
}
}
}
}
Usage:
<Interactivity:Interaction.Behaviors>
<Behaviors:PivotItemHideableBehavior PivotItem="{x:Bind PivotItemName}" Visible="{Binding IsPivotItemVisible}" />
</Interactivity:Interaction.Behaviors>