Forum Stats

  • 3,733,394 Users
  • 2,246,754 Discussions
  • 7,856,686 Comments

Discussions

Disable selection in ListView

csh
csh Member Posts: 525
edited June 2013 in JavaFX 2.0 and Later
Hi,

is it possible to disable the selection in ListView? So that the user cannot select anything?
shakir.gusaroffMuzib

Answers

  • shakir.gusaroff
    shakir.gusaroff Member Posts: 689
    edited April 2013
     final ListView<String> myListView = new ListView();
     myListView.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() {
                        @Override
                        public void changed(ObservableValue observable, Object oldvalue, Object newValue) {
                            Platform.runLater(new Runnable() {
                                public void run() {
                                    myListView.getSelectionModel().select(-1);
    
                                }
                            });
    
                        }
                    });
    It can also be done by overriding caspian.css.
    Here is a stylesheet.css file:
    .list-view:focused {
        -fx-background-color: -fx-focus-color,-fx-box-border,-fx-control-inner-background;
        -fx-background-insets: -1.4, 0, 1;
        -fx-background-radius: 1.4, 0, 0;
    
        /* There is some oddness if padding is in em values rather than pixels,
           in particular, the left border of the control doesn't show. */
        -fx-padding: 1; /* 0.083333em; */
    }
    
    .list-view .scroll-bar:vertical{
        -fx-background-insets: 0, 0 0 0 1;
        -fx-padding: -0.083333em -0.083333em -0.083333em 0.0em; /* -1 -1 -1 0 */
    }
    
    .list-view .scroll-bar:horizontal{
        -fx-background-insets: 0, 1 0 0 0;
        -fx-padding: 0.0em 0.0em -0.083333em -0.083333em; /* 0 0 -1 -1 */
    }
    
    .list-view:disabled {
        -fx-opacity: -fx-disabled-opacity;
    }
    
    .list-view .corner {
        -fx-background-color: -fx-box-border, -fx-base;
        -fx-background-insets: 0, 1 0 0 1;
    }
    
    .list-cell {
        -fx-skin: "com.sun.javafx.scene.control.skin.ListCellSkin";
        -fx-background-color: -fx-control-inner-background;
        -fx-padding: 0.25em; /* 3 */
        -fx-text-fill: -fx-text-inner-color;
        -fx-cell-size: 2.0em; /* 24 */
        -fx-opacity: 1;
    }
    
    
    .list-cell:odd {
        -fx-background-color: derive(-fx-control-inner-background,-5%);
    }
    Edited: Added a custom css file to disable selection.
    Muzib
  • James_D
    James_D Member Posts: 1,496
    I guess
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.control.ListView;
    import javafx.scene.control.MultipleSelectionModel;
    import javafx.stage.Stage;
    
    public class NoSelectionList extends Application {
    
    	@Override
    	public void start(Stage primaryStage) {
    		ListView<String> listView = new ListView<>(FXCollections.observableArrayList("Apples", "Oranges", "Pears", "Bananas"));
    		listView.setSelectionModel(new DisabledSelectionModel<String>());
    		primaryStage.setScene(new Scene(listView, 200, 400));
    		primaryStage.show();
    	}
    
    	public static void main(String[] args) {
    		launch(args);
    	}
    	
    	static class DisabledSelectionModel<T> extends MultipleSelectionModel<T> {
    	  DisabledSelectionModel() {
    	    super.setSelectedIndex(-1);
    	    super.setSelectedItem(null);
    	  }
    	  @Override
    	  public ObservableList<Integer> getSelectedIndices() { return FXCollections.<Integer>emptyObservableList() ; }
    	  @Override
    	  public ObservableList<T> getSelectedItems() { return FXCollections.<T>emptyObservableList() ; }
    	  @Override
    	  public void selectAll() {}
    	  @Override
    	  public void selectFirst() {}
    	  @Override
    	  public void selectIndices(int index, int... indicies) {}
    	  @Override
    	  public void selectLast() {}
    	  @Override
    	  public void clearAndSelect(int index) {}
    	  @Override
    	  public void clearSelection() {}
    	  @Override
    	  public void clearSelection(int index) {}
    	  @Override
    	  public boolean isEmpty() { return true ; }
    	  @Override
    	  public boolean isSelected(int index) { return false ; }
    	  @Override
    	  public void select(int index) {}
    	  @Override
    	  public void select(T item) {}
    	  @Override
    	  public void selectNext() {}
    	  @Override
    	  public void selectPrevious() {}
    	  
    	}
    }
    Which is a lot of typing to achieve "not selecting anything", but avoids the "select something then deselect it" approach.
    shakir.gusaroff
  • shakir.gusaroff
    shakir.gusaroff Member Posts: 689
    The best way to disable the selection in the listview would be to add one more constant of the enum type to the javafx.scene.control.SelectionMode :
         public static final SelectionMode NONE
    Then we could do:
    listView.setSelectionModel(SelectionMode.NONE);
  • csh
    csh Member Posts: 525
    Thanks for your answers.

    I've got another related question:

    Is it possible to prevent selecting by mouse? I want to select only programmatically.

    I've tried it with consuming the event, but it doesn't work:
    ListView<String> listView = new ListView<String>();
            listView.setItems(FXCollections.observableArrayList("Test1", "Test2"));
    
            listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
                @Override
                public ListCell<String> call(ListView<String> stringListView) {
                    ListCell<String> listCell = new ListCell<String>();
                    listCell.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
                        @Override
                        public void handle(MouseEvent mouseEvent) {
                            mouseEvent.consume();
                        }
                    });
                    return listCell;
                }
            });
  • shakir.gusaroff
    shakir.gusaroff Member Posts: 689
    Hi. Add an eventfilter to the listview:
        listView.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
                        @Override
                        public void handle(MouseEvent mouseEvent) {
                            mouseEvent.consume();
                        }
                    });
            
  • fabsav
    fabsav Member Posts: 79
    don't forget to check row changing by keyboard

    table.addEventFilter(MouseEvent.MOUSE_PRESSED, changeByMouseEvent);
    table.addEventFilter(KeyEvent.KEY_PRESSED, changeByKeyboardEvent);

    private final EventHandler<KeyEvent> changeByKeyboardEvent = new EventHandler<KeyEvent>() {
    @Override
    public void handle(final KeyEvent event) {
    if (event.getCode().isArrowKey()) {
    //do something if you want
    event.consume();
    }
    }
    };

    private final EventHandler<MouseEvent> changeByMouseEvent = new EventHandler<MouseEvent>() {
    @Override
    public void handle(final MouseEvent event) {
    event.consume();
    }
    };

    if you just need to disable selection, without any other control, just use the econd listener
  • James_D
    James_D Member Posts: 1,496
    You could also do this with a custom selection model implementation. In the implementation, create the required properties (ObservableList of selected items and ObservableList of selected indices). Implement methods to return them as required by MultipleSelectionModel. Implement all the select...(...) and clear...(...) methods to do nothing: these will be called by the UI. Then either create additional methods to manipulate the selectedItems, selectedItem, selectedIndices and selectedIndex from your code, or expose the list and property to your code as required. Again, it's a lot of code, but it would likely be more robust than trying to grab and consume events. (Also, you may want to implement other event handlers on your list, and this approach would allow you to do so.)
  • b.pradeep
    b.pradeep Member Posts: 22

    James I tried it but it doesnot work for tableview

    I added

    static class DisabledSelectionModel<T> extends TableViewSelectionModel<T> {
         public DisabledSelectionModel(TableView<T> arg0) {
      super(arg0);
      }
      /* DisabledSelectionModel() {
            //super.setSelectedIndex(-1);
           // super.setSelectedItem(null);
          }*/
    
    
      @Override
      public ObservableList<TablePosition> getSelectedCells() {
      // TODO Auto-generated method stub
      return null;
      }
    
    
      @Override
      public boolean isSelected(int row, TableColumn<T, ?> column) {
      // TODO Auto-generated method stub
      return false;
      }
    
    
      @Override
      public void select(int row, TableColumn<T, ?> column) {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void clearAndSelect(int row, TableColumn<T, ?> column) {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void clearSelection(int row, TableColumn<T, ?> column) {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void selectLeftCell() {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void selectRightCell() {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void selectAboveCell() {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void selectBelowCell() {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public ObservableList<Integer> getSelectedIndices() {
      // TODO Auto-generated method stub
      return null;
      }
    
    
      @Override
      public ObservableList<T> getSelectedItems() {
      // TODO Auto-generated method stub
      return null;
      }
    
    
      @Override
      public void selectIndices(int index, int... indices) {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void selectAll() {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void selectFirst() {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void selectLast() {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void clearAndSelect(int index) {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void select(int index) {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void select(T obj) {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void clearSelection(int index) {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void clearSelection() {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public boolean isSelected(int index) {
      // TODO Auto-generated method stub
      return false;
      }
    
    
      @Override
      public boolean isEmpty() {
      // TODO Auto-generated method stub
      return false;
      }
    
    
      @Override
      public void selectPrevious() {
      // TODO Auto-generated method stub
    
      }
    
    
      @Override
      public void selectNext() {
      // TODO Auto-generated method stub
    
      }
         
          
       }
    
    table.setSelectionModel(new DisabledSelectionModel<Person>(table));
    
    


    I got this run time error

    SEVERE: javafx.scene.control.Control loadSkinClass Failed to load skin 'StringProperty [bean: [email protected][styleClass=table-view], name: skinClassName, value: com.sun.javafx.scene.control.skin.TableViewSkin]' for control [email protected][styleClass=table-view]

    java.lang.NullPointerException

      at com.sun.javafx.scene.control.behavior.TableViewBehavior.<init>(TableViewBehavior.java:308)

      at com.sun.javafx.scene.control.skin.TableViewSkin.<init>(TableViewSkin.java:60)

      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)

      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

      at java.lang.reflect.Constructor.newInstance(Constructor.java:525)

      at javafx.scene.control.Control.loadSkinClass(Control.java:1044)

      at javafx.scene.control.Control.access$500(Control.java:70)

      at javafx.scene.control.Control$12.invalidated(Control.java:972)

      at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:127)

      at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:161)

      at com.sun.javafx.css.StyleableStringProperty.set(StyleableStringProperty.java:71)

      at javafx.scene.control.Control$12.set(Control.java:964)

      at com.sun.javafx.css.StyleableStringProperty.applyStyle(StyleableStringProperty.java:59)

      at com.sun.javafx.css.StyleableStringProperty.applyStyle(StyleableStringProperty.java:31)

      at com.sun.javafx.css.StyleableProperty.set(StyleableProperty.java:70)

      at com.sun.javafx.css.StyleHelper.transitionToState(StyleHelper.java:902)

      at javafx.scene.Node.impl_processCSS(Node.java:7415)

      at javafx.scene.Parent.impl_processCSS(Parent.java:1146)

      at javafx.scene.control.Control.impl_processCSS(Control.java:1154)

      at javafx.scene.Parent.impl_processCSS(Parent.java:1153)

      at javafx.scene.Node.processCSS(Node.java:7383)

      at javafx.scene.Scene.doCSSPass(Scene.java:446)

      at javafx.scene.Scene.preferredSize(Scene.java:1449)

      at javafx.scene.Scene.impl_preferredSize(Scene.java:1516)

      at javafx.stage.Window$9.invalidated(Window.java:716)

      at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:127)

      at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:161)

      at javafx.stage.Window.setShowing(Window.java:779)

      at javafx.stage.Window.show(Window.java:794)

      at javafx.stage.Stage.show(Stage.java:229)

      at TableInsertExample.start(TableInsertExample.java:374)

      at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)

      at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:215)

      at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)

      at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)

      at java.security.AccessController.doPrivileged(Native Method)

      at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)

      at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)

      at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)

      at com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:82)

      at java.lang.Thread.run(Thread.java:722)

    and no table was shown.... (insertion continues )

    any suggestion

This discussion has been closed.