I try to write a simple Shell with autocompletion. I use JLine library. Here is my code.
public class ConsoleDemo {
public static void main(String[] args) {
try {
ConsoleReader console = new ConsoleReader();
console.setPrompt(">>> ");
console.addCompleter(new MyStringsCompleter("a", "aaa", "b", "bbb"));
String line;
while ((line = console.readLine()) != null) {
console.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
The problem is that my app doesn't complete nothing when I press tab.
>>> a [press tab]
How can I use it right to get autocompletion my input?
UPD
public class MyStringsCompleter implements Completer {
private final SortedSet<String> strings = new TreeSet<>();
public MyStringsCompleter(Collection<String> strings) {
this.strings.addAll(strings);
}
public MyStringsCompleter(String... strings) {
this(asList(strings));
}
#Override
public int complete(String buffer, int cursor, List<CharSequence> candidates) {
if (buffer == null) {
candidates.addAll(strings);
} else {
for (String match : strings.tailSet(buffer)) {
if (!match.startsWith(buffer)) {
break;
}
candidates.add(match);
}
}
if (candidates.size() == 1) {
candidates.set(0, candidates.get(0) + " ");
}
return candidates.isEmpty() ? -1 : 0;
}
}
The problem is in my IDE. When I start my application not through IDE, than all works fine. So the problem is in IDE which somehow intercepts console input.
Simply adding strings in StringsCompleter will not accomplish what you want. You must make use of the complete method from StringsCompleter. An example can be found here .
Related
I'm working on a small project in which I need to remove some lines of commented code in java. There are two cases in which I should remove these lines: (i) when the line of code begins with //# and; (ii) when the line of code begins with //#.
However, the method I've developed for this case is not working on either type of removal:
private static void dropLines(String[] args, String f) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(f), Charset.forName("UTF-8"));
PrintWriter pw = new PrintWriter(new FileWriter(f));
boolean empty = false;
for (String string : lines) {
if (!string.trim().startsWith("//#")) {
if (string.trim().equals("") && !empty) {
pw.println(string);
empty = true;
} else if (!string.trim().equals("")) {
pw.println(string);
empty = false;
}
}
else if (!string.trim().startsWith("//#")) {
if (string.trim().equals("") && !empty) {
pw.println(string);
empty = true;
} else if (!string.trim().equals("")) {
pw.println(string);
empty = false;
}
}
}
pw.flush();
pw.close();
}
An example of an input file could be as follows:
public class Main {
//#ifdef calendar
//# public static void googleCalendar() {
//# System.out.println("Google Calendar");
//# }
//#endif
//#ifdef category
public static void addCategory() {
System.out.println("Add Category");
}
//#endif
public static void main(String[] args) {
//#ifdef base
//# System.out.println("Base");
//#endif
//#ifdef category
addCategory();
// #endif
//#ifdef calendar
//# googleCalendar();
//#endif
}
}
Important: although the input file has notations similar to preprocessing, this does not have any importance for this phase of removing the lines, because in theory, the preprocessing part is already done in previous methods with the use of Antenna. I need only create a method that deletes the rows after processing.
It looks like you'll want to change your surrounding if/else if statement to be a single if statement:
private static void dropLines(String[] args, String f) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(f), Charset.forName("UTF-8"));
PrintWriter pw = new PrintWriter(new FileWriter(f));
boolean empty = false;
for (String string : lines) {
if (!string.trim().startsWith("//#") && !string.trim().startsWith("//#")) {
if (string.trim().equals("") && !empty) {
pw.println(string);
empty = true;
} else if (!string.trim().equals("")) {
pw.println(string);
empty = false;
}
}
}
pw.flush();
pw.close();
}
With the way you have it right now, it's set up to always reprint the line, because if your line begins with "//#" then !string.trim().startsWith("//#") is true, and if it begins with "//#" then !string.trim().startsWith("//#") is true.
I use LanguageTool for some spellchecking and spell correction functionality in my application.
The LanguageTool documentation describes how to exclude words from spell checking (with call the addIgnoreTokens(...) method of the spell checking rule you're using).
How do you add some words (e.g., from a specific dictionary) to spell checking? That is, can LanguageTool fix words with misspellings and suggest words from my specific dictionary?
Unfortunately, the API doesn't support this I think. Without the API, you can add words to spelling.txt to get them accepted and used as suggestions. With the API, you might need to extend MorfologikSpellerRule and change this place of the code. (Disclosure: I'm the maintainer of LanguageTool)
I have similar requirement, which is load some custom words into dictionary as "suggest words", not just "ignored words". And finally I extend MorfologikSpellerRule to do this:
Create class MorfologikSpellerRuleEx extends from MorfologikSpellerRule, override the method "match()", and write my own "initSpeller()" for creating spellers.
And then for the language tool, create this custom speller rule to replace existing one.
Code:
Language lang = new AmericanEnglish();
JLanguageTool langTool = new JLanguageTool(lang);
langTool.disableRule("MORFOLOGIK_RULE_EN_US");
try {
MorfologikSpellerRuleEx spellingRule = new MorfologikSpellerRuleEx(JLanguageTool.getMessageBundle(), lang);
spellingRule.setSpellingFilePath(spellingFilePath);
//spellingFilePath is the file has my own words + words from /hunspell/spelling_en-US.txt
langTool.addRule(spellingRule);
} catch (IOException e) {
e.printStackTrace();
}
The code of my custom MorfologikSpellerRuleEx:
public class MorfologikSpellerRuleEx extends MorfologikSpellerRule {
private String spellingFilePath = null;
private boolean ignoreTaggedWords = false;
public MorfologikSpellerRuleEx(ResourceBundle messages, Language language) throws IOException {
super(messages, language);
}
#Override
public String getFileName() {
return "/en/hunspell/en_US.dict";
}
#Override
public String getId() {
return "MORFOLOGIK_SPELLING_RULE_EX";
}
#Override
public void setIgnoreTaggedWords() {
ignoreTaggedWords = true;
}
public String getSpellingFilePath() {
return spellingFilePath;
}
public void setSpellingFilePath(String spellingFilePath) {
this.spellingFilePath = spellingFilePath;
}
private void initSpellerEx(String binaryDict) throws IOException {
String plainTextDict = null;
if (JLanguageTool.getDataBroker().resourceExists(getSpellingFileName())) {
plainTextDict = getSpellingFileName();
}
if (plainTextDict != null) {
BufferedReader br = null;
if (this.spellingFilePath != null) {
try {
br = new BufferedReader(new FileReader(this.spellingFilePath));
}
catch (Exception e) {
br = null;
}
}
if (br != null) {
speller1 = new MorfologikMultiSpeller(binaryDict, br, plainTextDict, 1);
speller2 = new MorfologikMultiSpeller(binaryDict, br, plainTextDict, 2);
speller3 = new MorfologikMultiSpeller(binaryDict, br, plainTextDict, 3);
br.close();
}
else {
speller1 = new MorfologikMultiSpeller(binaryDict, plainTextDict, 1);
speller2 = new MorfologikMultiSpeller(binaryDict, plainTextDict, 2);
speller3 = new MorfologikMultiSpeller(binaryDict, plainTextDict, 3);
}
setConvertsCase(speller1.convertsCase());
} else {
throw new RuntimeException("Could not find ignore spell file in path: " + getSpellingFileName());
}
}
private boolean canBeIgnored(AnalyzedTokenReadings[] tokens, int idx, AnalyzedTokenReadings token)
throws IOException {
return token.isSentenceStart() || token.isImmunized() || token.isIgnoredBySpeller() || isUrl(token.getToken())
|| isEMail(token.getToken()) || (ignoreTaggedWords && token.isTagged()) || ignoreToken(tokens, idx);
}
#Override
public RuleMatch[] match(AnalyzedSentence sentence) throws IOException {
List<RuleMatch> ruleMatches = new ArrayList<>();
AnalyzedTokenReadings[] tokens = getSentenceWithImmunization(sentence).getTokensWithoutWhitespace();
// lazy init
if (speller1 == null) {
String binaryDict = null;
if (JLanguageTool.getDataBroker().resourceExists(getFileName())) {
binaryDict = getFileName();
}
if (binaryDict != null) {
initSpellerEx(binaryDict); //here's the change
} else {
// should not happen, as we only configure this rule (or rather its subclasses)
// when we have the resources:
return toRuleMatchArray(ruleMatches);
}
}
int idx = -1;
for (AnalyzedTokenReadings token : tokens) {
idx++;
if (canBeIgnored(tokens, idx, token)) {
continue;
}
// if we use token.getToken() we'll get ignored characters inside and speller
// will choke
String word = token.getAnalyzedToken(0).getToken();
if (tokenizingPattern() == null) {
ruleMatches.addAll(getRuleMatches(word, token.getStartPos(), sentence));
} else {
int index = 0;
Matcher m = tokenizingPattern().matcher(word);
while (m.find()) {
String match = word.subSequence(index, m.start()).toString();
ruleMatches.addAll(getRuleMatches(match, token.getStartPos() + index, sentence));
index = m.end();
}
if (index == 0) { // tokenizing char not found
ruleMatches.addAll(getRuleMatches(word, token.getStartPos(), sentence));
} else {
ruleMatches.addAll(getRuleMatches(word.subSequence(index, word.length()).toString(),
token.getStartPos() + index, sentence));
}
}
}
return toRuleMatchArray(ruleMatches);
}
}
So i have a .dat file that is a list. Each line starts with a letter as a command for my alarm clock program and some are followed by numbers in time format (XX:XX). I need to scan the letter arr[0] so the program knows which method to implement and then separate the integers from the colon to have arr[1] and arr[2]. I can't seem to figure out how to do both.
Example :T 25:00
while (scan.hasNextLine()){
String[] data = scan.nextLine().split(" ");
if (data[0] == "D"){
myClock.getTime();
}
else if (data[0] == "A"){
myClock.getAlarmTime();
}
else if (data[0] == "T"){
myClock.setTime(data[1], data[2]);
}
else if (data[0] == "S"){
myClock.setAlarmTime(data[1], data[2]);
}
else if (data[0] == "O"){
myClock.setAlarmOn(true);
}
else if (data[0] == "F"){
myClock.setAlarmOn(false);
}
else{
myClock.quit();
tells me I have incompatible types and that .String cannot be converted to int. So how do I convert or scan the two separately?
Instead of
String str[] = scan.nextLine().split(" ");
place
String str[] = scan.nextLine().split(" |:");
...............
if (str[0].equals("T"))
myClock.setTime(Integer.parseInt(str[1], Integer.parseInt(str[2]);
One more issue is if (data[0] == "T" ) means compaing strings
In java, we should use equals() for checking strings equality whether both are same or not.
Instead of
if (data[0] == "T" )
use
if (data[0].equals( "T" ))
If your error is at this line myClock.setAlarmTime(data[1], data[2]);, try to convert it to int.
Mby your functions for setAlarmTime and setTime need ints and you are passing Strings, compiler normally advise this.
Try this:
myClock.setAlarmTime(Integer.valueOf(data[1]), Integer.valueOf(data[2]));
Also, you want to separate this T 25:00to this: { "T","25", "00" }
And with this line String[] data = scan.nextLine().split(" "); you will get: { "T","25:00" }
You need to split again your data[1] before do setAlarmTime and setTime with:
String[] timeSplit = data[1].split(":");
myClock.setAlarmTime(Integer.valueOf(timeSplit[0]), Integer.valueOf(timeSplit[1]));
loosely based on #Boris the Spider comment
public class EnumCommand {
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("csv.dat"));
String s;
while ((s = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(s);
MyCommand.valueOf(st.nextToken()).execute(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private enum MyCommand {
D {
#Override
public void execute(String predicate) {
//getTime
}
},
A {
#Override
public void execute(String predicate) {
//getAlarm Time
}
},
T {
#Override
public void execute(String predicate) {
//setTime .. Parse here for time
System.out.println(predicate);
}
},
S {
#Override
public void execute(String predicate) {
//set alarm Time Parse here for time
System.out.println(predicate);
}
},
O {
#Override
public void execute(String predicate) {
//On alarm
}
},
F {
#Override
public void execute(String predicate) {
//Off alarm
}
};
public abstract void execute(String predicate);
}
}
I'm working on rewriting my simple Contacts app from normal JAVA FX to FXML.THe problem is in Lambda expressions. I have interface like:
interface ObjectCreator {
void create(String[] array);
}
And the problem is when i use this CSVFileReader:
public static class CSVFileReader {
String fileName;
CSVFileReader(String fileName) {
this.fileName = fileName;
}
void read(ObjectCreator creator) {
try {
BufferedReader csv = new BufferedReader(new FileReader(fileName));
String row = csv.readLine();
while (row != null) {
creator.create(row.split(","));
row = csv.readLine();
}
csv.close();
} catch (IOException e) {
}
}
}
In this code i use lambda expression to read Contacts from file:
#FXML
public void openFile() {
FileChooser fileChooser = new FileChooser();
File fileE = fileChooser.showOpenDialog(scene.getWindow());
if (fileE != null) {
CSVFileReader reader = new CSVFileReader(fileE.getName());
data.clear();
reader.read(v ->
data.add(new Contact(v[0], v[1], v[2], v[3])));
}
System.out.println("open list");
}
I use JDK 1.8.65 so preeety new one. Problem is that there is no error or exception just looks like code "v->data.add(new Contact(v[0], v[1], v[2], v[3]))" would not be invoked.
Question is am I doing something wrong or it just wont be working??
Ok no question, after futher studying my app i discovered i was taking
fileE.getName();
and i should take
fileE.getAbsolutePath();
So the app would look in proper location for a file.
I am making a class in java to parse in CSV's. It will read in the file line by line and parse out each field according to the regex pattern into an array, and then print that array. I put all this together in a main driver below. I looked over everything and it seems to be functional but for some reason whenever I run it, it just gets stuck in an infinite loop and will not cease. I have looked over this many times and can just not find where this would happen. Any help with this issue would be greatly appreciated!
import java.io.FileInputStream;
import java.io.IOException;
import java.util.regex.Pattern;
/**
*
*/
public class Csv {
private FileInputStream fin;
private String line;
private String[] parsedFields;
public boolean isEOL(char n) {
boolean eol;
if (n == '\n' || n == '\r') {
eol = true;
}
else
eol=false;
return eol;
}
public String getLine()
{
try
{
char c;
c= (char) fin.read();
while(!isEOL(c))
{
line+=c;
}
}
catch (IOException e) {
System.out.println("Input Error.");
}
return line;
}
public void parseFields(String s)
{
Pattern CSVLine=Pattern.compile("\"([^\"]*)\"|(?<=,|^)([^,]*)(?:,|$)");
parsedFields=CSVLine.split(s);
}
public void execute()
{
String field=getLine();
parseFields(field);
}
public void setFin(FileInputStream usrFin)
{
fin=usrFin;
}
public void outputFields()
{
for(int i=0; i<parsedFields.length;i++)
{
System.out.println(parsedFields[i]);
}
}
public static void main(String args[])
{
try {
FileInputStream fis;
fis = new FileInputStream("test.txt");
Csv test= new Csv();
test.setFin(fis);
test.execute();
test.outputFields();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
c= (char) fin.read();
while(!isEOL(c))
{
line+=c;
}
In this part, you loop, adding c, but you never read again. c never changes during the loop, and probably is stuck there. You need to have the c = fin.read(); inside the loop too.
public static List<String> readLine(String filePath){
List<String> listStr = new ArrayList<String>();
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
String line = null;
Pattern pat = Pattern.compile(LINE_PATTERN_REGEXP);
while((line=br.readLine())!=null){
Matcher matcher = pat.matcher(line);
if(!matcher.find()){
listStr.add(line);
}
}
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return listStr;
}
}