001 /*
002 * Copyright 2014-2016 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package griffon.plugins.glazedlists.javafx.gui;
017
018 import ca.odell.glazedlists.TextFilterator;
019 import ca.odell.glazedlists.matchers.TextMatcherEditor;
020 import javafx.beans.value.ChangeListener;
021 import javafx.beans.value.ObservableValue;
022 import javafx.event.EventHandler;
023 import javafx.scene.control.TextInputControl;
024 import javafx.scene.input.KeyCode;
025 import javafx.scene.input.KeyEvent;
026
027 /**
028 * @author Andres Almiray
029 * @since 1.3.1
030 */
031 public class TextInputControlMatcherEditor<E> extends TextMatcherEditor<E> {
032 private final TextInputControl textInputControl;
033 private boolean live;
034 private final TextHandler textHandler = new TextHandler();
035
036 public TextInputControlMatcherEditor(TextInputControl textInputControl, TextFilterator<? super E> textFilterator) {
037 this(textInputControl, textFilterator, true);
038 }
039
040 public TextInputControlMatcherEditor(TextInputControl textInputControl, TextFilterator<? super E> textFilterator, boolean live) {
041 super(textFilterator);
042 this.textInputControl = textInputControl;
043 this.live = live;
044 registerListeners(live);
045 refilter();
046 }
047
048 public boolean isLive() {
049 return live;
050 }
051
052 public void setLive(boolean live) {
053 if (live == this.live) { return; }
054 deregisterListeners(this.live);
055 this.live = live;
056 registerListeners(this.live);
057 }
058
059 private void registerListeners(boolean live) {
060 if (live) {
061 textInputControl.textProperty().addListener(textHandler);
062 } else {
063 EventHandler<? super KeyEvent> delegate = textInputControl.getOnKeyReleased();
064 KeyHandler keyHandler = new KeyHandler(delegate);
065 textInputControl.setOnKeyReleased(keyHandler);
066
067 }
068 }
069
070 private void deregisterListeners(boolean live) {
071 if (live) {
072 textInputControl.textProperty().removeListener(textHandler);
073 } else {
074 EventHandler<? super KeyEvent> handler = textInputControl.getOnKeyReleased();
075 if (handler instanceof TextInputControlMatcherEditor.KeyHandler) {
076 textInputControl.setOnKeyReleased(((TextInputControlMatcherEditor.KeyHandler) handler).getDelegate());
077 }
078 }
079 }
080
081 public void dispose() {
082 deregisterListeners(live);
083 }
084
085 private void refilter() {
086 final int mode = getMode();
087 final String text = textInputControl.getText();
088 final String[] filters;
089
090 // in CONTAINS mode we treat the string as whitespace delimited
091 if (mode == CONTAINS) { filters = text.split("[ \t]"); }
092
093 // in STARTS_WITH, REGULAR_EXPRESSION, or EXACT modes we use the string in its entirety
094 else if (mode == STARTS_WITH || mode == REGULAR_EXPRESSION || mode == EXACT) {
095 filters = new String[]{text};
096 } else { throw new IllegalStateException("Unknown mode: " + mode); }
097
098 setFilterText(filters);
099 }
100
101 private class TextHandler implements ChangeListener<String> {
102 @Override
103 public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
104 refilter();
105 }
106 }
107
108 private class KeyHandler extends DelegatingKeyHandler {
109 public KeyHandler(EventHandler<? super KeyEvent> delegate) {
110 super(delegate);
111 }
112
113 @Override
114 public void handle(KeyEvent event) {
115 if (event.getCode() == KeyCode.ENTER) {
116 refilter();
117 }
118 }
119 }
120
121 private static class DelegatingKeyHandler implements EventHandler<KeyEvent> {
122 private EventHandler<? super KeyEvent> delegate;
123
124 public DelegatingKeyHandler() {
125
126 }
127
128 public DelegatingKeyHandler(EventHandler<? super KeyEvent> delegate) {
129 this.delegate = delegate;
130 }
131
132 @Override
133 public void handle(KeyEvent event) {
134 delegate.handle(event);
135 }
136
137 protected EventHandler<? super KeyEvent> getDelegate() {
138 return delegate;
139 }
140 }
141 }
|