From 1abd22f2c0c7b0ae8d2938ee9a34addd4009ed36 Mon Sep 17 00:00:00 2001 From: Laszlo Kishalmi Date: Wed, 15 Jul 2026 20:03:12 -0700 Subject: [PATCH] Facelift on spellchecker module --- ide/spellchecker/nbproject/project.properties | 2 +- .../modules/spellchecker/ComponentPeer.java | 491 ++++++++---------- .../spellchecker/CompoundDictionary.java | 37 +- .../DefaultLocaleQueryImplementation.java | 81 ++- .../modules/spellchecker/DictionaryImpl.java | 307 ++++------- .../spellchecker/DictionaryProviderImpl.java | 42 +- .../ProjectLocaleQueryImplementation.java | 6 +- .../SpellcheckerHighlightLayerFactory.java | 22 +- .../modules/spellchecker/TrieDictionary.java | 28 +- .../modules/spellchecker/Utilities.java | 2 +- .../AddToDictionaryCompletionItem.java | 10 + .../completion/WordCompletion.java | 88 ++-- .../completion/WordCompletionItem.java | 49 +- .../hints/AddToDictionaryHint.java | 25 +- .../hints/DictionaryBasedHint.java | 37 +- .../options/CheckBoxRenderrer.java | 132 +++-- .../options/DictionaryInstallerPanel.form | 2 +- .../options/DictionaryInstallerPanel.java | 158 +++--- .../options/SpellcheckerOptionsPanel.java | 266 +++++----- .../SpellcheckerOptionsPanelController.java | 11 +- .../spellchecker/plain/PlainTokenList.java | 29 +- .../plain/PlainTokenListProvider.java | 3 +- 22 files changed, 832 insertions(+), 996 deletions(-) diff --git a/ide/spellchecker/nbproject/project.properties b/ide/spellchecker/nbproject/project.properties index 35b054670c38..2b7a0fcc5107 100644 --- a/ide/spellchecker/nbproject/project.properties +++ b/ide/spellchecker/nbproject/project.properties @@ -17,7 +17,7 @@ # under the License. # javac.compilerargs=-Xlint -javac.release=17 +javac.release=21 nbm.homepage=http://spellchecker.netbeans.org nbm.module.author=Jan Lahoda spec.version.base=1.68.0 diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/ComponentPeer.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/ComponentPeer.java index a528f749f2d5..38f44fb3d18e 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/ComponentPeer.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/ComponentPeer.java @@ -59,7 +59,6 @@ import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.Highlighter; -import javax.swing.text.Highlighter.HighlightPainter; import javax.swing.text.JTextComponent; import javax.swing.text.Position; import org.netbeans.api.editor.mimelookup.MimeLookup; @@ -97,18 +96,22 @@ * * @author Jan Lahoda */ -public class ComponentPeer implements PropertyChangeListener, DocumentListener, ChangeListener, CaretListener, AncestorListener { +public final class ComponentPeer implements PropertyChangeListener, DocumentListener, ChangeListener, CaretListener, AncestorListener { + + private record Range(int start, int end) {} private static final Logger LOG = Logger.getLogger(ComponentPeer.class.getName()); - + private DocumentListener weakDocL; - + private final static String SPELLCHECKER_ERROR_HIGHLIGHTS = "spellchecker-error-highlights"; //NOI18N + public static void assureInstalled(JTextComponent pane) { if (pane.getClientProperty(ComponentPeer.class) == null) { pane.putClientProperty(ComponentPeer.class, new ComponentPeer(pane)); } } + @Override public synchronized void propertyChange(PropertyChangeEvent evt) { if (document != pane.getDocument()) { if (document != null) { @@ -130,45 +133,18 @@ public synchronized void propertyChange(PropertyChangeEvent evt) { private Document document; private static final RequestProcessor WORKER = new RequestProcessor("Spellchecker", 1, false, false); - - private final RequestProcessor.Task checker = WORKER.create(new Runnable() { - public void run() { - try { - process(); - } catch (BadLocationException e) { - Exceptions.printStackTrace(e); - } - } - }); - - private final RequestProcessor.Task updateVisibleSpans = WORKER.create(new Runnable() { - public void run() { - try { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - updateCurrentVisibleSpan(); - reschedule(); - } - }); - } catch (InterruptedException ex) { - Exceptions.printStackTrace(ex); - } catch (InvocationTargetException ex) { - Exceptions.printStackTrace(ex); - } - } - }); - private final RequestProcessor.Task computeHint = WORKER.create(new Runnable() { - public void run() { - computeHint(); - } - }); - + private final RequestProcessor.Task checker = WORKER.create(this::process); + + private final RequestProcessor.Task updateVisibleSpans = WORKER.create(this::updateVisibleSpan); + + private final RequestProcessor.Task computeHint = WORKER.create(this::computeHint); + public void reschedule() { cancel(); checker.schedule(100); } - + private synchronized Document getDocument() { return document; } @@ -176,7 +152,6 @@ private synchronized Document getDocument() { /** Creates a new instance of ComponentPeer */ private ComponentPeer(JTextComponent pane) { this.pane = pane; -// reschedule(); pane.addPropertyChangeListener(this); pane.addCaretListener(this); pane.addAncestorListener(this); @@ -186,57 +161,56 @@ private ComponentPeer(JTextComponent pane) { ancestorAdded(null); } - + private Component parentWithListener; - private int[] computeVisibleSpan() { + private Range computeVisibleSpan() { Component parent = pane.getParent(); - + if (parent instanceof JLayeredPane) { parent = parent.getParent(); } - if (parent instanceof JViewport) { - JViewport vp = (JViewport) parent; + if (parent instanceof JViewport vp) { Point start = vp.getViewPosition(); Dimension size = vp.getExtentSize(); Point end = new Point((int) (start.getX() + size.getWidth()), (int) (start.getY() + size.getHeight())); - int startPosition = pane.viewToModel(start); - int endPosition = pane.viewToModel(end); + int startPosition = pane.viewToModel2D(start); + int endPosition = pane.viewToModel2D(end); if (parentWithListener != vp) { vp.addChangeListener(WeakListeners.change(this, vp)); parentWithListener = vp; } - return new int[] {startPosition, endPosition}; + return new Range(startPosition, endPosition); } - return new int[] {0, pane.getDocument().getLength()}; + return new Range(0, pane.getDocument().getLength()); } private void updateCurrentVisibleSpan() { //check possible change in visible rect: - int[] newSpan = computeVisibleSpan(); - + Range newSpan = computeVisibleSpan(); + synchronized (this) { - if (currentVisibleRange == null || currentVisibleRange[0] != newSpan[0] || currentVisibleRange[1] != newSpan[1]) { + if (!newSpan.equals(currentVisibleRange)) { currentVisibleRange = newSpan; reschedule(); } } } - private int[] currentVisibleRange; + private Range currentVisibleRange; - private synchronized int[] getCurrentVisibleSpan() { + private synchronized Range getCurrentVisibleSpan() { return currentVisibleRange; } private final Object tokenListLock = new Object(); private TokenList tokenList; - + private TokenList getTokenList(Document doc) { synchronized(tokenListLock) { if (tokenList == null) { @@ -249,22 +223,22 @@ private TokenList getTokenList(Document doc) { return tokenList; } } - - private void process() throws BadLocationException { + + private void process() { final Document _document = getDocument(); - + if (_document.getLength() == 0) return ; - - final List localHighlights = new LinkedList(); - + + List localHighlights = new LinkedList<>(); + long startTime = System.currentTimeMillis(); - + try { resume(); - + final TokenList _tokenList = getTokenList(_document); - + if (_tokenList == null) { //nothing to do: return ; @@ -274,139 +248,128 @@ private void process() throws BadLocationException { if (d == null) return ; - - final int[] span = getCurrentVisibleSpan(); + + Range span = getCurrentVisibleSpan(); if (span == null) { //not initialized yet: doUpdateCurrentVisibleSpan(); return ; } - - if (span[0] == (-1)) { + + if (span.start == -1) { return ; } - final boolean[] cont = new boolean [1]; - - _document.render(new Runnable() { - public void run() { - if (isCanceled()) { - cont[0] = false; - return; - } else { - _tokenList.setStartOffset(span[0]); - cont[0] = true; - } + AtomicBoolean cont = new AtomicBoolean(); + + _document.render(() -> { + if (isCanceled()) { + cont.set(false);; + return; + } else { + _tokenList.setStartOffset(span.start); + cont.set(true); } }); - - if (!cont[0]) { + + if (!cont.get()) { return ; } final CharSequence[] word = new CharSequence[1]; - + while (!isCanceled()) { - _document.render(new Runnable() { - public void run() { - if (isCanceled()) { - cont[0] = false; + _document.render(() -> { + if (isCanceled()) { + cont.set(false); + return ; + } + cont.set(_tokenList.nextWord()); + if (cont.get()) { + if (_tokenList.getCurrentWordStartOffset() > span.end) { + cont.set(false); return ; } - - if (cont[0] = _tokenList.nextWord()) { - if (_tokenList.getCurrentWordStartOffset() > span[1]) { - cont[0] = false; - return ; - } - - word[0] = _tokenList.getCurrentWordText(); - } + + word[0] = _tokenList.getCurrentWordText(); } }); - - if (!cont[0]) + + if (!cont.get()) break; - + LOG.log(Level.FINER, "going to test word: {0}", word[0]); - + if (word[0].length() < 2) { //ignore single letter words LOG.log(Level.FINER, "too short"); continue; } - + ValidityType validity = d.validateWord(word[0]); - + LOG.log(Level.FINER, "validity: {0}", validity); switch (validity) { case PREFIX_OF_VALID: case BLACKLISTED: case INVALID: - _document.render(new Runnable() { - public void run() { - if (!isCanceled()) { - localHighlights.add(new int[] {_tokenList.getCurrentWordStartOffset(), _tokenList.getCurrentWordStartOffset() + word[0].length()}); - } + _document.render(() -> { + if (!isCanceled()) { + localHighlights.add(new Range(_tokenList.getCurrentWordStartOffset(), _tokenList.getCurrentWordStartOffset() + word[0].length())); } - }); + }); } } } finally { if (!isCanceled()) { if (!(pane instanceof JEditorPane)) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - _document.render(new Runnable() { - public void run() { - if (isCanceled()) { - return; - } - try { - Highlighter h = pane.getHighlighter(); - - if (h != null) { - List oldTags = (List) pane.getClientProperty(ErrorHighlightPainter.class); - - if (oldTags != null) { - for (Object tag : oldTags) { - h.removeHighlight(tag); - } - } - - List newTags = new LinkedList(); - for (int[] current : localHighlights) { - newTags.add(h.addHighlight(current[0], current[1], new ErrorHighlightPainter())); - } - - pane.putClientProperty(ErrorHighlightPainter.class, newTags); + SwingUtilities.invokeLater(() -> { + _document.render(() -> { + if (isCanceled()) { + return; + } + try { + Highlighter h = pane.getHighlighter(); + + if (h != null) { + @SuppressWarnings("unchecked") + List oldTags = (List) pane.getClientProperty(SPELLCHECKER_ERROR_HIGHLIGHTS); + + if (oldTags != null) { + for (Object tag : oldTags) { + h.removeHighlight(tag); } - } catch (BadLocationException e) { - Exceptions.printStackTrace(e); } + + List newTags = new LinkedList<>(); + for (Range current : localHighlights) { + newTags.add(h.addHighlight(current.start, current.end, this::paintErrorHighlights)); + } + + pane.putClientProperty(SPELLCHECKER_ERROR_HIGHLIGHTS, newTags); } - }); - } + } catch (BadLocationException e) { + Exceptions.printStackTrace(e); + } + }); }); } else { final OffsetsBag paneBag = SpellcheckerHighlightLayerFactory.getBag(pane); - _document.render(new Runnable() { - public void run() { - if (isCanceled()) { - return; - } - OffsetsBag localHighlightsBag = new OffsetsBag(_document); - - for (int[] current : localHighlights) { - localHighlightsBag.addHighlight(current[0], current[1], ERROR); - } - paneBag.setHighlights(localHighlightsBag); + _document.render(() -> { + if (isCanceled()) { + return; + } + OffsetsBag localHighlightsBag = new OffsetsBag(_document); + + for (Range current : localHighlights) { + localHighlightsBag.addHighlight(current.start, current.end, ERROR); } + paneBag.setHighlights(localHighlightsBag); }); } - + FileObject file = NbEditorUtilities.getFileObject(_document); if (file != null) { @@ -418,43 +381,36 @@ public void run() { } private static Set knownDocuments = Collections.newSetFromMap(new WeakHashMap<>()); - private static Map locale2UsersLocalDictionary = new HashMap(); - private static Map> project2Reference = new WeakHashMap>(); - + private static Map locale2UsersLocalDictionary = new HashMap<>(); + private static Map> project2Reference = new WeakHashMap<>(); + public static synchronized DictionaryImpl getUsersLocalDictionary(Locale locale) { - DictionaryImpl d = locale2UsersLocalDictionary.get(locale); - - if (d != null) - return d; - - File cache = new File(Places.getUserDirectory(), "private-dictionary-" + locale.toString()); - - locale2UsersLocalDictionary.put(locale, d = new DictionaryImpl(cache, locale)); - - return d; + return locale2UsersLocalDictionary.computeIfAbsent(locale, (l) -> + new DictionaryImpl(new File(Places.getUserDirectory(), "private-dictionary-" + l), l) + ); } - + public static synchronized DictionaryImpl getProjectDictionary(Project p, Locale locale) { Reference r = project2Reference.get(p); DictionaryImpl d = r != null ? r.get() : null; - + if (d == null) { AuxiliaryConfiguration ac = ProjectUtils.getAuxiliaryConfiguration(p); - project2Reference.put(p, new WeakReference(d = new DictionaryImpl(p, ac, locale))); + project2Reference.put(p, new WeakReference<>(d = new DictionaryImpl(p, ac, locale))); } - + return d; } - + public static synchronized Dictionary getDictionary(Document doc) { Dictionary result = (Dictionary) doc.getProperty(CompoundDictionary.class); - + if (result != null) { return result; } - + Locale locale; - + FileObject file = NbEditorUtilities.getFileObject(doc); if (file != null) { @@ -462,20 +418,20 @@ public static synchronized Dictionary getDictionary(Document doc) { } else { locale = DefaultLocaleQueryImplementation.getDefaultLocale(); } - + if (locale == null) { locale = Locale.getDefault(); } - + Dictionary d = ACCESSOR.lookupDictionary(locale); - + if (d == null) return null; //XXX - - List dictionaries = new LinkedList(); - + + List dictionaries = new LinkedList<>(); + dictionaries.add(getUsersLocalDictionary(locale)); - + if (file != null) { Project p = FileOwnerQuery.getOwner(file); @@ -487,14 +443,14 @@ public static synchronized Dictionary getDictionary(Document doc) { } } } - + dictionaries.add(d); - - result = CompoundDictionary.create(dictionaries.toArray(new Dictionary[0])); + + result = new CompoundDictionary(dictionaries); doc.putProperty(CompoundDictionary.class, result); knownDocuments.add(doc); - + return result; } @@ -521,14 +477,17 @@ private void resume() { private static final AttributeSet ERROR = AttributesUtilities.createImmutable(EditorStyleConstants.WaveUnderlineColor, Color.RED, EditorStyleConstants.Tooltip, NbBundle.getMessage(ComponentPeer.class, "TP_MisspelledWord")); + @Override public void insertUpdate(DocumentEvent e) { documentUpdate(); } + @Override public void removeUpdate(DocumentEvent e) { documentUpdate(); } + @Override public void changedUpdate(DocumentEvent e) { } @@ -536,7 +495,7 @@ private void documentUpdate() { doUpdateCurrentVisibleSpan(); cancel(); } - + private void doUpdateCurrentVisibleSpan() { //#156490: updateCurrentVisibleSpan invokes viewToModel, which may throw StateInvariantError //if the starting position of view disappeared from the document in the current change (before the views are adjusted) @@ -544,6 +503,7 @@ private void doUpdateCurrentVisibleSpan() { updateVisibleSpans.schedule(250); } + @Override public void stateChanged(ChangeEvent e) { if (e.getSource() == tokenList) { reschedule(); @@ -551,19 +511,31 @@ public void stateChanged(ChangeEvent e) { doUpdateCurrentVisibleSpan(); } } - + + @Override public void caretUpdate(CaretEvent e) { synchronized (this) { lastCaretPosition = e.getDot(); } - + LOG.fine("scheduling hints computation"); - + computeHint.schedule(100); } - + private int lastCaretPosition = -1; - + + private void updateVisibleSpan() { + try { + SwingUtilities.invokeAndWait(() -> { + updateCurrentVisibleSpan(); + reschedule(); + }); + } catch (InterruptedException | InvocationTargetException ex) { + Exceptions.printStackTrace(ex); + } + } + private void computeHint() { LOG.entering(ComponentPeer.class.getName(), "computeHint"); @@ -578,45 +550,43 @@ private void computeHint() { } final Dictionary d = ComponentPeer.getDictionary(_document); - + if (d == null) { LOG.fine("dictionary == null"); LOG.exiting(ComponentPeer.class.getName(), "computeHint"); return ; } - + final int[] lastCaretPositionCopy = new int[1]; final Position[] span = new Position[2]; final CharSequence[] word = new CharSequence[1]; - + synchronized (this) { lastCaretPositionCopy[0] = lastCaretPosition; } - - _document.render(new Runnable() { - public void run() { - LOG.log(Level.FINE, "lastCaretPosition={0}", lastCaretPositionCopy[0]); - l.setStartOffset(lastCaretPositionCopy[0]); - - if (!l.nextWord()) { - LOG.log(Level.FINE, "l.nextWord() == false"); - return ; - } - - int currentWSO = l.getCurrentWordStartOffset(); - CharSequence w = l.getCurrentWordText(); - int length = w.length(); - - LOG.log(Level.FINE, "currentWSO={0}, w={1}, length={2}", new Object[] {currentWSO, w, length}); - - if (currentWSO <= lastCaretPositionCopy[0] && (currentWSO + length) >= lastCaretPositionCopy[0]) { - try { - span[0] = _document.createPosition(currentWSO); - span[1] = _document.createPosition(currentWSO + length); - word[0] = w; - } catch (BadLocationException e) { - LOG.log(Level.INFO, null, e); - } + + _document.render(() -> { + LOG.log(Level.FINE, "lastCaretPosition={0}", lastCaretPositionCopy[0]); + l.setStartOffset(lastCaretPositionCopy[0]); + + if (!l.nextWord()) { + LOG.log(Level.FINE, "l.nextWord() == false"); + return ; + } + + int currentWSO = l.getCurrentWordStartOffset(); + CharSequence w = l.getCurrentWordText(); + int length = w.length(); + + LOG.log(Level.FINE, "currentWSO={0}, w={1}, length={2}", new Object[] {currentWSO, w, length}); + + if (currentWSO <= lastCaretPositionCopy[0] && (currentWSO + length) >= lastCaretPositionCopy[0]) { + try { + span[0] = _document.createPosition(currentWSO); + span[1] = _document.createPosition(currentWSO + length); + word[0] = w; + } catch (BadLocationException e) { + LOG.log(Level.INFO, null, e); } } }); @@ -628,38 +598,38 @@ public void run() { span[0] = span[1] = null; } } - - List result = new ArrayList(); - + + List result = new ArrayList<>(); + LOG.log(Level.FINE, "word={0}", word[0]); - + if (span[0] != null && span[1] != null) { String currentWord = word[0].toString(); - + for (String proposal : d.findProposals(currentWord)) { result.add(new DictionaryBasedHint(currentWord, proposal, _document, span, "0" + currentWord)); } - + FileObject file = NbEditorUtilities.getFileObject(_document); if (file != null) { Project p = FileOwnerQuery.getOwner(file); Locale locale = LocaleQuery.findLocale(file); - + if (p != null) { DictionaryImpl projectDictionary = getProjectDictionary(p, locale); - + if (projectDictionary != null) { String displayName = NbBundle.getMessage(ComponentPeer.class, "FIX_ToProjectDictionary"); result.add(new AddToDictionaryHint(this, projectDictionary, currentWord, displayName, "1" + currentWord)); } } - + String displayName = NbBundle.getMessage(ComponentPeer.class, "FIX_ToPrivateDictionary"); result.add(new AddToDictionaryHint(this, getUsersLocalDictionary(locale), currentWord, displayName, "2" + currentWord)); } - + if (!result.isEmpty()) { String displayName = NbBundle.getMessage(ComponentPeer.class, "ERR_MisspelledWord"); HintsController.setErrors(_document, ComponentPeer.class.getName(), Collections.singletonList(ErrorDescriptionFactory.createErrorDescription(Severity.HINT, displayName, result, _document, span[0], span[1]))); @@ -670,79 +640,76 @@ public void run() { HintsController.setErrors(_document, ComponentPeer.class.getName(), Collections.emptyList()); } } - + public static LookupAccessor ACCESSOR = new LookupAccessor() { + @Override public Dictionary lookupDictionary(Locale locale) { for (DictionaryProvider p : Lookup.getDefault().lookupAll(DictionaryProvider.class)) { Dictionary d = p.getDictionary(locale); - + if (d != null) return d; } - + return null; } + + @Override public TokenList lookupTokenList(Document doc) { Object mimeTypeObj = doc.getProperty("mimeType"); - String mimeType = "text/plain"; - - if (mimeTypeObj instanceof String) { - mimeType = (String) mimeTypeObj; - } - + String mimeType = mimeTypeObj instanceof String s ? s : "text/plain"; + for (TokenListProvider p : MimeLookup.getLookup(MimePath.get(mimeType)).lookupAll(TokenListProvider.class)) { TokenList l = p.findTokenList(doc); - + if (l != null) return l; } - + return null; - + } }; + @Override public void ancestorAdded(AncestorEvent event) { if (pane.getParent() != null) doUpdateCurrentVisibleSpan(); } + @Override public void ancestorRemoved(AncestorEvent event) {} + @Override public void ancestorMoved(AncestorEvent event) {} - - private class ErrorHighlightPainter implements HighlightPainter { - private ErrorHighlightPainter() { - } - public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) { - g.setColor(Color.RED); - - try { - Rectangle start = pane.modelToView(p0); - Rectangle end = pane.modelToView(p1); + private void paintErrorHighlights(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) { + g.setColor(Color.RED); - if (start.x < 0) { - LOG.log(Level.INFO, "#182545: negative view position: {0} for: {1}", new Object[] {start, p0}); - return; - } + try { + Rectangle start = pane.modelToView(p0); + Rectangle end = pane.modelToView(p1); + + if (start.x < 0) { + LOG.log(Level.INFO, "#182545: negative view position: {0} for: {1}", new Object[] {start, p0}); + return; + } - int waveLength = end.x + end.width - start.x; - if (waveLength > 0) { - int[] wf = {0, 0, -1, -1}; - int[] xArray = new int[waveLength + 1]; - int[] yArray = new int[waveLength + 1]; + int waveLength = end.x + end.width - start.x; + if (waveLength > 0) { + int[] wf = {0, 0, -1, -1}; + int[] xArray = new int[waveLength + 1]; + int[] yArray = new int[waveLength + 1]; - int yBase = (int) (start.y + start.height - 2); - for (int i = 0; i <= waveLength; i++) { - xArray[i] = start.x + i; - yArray[i] = yBase + wf[xArray[i] % 4]; - } - g.drawPolyline(xArray, yArray, waveLength); + int yBase = start.y + start.height - 2; + for (int i = 0; i <= waveLength; i++) { + xArray[i] = start.x + i; + yArray[i] = yBase + wf[xArray[i] % 4]; } - } catch (BadLocationException e) { - Exceptions.printStackTrace(e); + g.drawPolyline(xArray, yArray, waveLength); } + } catch (BadLocationException e) { + Exceptions.printStackTrace(e); } } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/CompoundDictionary.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/CompoundDictionary.java index 338975c9fd97..e6cf766febfd 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/CompoundDictionary.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/CompoundDictionary.java @@ -29,22 +29,19 @@ * * @author Jan Lahoda */ -public class CompoundDictionary implements Dictionary { +public final class CompoundDictionary implements Dictionary { private static final Logger LOGGER = Logger.getLogger(CompoundDictionary.class.getName()); - private Dictionary[] delegates; - - private CompoundDictionary(Dictionary... delegates) { - this.delegates = delegates.clone(); - } - - public static Dictionary create(Dictionary... delegates) { - return new CompoundDictionary(delegates); + private final List delegates; + + public CompoundDictionary(List delegates) { + this.delegates = List.copyOf(delegates); } - + + @Override public ValidityType validateWord(CharSequence word) { ValidityType result = ValidityType.INVALID; - + for (Dictionary d : delegates) { ValidityType thisResult = d.validateWord(word); if (LOGGER.isLoggable(Level.FINE)) { @@ -54,32 +51,34 @@ public ValidityType validateWord(CharSequence word) { if (thisResult == ValidityType.VALID || thisResult == ValidityType.BLACKLISTED) { return thisResult; } - + if (thisResult == ValidityType.PREFIX_OF_VALID && result == ValidityType.INVALID) { result = ValidityType.PREFIX_OF_VALID; } } - + return result; } + @Override public List findValidWordsForPrefix(CharSequence word) { - List result = new LinkedList(); - + List result = new LinkedList<>(); + for (Dictionary d : delegates) { result.addAll(d.findValidWordsForPrefix(word)); } - + return result; } + @Override public List findProposals(CharSequence word) { - List result = new LinkedList(); - + List result = new LinkedList<>(); + for (Dictionary d : delegates) { result.addAll(d.findProposals(word)); } - + return result; } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/DefaultLocaleQueryImplementation.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/DefaultLocaleQueryImplementation.java index 2006dbae771b..016a9c1eef5d 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/DefaultLocaleQueryImplementation.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/DefaultLocaleQueryImplementation.java @@ -23,71 +23,68 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.Locale; import java.util.StringTokenizer; import org.netbeans.modules.spellchecker.spi.LocaleQueryImplementation; import org.openide.ErrorManager; -import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import static java.nio.charset.StandardCharsets.UTF_8; + /** * * @author Jan Lahoda */ @org.openide.util.lookup.ServiceProvider(service=org.netbeans.modules.spellchecker.spi.LocaleQueryImplementation.class, position=2000) public class DefaultLocaleQueryImplementation implements LocaleQueryImplementation { - + + private static final String DEFAULT_LOCALE_FILE = "spellchecker-default-locale"; + /** Creates a new instance of DefaultLocaleQueryImplementation */ public DefaultLocaleQueryImplementation() { } + @Override public Locale findLocale(FileObject file) { return getDefaultLocale(); } - - private static final String FILE_NAME = "spellchecker-default-locale"; - + + private static FileObject getDefaultLocaleFile() { - return FileUtil.getConfigFile(FILE_NAME); + return FileUtil.getConfigFile(DEFAULT_LOCALE_FILE); } - + public static Locale getDefaultLocale() { FileObject file = getDefaultLocaleFile(); - + if (file == null) - return Locale.getDefault (); - - Charset UTF8 = StandardCharsets.UTF_8; - + return Locale.getDefault(); + BufferedReader r = null; - + try { - r = new BufferedReader(new InputStreamReader(file.getInputStream(), UTF8)); - + r = new BufferedReader(new InputStreamReader(file.getInputStream(), UTF_8)); + String localeLine = r.readLine(); - + if (localeLine == null || localeLine.trim().isEmpty()) return null; - - String language = ""; + + StringTokenizer stok = new StringTokenizer(localeLine, "_"); + + String language = stok.nextToken(); String country = ""; String variant = ""; - - StringTokenizer stok = new StringTokenizer(localeLine, "_"); - - language = stok.nextToken(); - + if (stok.hasMoreTokens()) { country = stok.nextToken(); - + if (stok.hasMoreTokens()) variant = stok.nextToken(); } - - return new Locale(language, country, variant); + + return Locale.of(language, country, variant); } catch (IOException e) { ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); } finally { @@ -98,36 +95,24 @@ public static Locale getDefaultLocale() { ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); } } - + return null; } - + public static void setDefaultLocale(Locale locale) { FileObject file = getDefaultLocaleFile(); - Charset UTF8 = StandardCharsets.UTF_8; - FileLock lock = null; - PrintWriter pw = null; - + try { if (file == null) { - file = FileUtil.getConfigRoot().createData(FILE_NAME); + file = FileUtil.getConfigRoot().createData(DEFAULT_LOCALE_FILE); } - - lock = file.lock(); - pw = new PrintWriter(new OutputStreamWriter(file.getOutputStream(lock), UTF8)); - - pw.println(locale.toString()); - ComponentPeer.clearDoc2DictionaryCache(); + try (var lock = file.lock(); var pw = new PrintWriter(new OutputStreamWriter(file.getOutputStream(lock), UTF_8))) { + pw.println(locale.toString()); + ComponentPeer.clearDoc2DictionaryCache(); + } } catch (IOException e) { ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); - } finally { - if (pw != null) - pw.close(); - - if (lock != null) { - lock.releaseLock(); - } } } } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/DictionaryImpl.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/DictionaryImpl.java index b8b47afb1e33..b6b38641f50d 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/DictionaryImpl.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/DictionaryImpl.java @@ -18,15 +18,9 @@ */ package org.netbeans.modules.spellchecker; -import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -41,7 +35,6 @@ import org.netbeans.modules.spellchecker.spi.dictionary.ValidityType; import org.netbeans.spi.project.AuxiliaryConfiguration; import org.openide.util.Exceptions; -import org.openide.util.Mutex.Action; import org.openide.util.RequestProcessor; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -52,10 +45,10 @@ * * @author Jan Lahoda */ -public class DictionaryImpl implements Dictionary { - +public final class DictionaryImpl implements Dictionary { + private static final RequestProcessor WORKER = new RequestProcessor(DictionaryImpl.class.getName(), 1, false, false); - private List dictionary = null; + private final List dictionary = new ArrayList<>(); private StringBuffer dictionaryText = null; private final File source; private final Project p; @@ -80,119 +73,99 @@ public DictionaryImpl(Project p, AuxiliaryConfiguration ac, Locale locale) { this.dictionaryComparator = prepareDictionaryComparator(locale); loadDictionary(ac); } - - private Comparator prepareDictionaryComparator(final Locale locale) { - return new Comparator() { - public int compare(String s1, String s2) { - return s1.toLowerCase(locale).compareTo(s2.toLowerCase(locale)); - } - }; + + private Comparator prepareDictionaryComparator(Locale locale) { + return (String s1, String s2) -> s1.toLowerCase(locale).compareTo(s2.toLowerCase(locale)); } private void loadDictionary(File source) { if (!source.canRead()) return ; - - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(new FileInputStream(source), StandardCharsets.UTF_8)); - - String line = null; - - while ((line = reader.readLine()) != null) { - addEntryImpl(line); - } - } catch (IOException e) { - e.printStackTrace(System.err); - } finally { + + synchronized (dictionary) { try { - if (reader != null) { - reader.close(); - } + dictionary.addAll(Files.readAllLines(source.toPath())); } catch (IOException e) { e.printStackTrace(System.err); - } + } + dictionary.sort(dictionaryComparator); } - - getDictionary().sort(dictionaryComparator); + } - + private static final String WORDLIST = "spellchecker-wordlist"; private static final String NAMESPACE = "http://www.netbeans.org/ns/spellchecker-wordlist/1"; - + private void loadDictionary(final AuxiliaryConfiguration ac) { - ProjectManager.mutex().readAccess(new Action() { - public Void run() { - Element conf = ac.getConfigurationFragment(WORDLIST, NAMESPACE, true); + ProjectManager.mutex().readAccess(() -> { + Element conf = ac.getConfigurationFragment(WORDLIST, NAMESPACE, true); - if (conf == null) { - return null; - } - - NodeList childNodes = conf.getChildNodes(); + if (conf == null) { + return; + } - for (int cntr = 0; cntr < childNodes.getLength(); cntr++) { - Node n = childNodes.item(cntr); + NodeList childNodes = conf.getChildNodes(); - if ("word".equals(n.getLocalName())) { - addEntryImpl(n.getTextContent()); - } + for (int cntr = 0; cntr < childNodes.getLength(); cntr++) { + Node n = childNodes.item(cntr); + + if ("word".equals(n.getLocalName())) { + addEntryImpl(n.getTextContent()); } - return null; } }); - - getDictionary().sort(dictionaryComparator); + + dictionary.sort(dictionaryComparator); } - + public int findLesser(String word) { word = word.toLowerCase(locale); - List dict = getDictionary(); - + List dict = dictionary; + int lower = 0; int upper = dict.size() - 1; - + boolean last = false; - + while (true) { if (lower == upper) break; - + if (last) break; - + if ((upper - lower) == 1) last = true; - + int current = (lower + upper) / 2; String currentObj = dict.get(current); - + int result = currentObj.toLowerCase(locale).compareTo(word); - + if (result == 0) return current; - + if (result < 0) { lower = current + 1; } - + if (result > 0) { upper = current - 1; } } - + if (dict.get(lower).toLowerCase(locale).compareTo(word) == 0) return lower; else return (lower + 1) < dict.size() ? lower + 1 : lower; } - + public ValidityType findWord(String word) { - if (getDictionary().isEmpty()) return ValidityType.INVALID; - String str = getDictionary().get(findLesser(word)); + if (dictionary.isEmpty()) return ValidityType.INVALID; + String str = dictionary.get(findLesser(word)); String lWord = word.toLowerCase(locale); -// System.err.println("str=" + str); + if (str.startsWith(word) || str.startsWith(lWord)) { if (str.equals(word) || str.equals(lWord)) return ValidityType.VALID; @@ -201,68 +174,44 @@ public ValidityType findWord(String word) { } else return ValidityType.INVALID; } - - protected synchronized List getDictionary() { - if (dictionary == null) - dictionary = new ArrayList(); - -// System.err.println("returning dictionary=" + System.identityHashCode(dictionary)); - return dictionary; - } - + protected synchronized StringBuffer getDictionaryText() { if (dictionaryText == null) { dictionaryText = new StringBuffer(); dictionaryText.append('\n'); - - for (String e : getDictionary()) { + + for (String e : dictionary) { dictionaryText.append(e); dictionaryText.append('\n'); } } - + return dictionaryText; } - + private void addEntryImpl(String entry) { - getDictionary().add(entry); + dictionary.add(entry); } - - private void dumpToFile(List dictionary) { - BufferedWriter writer = null; + private void dumpToFile(List dictionary) { try { - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(source), StandardCharsets.UTF_8)); - - for (String s : dictionary) { - writer.append(s); - writer.append('\n'); - } + Files.write(source.toPath(), dictionary); } catch (IOException e) { Exceptions.printStackTrace(e); - } finally { - try { - if (writer != null) { - writer.close(); - } - } catch (IOException e) { - Exceptions.printStackTrace(e); - } } } - + private void dumpToProject(final List dictionary) { - ProjectManager.mutex().writeAccess(new Action(){ - public Void run() { + ProjectManager.mutex().writeAccess(() -> { Element conf = null; Document doc = createXmlDocument(); - + if (doc != null) { conf = doc.createElementNS(NAMESPACE, WORDLIST); } - + if (conf == null) { - return null; + return; } for (String s : dictionary) { @@ -273,23 +222,18 @@ public Void run() { } ac.putConfigurationFragment(conf, true); - return null; } - }); - - WORKER.post(new Runnable() { - @Override public void run() { - try { - ProjectManager.getDefault().saveProject(p); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } catch (IllegalArgumentException ex) { - Exceptions.printStackTrace(ex); - } + ); + + WORKER.post(() -> { + try { + ProjectManager.getDefault().saveProject(p); + } catch (IOException | IllegalArgumentException ex) { + Exceptions.printStackTrace(ex); } }); } - + private Document createXmlDocument() { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { @@ -298,120 +242,90 @@ private Document createXmlDocument() { return null; } } - + public synchronized void addEntry(String entry) { - List dictionary = getDictionary(); int index = Collections.binarySearch(dictionary, entry, dictionaryComparator); - + if (index >= 0) return ; - + index = -index - 1; - + dictionary.add(index, entry); dictionaryText = null; - + if (source != null) { dumpToFile(dictionary); } else { dumpToProject(dictionary); } } - + public List completions(String word) { if ("".equals(word)) return Collections.emptyList(); - + int start = findLesser(word); - -// if (!((String )getDictionary().get(start)).equalsIgnoreCase(word)) { -// start++; -// } - int end = findLesser(word.substring(0, word.length() - 1) + (char) (word.charAt(word.length() - 1) + 1)); - - return getDictionary().subList(start, end/* + 1*/); - } - - private static class Pair { - private int distance; - private String proposedWord; - - public Pair(String proposedWord, int distance) { - this.distance = distance; - this.proposedWord = proposedWord; - } + + return dictionary.subList(start, end/* + 1*/); } - - private static class SimilarComparator implements Comparator { - - public int compare(Pair p1, Pair p2) { - if (p1.distance < p2.distance) - return (-1); - - if (p1.distance > p2.distance) - return 1; - - return 0; - } - + + private record Pair(String proposedWord, int distance) { + static final Comparator SIMILAR_COMPARATOR = (Pair p1, Pair p2) -> p1.distance - p2.distance; } - + private static int MINIMAL_SIMILAR_COUNT = 3; - + public List getSimilarWords(String word) { - if (getDictionary().isEmpty()) return Collections.emptyList(); + if (dictionary.isEmpty()) return List.of(); List proposal = dynamicProgramming(word, getDictionaryText(), 5); - List result = new ArrayList(); - - //future: -// if (Character.isLowerCase(word.charAt(0))) -// return result; - - proposal.sort(new SimilarComparator()); - - Iterator words = proposal.iterator(); + List result = new ArrayList<>(); + + proposal.sort(Pair.SIMILAR_COMPARATOR); + + Iterator words = proposal.iterator(); int proposedCount = 0; int lastDistance = 0; - + while (words.hasNext()) { - Pair pair = (Pair) words.next(); - + Pair pair = words.next(); + if (proposedCount >= MINIMAL_SIMILAR_COUNT && lastDistance != pair.distance) continue; - + result.add(pair.proposedWord); proposedCount++; lastDistance = pair.distance; } - + return result; } - + private static List dynamicProgramming(String pattern, CharSequence text, int distance) { - List result = new ArrayList(); + List result = new ArrayList<>(); pattern = pattern.toLowerCase(); - + int[] old = new int[pattern.length() + 1]; int[] current = new int[pattern.length() + 1]; int[] oldLength = new int[pattern.length() + 1]; int[] length = new int[pattern.length() + 1]; - + for (int cntr = 0; cntr < old.length; cntr++) { old[cntr] = distance + 1;//cntr; oldLength[cntr] = (-1); } - + current[0] = old[0] = oldLength[0] = length[0] = 0; - + int currentIndex = 0; - + while (currentIndex < text.length()) { for (int cntr = 0; cntr < pattern.length(); cntr++) { int insert = old[cntr + 1] + 1; int delete = current[cntr] + 1; int replace = old[cntr] + ((pattern.charAt(cntr) == text.charAt(currentIndex)) ? 0 : 1); - + if (insert < delete) { if (insert < replace) { current[cntr + 1] = insert; @@ -430,46 +344,49 @@ private static List dynamicProgramming(String pattern, CharSequence text, } } } - + if (current[pattern.length()] <= distance) { int start = currentIndex - length[pattern.length()] + 1; int end = currentIndex + 1; - + end = end >= text.length() ? text.length() - 1 : end; - + if ((start == 0 || text.charAt(start - 1) == '\n') && text.charAt(end) == '\n') { String occurence = text.subSequence(start, end).toString(); - + if (occurence.indexOf('\n') == (-1) && !pattern.equals(occurence)) { result.add(new Pair(occurence, current[pattern.length()])); } } } - + currentIndex++; - + int[] temp = old; - + old = current; current = temp; - + temp = oldLength; - + oldLength = length; length = temp; } - + return result; } + @Override public ValidityType validateWord(CharSequence word) { return findWord(word.toString()); } + @Override public List findValidWordsForPrefix(CharSequence word) { return Collections.emptyList(); } + @Override public List findProposals(CharSequence word) { return getSimilarWords(word.toString()); } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/DictionaryProviderImpl.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/DictionaryProviderImpl.java index c37561a896f1..785023ed4ef7 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/DictionaryProviderImpl.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/DictionaryProviderImpl.java @@ -20,7 +20,6 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; @@ -40,19 +39,20 @@ import org.openide.ErrorManager; import org.openide.modules.InstalledFileLocator; import org.openide.util.NbBundle; +import org.openide.util.lookup.ServiceProvider; /** * * @author Jan Lahoda */ -@org.openide.util.lookup.ServiceProvider(service=org.netbeans.modules.spellchecker.spi.dictionary.DictionaryProvider.class) +@ServiceProvider(service=DictionaryProvider.class) public class DictionaryProviderImpl implements DictionaryProvider { /** Creates a new instance of DictionaryProviderImpl */ public DictionaryProviderImpl() { } - private Map dictionaries = new HashMap(); + private final Map dictionaries = new HashMap<>(); // public DictionaryImpl getDefault() { // return getDictionary(Locale.getDefault()); @@ -62,6 +62,7 @@ public synchronized void clearDictionaries() { dictionaries.clear(); } + @Override public synchronized Dictionary getDictionary(Locale locale) { Iterator suffixes = getLocalizingSuffixes(locale); @@ -76,16 +77,12 @@ public synchronized Dictionary getDictionary(Locale locale) { } public static synchronized Locale[] getInstalledDictionariesLocales() { - Collection hardcoded = new HashSet(); - Collection maskedHardcoded = new HashSet(); - Collection user = new HashSet(); + Collection hardcoded = new HashSet<>(); + Collection maskedHardcoded = new HashSet<>(); + Collection user = new HashSet<>(); for (File dictDir : InstalledFileLocator.getDefault().locateAll("modules/dict", null, false)) { - File[] children = dictDir.listFiles(new FileFilter() { - public boolean accept(File pathname) { - return pathname.isFile() && pathname.getName().startsWith("dictionary_"); - } - }); + File[] children = dictDir.listFiles((File pathname) -> pathname.isFile() && pathname.getName().startsWith("dictionary_")); if (children == null) continue; @@ -118,12 +115,12 @@ public boolean accept(File pathname) { hardcoded.removeAll(maskedHardcoded); hardcoded.addAll(user); - return hardcoded.toArray(new Locale[0]); + return hardcoded.toArray(Locale[]::new); } private synchronized Dictionary createDictionary(Locale locale) { try { - List sources = new ArrayList(); + List sources = new ArrayList<>(); String suffix = getDictionaryStream(locale, sources); if (suffix == null) { @@ -143,15 +140,15 @@ private synchronized Dictionary createDictionary(Locale locale) { } static String getDictionaryStream(Locale locale, List streams) throws IOException { - Iterator suffixes = getLocalizingSuffixes(locale); + Iterator suffixes = getLocalizingSuffixes(locale); while (suffixes.hasNext()) { - String currentSuffix = (String) suffixes.next(); + String currentSuffix = suffixes.next(); File file = InstalledFileLocator.getDefault().locate("modules/dict/dictionary" + currentSuffix + ".txt", null, false); if (file != null) { - streams.add(file.toURI().toURL()); + streams.add(org.openide.util.Utilities.toURI(file).toURL()); return currentSuffix; } @@ -204,7 +201,7 @@ static Iterator getLocalizingSuffixes(Locale locale) { return new LocaleIterator(locale); } - /** This class (enumeration) gives all localized sufixes using nextElement + /** This class (enumeration) gives all localized suffixes using nextElement * method. It goes through given Locale and continues through Locale.getDefault() * Example 1: * Locale.getDefault().toString() -> "_en_US" @@ -259,6 +256,7 @@ public LocaleIterator(Locale locale) { /** @return next sufix. * @exception NoSuchElementException if there is no more locale sufix. */ + @Override public String next() throws NoSuchElementException { if (current == null) throw new NoSuchElementException(); @@ -280,15 +278,7 @@ public String next() throws NoSuchElementException { } else { if (lastUnderbar == -1) { -// if (defaultInProgress) reset(); -// else { -// // [PENDING] stuff with trying the default locale -// // after the real one does not actually seem to work... -// locale = Locale.getDefault(); -// current = '_' + locale.toString(); -// defaultInProgress = true; -// } } else { current = current.substring(0, lastUnderbar); @@ -317,10 +307,12 @@ private void reset() { } /** Tests if there is any sufix.*/ + @Override public boolean hasNext() { return (current != null); } + @Override public void remove() throws UnsupportedOperationException { throw new UnsupportedOperationException(); } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/ProjectLocaleQueryImplementation.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/ProjectLocaleQueryImplementation.java index fc5b896dc445..ec7d1bb8e60d 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/ProjectLocaleQueryImplementation.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/ProjectLocaleQueryImplementation.java @@ -23,23 +23,25 @@ import org.netbeans.api.project.Project; import org.netbeans.modules.spellchecker.spi.LocaleQueryImplementation; import org.openide.filesystems.FileObject; +import org.openide.util.lookup.ServiceProvider; /** * * @author Jan Lahoda */ -@org.openide.util.lookup.ServiceProvider(service=org.netbeans.modules.spellchecker.spi.LocaleQueryImplementation.class, position=1000) +@ServiceProvider(service=LocaleQueryImplementation.class, position=1000) public class ProjectLocaleQueryImplementation implements LocaleQueryImplementation { /** Creates a new instance of ProjectLocaleQueryImplementation */ public ProjectLocaleQueryImplementation() { } + @Override public Locale findLocale(FileObject file) { Project p = FileOwnerQuery.getOwner(file); if (p != null) { - LocaleQueryImplementation i = (LocaleQueryImplementation) p.getLookup().lookup(LocaleQueryImplementation.class); + LocaleQueryImplementation i = p.getLookup().lookup(LocaleQueryImplementation.class); if (i != null) { return i.findLocale(file); diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/SpellcheckerHighlightLayerFactory.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/SpellcheckerHighlightLayerFactory.java index ea04552cc171..7f59bc5951ba 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/SpellcheckerHighlightLayerFactory.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/SpellcheckerHighlightLayerFactory.java @@ -30,30 +30,30 @@ * * @author Jan Lahoda */ -public class SpellcheckerHighlightLayerFactory implements HighlightsLayerFactory { - +public final class SpellcheckerHighlightLayerFactory implements HighlightsLayerFactory { + public SpellcheckerHighlightLayerFactory() { } - + public HighlightsLayer[] createLayers(Context ctx) { OffsetsBag bag = getBag(ctx.getComponent()); - return new HighlightsLayer[] { - HighlightsLayer.create(SpellcheckerHighlightLayerFactory.class.getName(), ZOrder.CARET_RACK.forPosition(30), true, bag), - }; + return new HighlightsLayer[]{ + HighlightsLayer.create(SpellcheckerHighlightLayerFactory.class.getName(), ZOrder.CARET_RACK.forPosition(30), true, bag),}; } - + public static synchronized OffsetsBag getBag(JTextComponent component) { Document doc = component.getDocument(); OffsetsBag bag = null; if (doc != null) { bag = (OffsetsBag) doc.getProperty(SpellcheckerHighlightLayerFactory.class); if (bag == null) { - doc.putProperty(SpellcheckerHighlightLayerFactory.class, bag = new OffsetsBag(doc)); + bag = new OffsetsBag(doc); + doc.putProperty(SpellcheckerHighlightLayerFactory.class, bag); } } - Spellchecker.register (component); - + Spellchecker.register(component); + return bag; } - + } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/TrieDictionary.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/TrieDictionary.java index 210992c107c7..adc1dc2838cc 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/TrieDictionary.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/TrieDictionary.java @@ -77,16 +77,14 @@ private TrieDictionary(File data) throws IOException { this.array = null; FileInputStream ins = new FileInputStream(data); - FileChannel channel = ins.getChannel(); - - try { + try (FileChannel channel = ins.getChannel()) { this.buffer = channel.map(MapMode.READ_ONLY, 0, channel.size()); } finally { - channel.close(); ins.close(); } } + @Override public ValidityType validateWord(CharSequence word) { String wordString = word.toString(); ValidityType type = validateWordImpl(wordString.toLowerCase()); @@ -119,8 +117,9 @@ private ValidityType validateWordImpl(CharSequence word) { return ValidityType.PREFIX_OF_VALID; } + @Override public List findValidWordsForPrefix(CharSequence word) { - List result = new ArrayList(); + List result = new ArrayList<>(); int node = findNode(word, 0, 4); if (node == (-1)) @@ -129,6 +128,7 @@ public List findValidWordsForPrefix(CharSequence word) { return findValidWordsForPrefix(new StringBuffer(word), node, result); } + @Override public List findProposals(CharSequence pattern) { ListProposalAcceptor result = new ListProposalAcceptor(); @@ -307,7 +307,7 @@ private static int distance(CharSequence pattern, CharSequence word) { } private static void constructTrie(ByteArray array, List sources) throws IOException { - SortedSet data = new TreeSet(); + SortedSet data = new TreeSet<>(); for (URL u : sources) { FileObject f = URLMapper.findFileObject(u); @@ -335,7 +335,7 @@ private static void constructTrieData(ByteArray array, SortedSet data) throws IOException { - Map> char2Words = new TreeMap>(); + Map> char2Words = new TreeMap<>(); boolean representsFullWord = !data.isEmpty() && data.first().length() <= currentChar; Iterator dataIt = data.iterator(); @@ -349,7 +349,7 @@ private static int encodeOneLayer(ByteArray array, int currentPointer, int curre SortedSet words = char2Words.get(c); if (words == null) { - char2Words.put(c, words = new TreeSet()); + char2Words.put(c, words = new TreeSet<>()); } words.add(word); @@ -386,8 +386,8 @@ private static int encodeOneLayer(ByteArray array, int currentPointer, int curre private static final class FutureDictionary implements Dictionary, Runnable { private final File trie; private final List sources; - private final AtomicReference delegate = new AtomicReference(); - private final AtomicReference workingTask = new AtomicReference(); + private final AtomicReference delegate = new AtomicReference<>(); + private final AtomicReference workingTask = new AtomicReference<>(); private final AtomicBoolean wasBroken = new AtomicBoolean(); public FutureDictionary(File trie, List sources) throws IOException { @@ -396,6 +396,7 @@ public FutureDictionary(File trie, List sources) throws IOException { workingTask.set(WORKER.post(this)); } + @Override public ValidityType validateWord(CharSequence word) { waitDictionaryConstructed(); @@ -412,6 +413,7 @@ public ValidityType validateWord(CharSequence word) { return ValidityType.VALID; } + @Override public List findValidWordsForPrefix(CharSequence word) { waitDictionaryConstructed(); @@ -428,6 +430,7 @@ public List findValidWordsForPrefix(CharSequence word) { return Collections.emptyList(); } + @Override public List findProposals(CharSequence word) { waitDictionaryConstructed(); @@ -464,6 +467,7 @@ private void rebuild(Throwable t) { } } + @Override public void run() { trie.getParentFile().mkdirs(); @@ -474,9 +478,7 @@ public void run() { d.verifyDictionary(); delegate.set(d); return ;//valid - } catch (IOException ex) { - LOG.log(Level.INFO, "Dictionary file failed validation, attempting to rebuild", ex); - } catch (IndexOutOfBoundsException ex) { + } catch (IOException | IndexOutOfBoundsException ex) { LOG.log(Level.INFO, "Dictionary file failed validation, attempting to rebuild", ex); } } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/Utilities.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/Utilities.java index 2b5338c4b945..10f603116dc0 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/Utilities.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/Utilities.java @@ -46,6 +46,6 @@ public static Locale name2Locale(String name) { } } - return new Locale(language, country, variant); + return Locale.of(language, country, variant); } } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/AddToDictionaryCompletionItem.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/AddToDictionaryCompletionItem.java index 28499f4b4435..b20cfcbe1d6a 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/AddToDictionaryCompletionItem.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/AddToDictionaryCompletionItem.java @@ -59,6 +59,7 @@ public AddToDictionaryCompletionItem ( this.projects = projects; } + @Override public void defaultAction ( final JTextComponent component ) { @@ -77,11 +78,13 @@ public void defaultAction ( componentPeer.reschedule(); } + @Override public void processKeyEvent ( KeyEvent evt ) { } + @Override public int getPreferredWidth ( Graphics g, Font defaultFont @@ -89,6 +92,7 @@ public int getPreferredWidth ( return CompletionUtilities.getPreferredWidth (getText (), null, g, defaultFont); } + @Override public void render ( Graphics g, Font defaultFont, @@ -110,24 +114,29 @@ null, getText (), null, g, ); } + @Override public CompletionTask createDocumentationTask () { return null; } + @Override public CompletionTask createToolTipTask () { return null; } + @Override public boolean instantSubstitution ( JTextComponent component ) { return true; } + @Override public int getSortPriority () { return 200; } + @Override public CharSequence getSortText () { return getText(); } @@ -138,6 +147,7 @@ protected String getText () { return NbBundle.getMessage (AddToDictionaryCompletionItem.class, "CTL_Add_to_private"); } + @Override public CharSequence getInsertPrefix () { return ""; } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/WordCompletion.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/WordCompletion.java index af3c2adbbab0..b4feeb14662e 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/WordCompletion.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/WordCompletion.java @@ -35,87 +35,91 @@ import org.netbeans.spi.editor.completion.support.AsyncCompletionTask; import org.openide.ErrorManager; - /** * * @author Jan Lahoda */ public class WordCompletion implements CompletionProvider { - - /** Creates a new instance of WordCompletion */ + + /** + * Creates a new instance of WordCompletion + */ public WordCompletion() { } + @Override public CompletionTask createTask(int queryType, JTextComponent component) { if (queryType == COMPLETION_QUERY_TYPE) { return new AsyncCompletionTask(new Query(), component); } - + return null; } - + + @Override public int getAutoQueryTypes(JTextComponent component, String typedText) { return 0; } - + private static class Query extends AsyncCompletionQuery { - + + @Override protected void query(CompletionResultSet resultSet, Document document, final int caretOffset) { Dictionary dictionary = ComponentPeer.getDictionary(document); - final TokenList l = ComponentPeer.ACCESSOR.lookupTokenList(document); - + final TokenList l = ComponentPeer.ACCESSOR.lookupTokenList(document); + if (dictionary != null && l != null && document instanceof BaseDocument) { final BaseDocument bdoc = (BaseDocument) document; final String[] text = new String[2]; - - document.render(new Runnable() { - public void run() { - try { - int lineStart = LineDocumentUtils.getLineStartOffset(bdoc, caretOffset); - - l.setStartOffset(lineStart); - - while (l.nextWord()) { - int start = l.getCurrentWordStartOffset(); - int end = l.getCurrentWordStartOffset() + l.getCurrentWordText().length(); - - if (start < caretOffset && end >= caretOffset) { - text[0] = l.getCurrentWordText().subSequence(0, caretOffset - start).toString(); - text[1] = l.getCurrentWordText().toString(); - return ; - } + + document.render(() -> { + try { + int lineStart = LineDocumentUtils.getLineStartOffset(bdoc, caretOffset); + + l.setStartOffset(lineStart); + + while (l.nextWord()) { + int start = l.getCurrentWordStartOffset(); + int end = l.getCurrentWordStartOffset() + l.getCurrentWordText().length(); + + if (start < caretOffset && end >= caretOffset) { + text[0] = l.getCurrentWordText().subSequence(0, caretOffset - start).toString(); + text[1] = l.getCurrentWordText().toString(); + return; } - } catch (BadLocationException e) { - ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); } + } catch (BadLocationException e) { + ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); } }); - + if (text[0] != null) { int i = 0; for (String proposal : dictionary.findValidWordsForPrefix(text[0])) { - resultSet.addItem (new WordCompletionItem ( - caretOffset - text[0].length (), - proposal + resultSet.addItem(new WordCompletionItem( + caretOffset - text[0].length(), + proposal )); - if (i == 8) break; + if (i == 8) { + break; + } i++; } - if (dictionary.validateWord (text [1]) != ValidityType.VALID) { - resultSet.addItem (new AddToDictionaryCompletionItem ( - text [1], - true + if (dictionary.validateWord(text[1]) != ValidityType.VALID) { + resultSet.addItem(new AddToDictionaryCompletionItem( + text[1], + true )); - resultSet.addItem (new AddToDictionaryCompletionItem ( - text [1], - false + resultSet.addItem(new AddToDictionaryCompletionItem( + text[1], + false )); } } } - + resultSet.finish(); } } - + } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/WordCompletionItem.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/WordCompletionItem.java index 66cf15f48e30..7442b1ad4ee5 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/WordCompletionItem.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/completion/WordCompletionItem.java @@ -38,49 +38,34 @@ * * @author Jan Lahoda */ -public class WordCompletionItem implements CompletionItem { +public record WordCompletionItem(int substituteOffset, String word) implements CompletionItem { - private int substituteOffset; - private String word; - - /** Creates a new instance of WordCompletionItem */ - public WordCompletionItem(int substituteOffset, String word) { - this.substituteOffset = substituteOffset; - this.word = word; - } - - public void setSubstituteOffset(int substituteOffset) { - this.substituteOffset = substituteOffset; - } - - public int getSubstituteOffset() { - return substituteOffset; - } - + @Override public void defaultAction(final JTextComponent component) { Completion.get().hideCompletion(); Completion.get().hideDocumentation(); - NbDocument.runAtomic((StyledDocument) component.getDocument(), new Runnable() { - public void run() { - Document doc = component.getDocument(); - - try { - doc.remove(substituteOffset, component.getCaretPosition() - substituteOffset); - doc.insertString(substituteOffset, getText(), null); - } catch (BadLocationException e) { - ErrorManager.getDefault().notify(e); - } + NbDocument.runAtomic((StyledDocument) component.getDocument(), () -> { + Document doc = component.getDocument(); + + try { + doc.remove(substituteOffset, component.getCaretPosition() - substituteOffset); + doc.insertString(substituteOffset, getText(), null); + } catch (BadLocationException e) { + ErrorManager.getDefault().notify(e); } }); } + @Override public void processKeyEvent(KeyEvent evt) { } + @Override public int getPreferredWidth(Graphics g, Font defaultFont) { return CompletionUtilities.getPreferredWidth(getText(), null, g, defaultFont); } + @Override public void render(Graphics g, Font defaultFont, Color defaultColor, Color backgroundColor, int width, int height, boolean selected) { if (selected) { g.setColor(backgroundColor); @@ -90,30 +75,36 @@ public void render(Graphics g, Font defaultFont, Color defaultColor, Color backg CompletionUtilities.renderHtml(null, getText(), null, g, defaultFont, defaultColor, width, height, selected); } + @Override public CompletionTask createDocumentationTask() { return null; } + @Override public CompletionTask createToolTipTask() { return null; } + @Override public boolean instantSubstitution(JTextComponent component) { return true; } + @Override public int getSortPriority() { return 100; } + @Override public CharSequence getSortText() { return getText(); } - protected String getText() { + private String getText() { return word; } + @Override public CharSequence getInsertPrefix() { return getText(); } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/hints/AddToDictionaryHint.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/hints/AddToDictionaryHint.java index 193b9b46b316..8dab69823361 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/hints/AddToDictionaryHint.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/hints/AddToDictionaryHint.java @@ -27,33 +27,22 @@ * * @author Jan Lahoda */ -public final class AddToDictionaryHint implements EnhancedFix { +public record AddToDictionaryHint(ComponentPeer peer, DictionaryImpl d, String word, String text, String sortText) implements EnhancedFix { - private DictionaryImpl d; - private String word; - private String text; - private ComponentPeer peer; - private String sortText; - - public AddToDictionaryHint(ComponentPeer peer, DictionaryImpl d, String word, String text, String sortText) { - this.peer = peer; - this.d = d; - this.word = word; - this.text = text; - this.sortText = sortText; - } - + @Override public String getText() { return String.format(text, word); } + @Override public ChangeInfo implement() { d.addEntry(word); - peer.reschedule(); - - return null; + peer.reschedule(); + + return null; } + @Override public CharSequence getSortText() { return sortText; } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/hints/DictionaryBasedHint.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/hints/DictionaryBasedHint.java index be8d2d24f683..279726a4e81a 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/hints/DictionaryBasedHint.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/hints/DictionaryBasedHint.java @@ -32,45 +32,32 @@ * * @author Jan Lahoda */ -public final class DictionaryBasedHint implements EnhancedFix { - - private String original; - private Document doc; - private String proposal; - private Position[] span; - private String sortText; - - public DictionaryBasedHint(String original, String proposal, Document doc, Position[] span, String sortText) { - this.original = original; - this.doc = doc; - this.proposal = proposal; - this.span = span; - this.sortText = sortText; - } +public record DictionaryBasedHint(String original, String proposal, Document doc, Position[] span, String sortText) implements EnhancedFix { + @Override public String getText() { return NbBundle.getMessage(DictionaryBasedHint.class, "FIX_ChangeWord", original, proposal); } + @Override public ChangeInfo implement() { try { - NbDocument.runAtomicAsUser((StyledDocument) doc, new Runnable() { - public void run() { - try { - doc.remove(span[0].getOffset(), span[1].getOffset() - span[0].getOffset()); - doc.insertString(span[0].getOffset(), proposal, null); - } catch (BadLocationException e) { - ErrorManager.getDefault().notify(e); - } + NbDocument.runAtomicAsUser((StyledDocument) doc, () -> { + try { + doc.remove(span[0].getOffset(), span[1].getOffset() - span[0].getOffset()); + doc.insertString(span[0].getOffset(), proposal, null); + } catch (BadLocationException e) { + ErrorManager.getDefault().notify(e); } }); } catch (BadLocationException e) { ErrorManager.getDefault().notify(e); } - - return null; + + return null; } + @Override public CharSequence getSortText() { return sortText; } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/options/CheckBoxRenderrer.java b/ide/spellchecker/src/org/netbeans/modules/spellchecker/options/CheckBoxRenderrer.java index 02f7706a8c34..0a965b68b148 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/options/CheckBoxRenderrer.java +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/options/CheckBoxRenderrer.java @@ -32,52 +32,44 @@ import javax.swing.border.Border; import javax.swing.border.EmptyBorder; +public final class CheckBoxRenderrer extends JCheckBox implements ListCellRenderer, Serializable { -public class CheckBoxRenderrer extends JCheckBox implements ListCellRenderer, Serializable { + private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); - private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder (1, 1, 1, 1); - private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder (1, 1, 1, 1); + protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER; - protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER; - - public CheckBoxRenderrer () { - super (); - setOpaque (true); - setBorder (getNoFocusBorder ()); - setName ("List.cellRenderer"); + public CheckBoxRenderrer() { + super(); + setOpaque(true); + setBorder(getNoFocusBorder()); + setName("List.cellRenderer"); } - private Border getNoFocusBorder () { + private Border getNoFocusBorder() { Border border = UIManager.getBorder("List.cellNoFocusBorder"); - if (System.getSecurityManager () != null) { - if (border != null) { - return border; - } - return SAFE_NO_FOCUS_BORDER; - } else { - if (border != null && - (noFocusBorder == null || - noFocusBorder == DEFAULT_NO_FOCUS_BORDER)) { - return border; - } - return noFocusBorder; + if (border != null + && (noFocusBorder == null + || noFocusBorder == DEFAULT_NO_FOCUS_BORDER)) { + return border; } + return noFocusBorder; } - public Component getListCellRendererComponent ( - JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus + @Override + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus ) { - setComponentOrientation (list.getComponentOrientation ()); + setComponentOrientation(list.getComponentOrientation()); Color bg = null; Color fg = null; - JList.DropLocation dropLocation = list.getDropLocation (); - if (dropLocation != null && !dropLocation.isInsert () && dropLocation.getIndex () == index) { + JList.DropLocation dropLocation = list.getDropLocation(); + if (dropLocation != null && !dropLocation.isInsert() && dropLocation.getIndex() == index) { bg = UIManager.getColor("List.dropCellBackground"); fg = UIManager.getColor("List.dropCellForeground"); @@ -86,19 +78,19 @@ public Component getListCellRendererComponent ( } if (isSelected) { - setBackground (bg == null ? list.getSelectionBackground () : bg); - setForeground (fg == null ? list.getSelectionForeground () : fg); + setBackground(bg == null ? list.getSelectionBackground() : bg); + setForeground(fg == null ? list.getSelectionForeground() : fg); } else { - setBackground (list.getBackground ()); - setForeground (list.getForeground ()); + setBackground(list.getBackground()); + setForeground(list.getForeground()); } String name = (String) value; - setText (name.substring (1)); - setSelected (name.charAt (0) == '+'); + setText(name.substring(1)); + setSelected(name.charAt(0) == '+'); - setEnabled (list.isEnabled ()); - setFont (list.getFont ()); + setEnabled(list.isEnabled()); + setFont(list.getFont()); Border border = null; if (cellHasFocus) { @@ -109,10 +101,10 @@ public Component getListCellRendererComponent ( border = UIManager.getBorder("List.focusCellHighlightBorder"); } } else { - border = getNoFocusBorder (); + border = getNoFocusBorder(); } if (border != null) { //#189786: rarely, the border is null - reasons are unknown - setBorder (border); + setBorder(border); } else { Logger.getLogger(CheckBoxRenderrer.class.getName()).log(Level.INFO, "Cannot set any border"); } @@ -121,83 +113,81 @@ public Component getListCellRendererComponent ( } @Override - public boolean isOpaque () { - Color back = getBackground (); - Component p = getParent (); + public boolean isOpaque() { + Color back = getBackground(); + Component p = getParent(); if (p != null) { - p = p.getParent (); + p = p.getParent(); } // p should now be the JList. - boolean colorMatch = (back != null) && (p != null) && - back.equals (p.getBackground ()) && - p.isOpaque (); - return !colorMatch && super.isOpaque (); + boolean colorMatch = (back != null) && (p != null) + && back.equals(p.getBackground()) + && p.isOpaque(); + return !colorMatch && super.isOpaque(); } @Override - public void validate () { + public void validate() { } @Override - public void invalidate () { + public void invalidate() { } @Override - public void repaint () { + public void repaint() { } @Override - public void revalidate () { + public void revalidate() { } @Override - public void repaint (long tm, int x, int y, int width, int height) { + public void repaint(long tm, int x, int y, int width, int height) { } @Override - public void repaint (Rectangle r) { + public void repaint(Rectangle r) { } @Override - protected void firePropertyChange (String propertyName, Object oldValue, Object newValue) { - // Strings get interned... - if (propertyName == "text" || ((propertyName == "font" || propertyName == "foreground") && - oldValue != newValue && - getClientProperty (javax.swing.plaf.basic.BasicHTML.propertyKey) != null) - ) { - super.firePropertyChange (propertyName, oldValue, newValue); + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + if ("text".equals(propertyName) || (("font".equals(propertyName) || "foreground".equals(propertyName)) + && oldValue != newValue + && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) { + super.firePropertyChange(propertyName, oldValue, newValue); } } @Override - public void firePropertyChange (String propertyName, byte oldValue, byte newValue) { + public void firePropertyChange(String propertyName, byte oldValue, byte newValue) { } @Override - public void firePropertyChange (String propertyName, char oldValue, char newValue) { + public void firePropertyChange(String propertyName, char oldValue, char newValue) { } @Override - public void firePropertyChange (String propertyName, short oldValue, short newValue) { + public void firePropertyChange(String propertyName, short oldValue, short newValue) { } @Override - public void firePropertyChange (String propertyName, int oldValue, int newValue) { + public void firePropertyChange(String propertyName, int oldValue, int newValue) { } @Override - public void firePropertyChange (String propertyName, long oldValue, long newValue) { + public void firePropertyChange(String propertyName, long oldValue, long newValue) { } @Override - public void firePropertyChange (String propertyName, float oldValue, float newValue) { + public void firePropertyChange(String propertyName, float oldValue, float newValue) { } @Override - public void firePropertyChange (String propertyName, double oldValue, double newValue) { + public void firePropertyChange(String propertyName, double oldValue, double newValue) { } @Override - public void firePropertyChange (String propertyName, boolean oldValue, boolean newValue) { + public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { } } diff --git a/ide/spellchecker/src/org/netbeans/modules/spellchecker/options/DictionaryInstallerPanel.form b/ide/spellchecker/src/org/netbeans/modules/spellchecker/options/DictionaryInstallerPanel.form index 20701ebe269b..bc525eaaaad4 100644 --- a/ide/spellchecker/src/org/netbeans/modules/spellchecker/options/DictionaryInstallerPanel.form +++ b/ide/spellchecker/src/org/netbeans/modules/spellchecker/options/DictionaryInstallerPanel.form @@ -1,4 +1,4 @@ - +