I want to use JLine to build a simple CLI. But I ran into a problem. File name completer doesn't work properly on Windows.
When I enter 8> first C:\ and press tab, completer do nothing although it should display all subfolders.
Here is my code:
ArgumentCompleter completer1 = new ArgumentCompleter(
new StringsCompleter("first"),
new FileNameCompleter(),
new NullCompleter()
);
ArgumentCompleter completer2 = new ArgumentCompleter(
new StringsCompleter("second"),
new NullCompleter()
);
AggregateCompleter completer3 = new AggregateCompleter(
completer1, completer2
);
ConsoleReader console = new ConsoleReader();
console.addCompleter(completer3);
while (true) {
String line = console.readLine("8> ");
if (line.isEmpty()){
console.println();
}
}
Any ideas how to fix this?
Related
I'm new to Java so apologies in advance.
I need to scan through a .txt file where each line is a set of names, and if a name is present anywhere in another .txt file it should then output the line from the first file into a third .txt file.
As far as I am aware my current solution will only scan through the first line and then stop, because once scanB has reached the end of the file it cannot return to the beginning? So I probably need to use a completely different approach to achieve the result I'm looking for. The code I've got so far is below but I am aware it is most likely waaay off for what I need to be doing.
Sorry again if there's any really really stupid mistakes in this, as I said I'm very new to this.
`File A = new File("A.txt");
Scanner scanA = new Scanner(A);
String personA = "";
File B = new File("B.txt");
Scanner scanB = new Scanner(B);
String personCheck = "";
while(scanA.hasNextLine()){
personA = scanA.nextLine();
while(scanB.hasNextLine()){
personB = scaninteractionevents.nextLine();
if(personCheck.contains(personB)){
FileWriter f = new FileWriter("PersonList.txt", true);
BufferedWriter b = new BufferedWriter(f);
PrintWriter writer = new PrintWriter(b);
writer.print(personCheck);
}
}
}`
Thank you for asking your question. Being new is not a problem. Your question is clear and well provided with a reproducable example.
If you want to rescan a file multiple times, you need to reprovide the file to the scanner every time. The best way to do this, is to make a new scanner every iteration.
File A = new File("A.txt");
Scanner scanA = new Scanner(A);
String personA = "";
File B = new File("B.txt");
String personCheck = "";
while(scanA.hasNextLine()){
personA = scanA.nextLine();
Scanner scanB = new Scanner(B);
while(scanB.hasNextLine()){
personB = scaninteractionevents.nextLine();
if(personCheck.contains(personB)){
FileWriter f = new FileWriter("PersonList.txt", true);
BufferedWriter b = new BufferedWriter(f);
PrintWriter writer = new PrintWriter(b);
writer.print(personCheck);
}
}
scanB.close();
}
scanA.close();
f.close();
b.close();
As you can see, I also added some close() calls, as it is good practice to close readers and writers to make sure your memory does not get flooded.
Edit: as was said in the answers, it might be better not to reread the file every time you run the code. You could indeed store it in a string, depending on the file size. This requires slightly more programming insights and is only necessary if you are working on efficient programming rather than starting to learn a new coding language. This is my opinion, others may disagree. ;)
So far I have
Terminal terminal = new DefaultTerminalFactory().createTerminal();
TerminalScreen screen = new TerminalScreen(terminal);
MultiWindowTextGUI mwtg = new MultiWindowTextGUI(screen);
CheckBoxList checkBoxList = new CheckBoxList<String>();
checkBoxList.addItem("Check one");
checkBoxList.addItem("Check two");
What I can't figure out is how to add checkBoxList directly to mwtg
Many thanks for your help
ok, so after muddling blindly through the API for hours guessing here and there, I did this, which works but is probably clunky or smells, so please feel free to improve on my own answer.
private MultiWindowTextGUI mwtg;
private BasicWindow bw;
private CheckBoxList<String> checkBoxList;
private List<String> ckeckedItems;
Terminal terminal = new DefaultTerminalFactory().createTerminal();
TerminalScreen screen = new TerminalScreen(terminal);
MultiWindowTextGUI mwtg = new MultiWindowTextGUI(screen);
this.checkBoxList = new CheckBoxList<String>();
this.checkBoxList.addItem("item1");
this.checkBoxList.addItem("item2");
this.checkBoxList.addItem("item3");
this.checkBoxList.addListener((sel, prev) ->
{ this.ckeckedItems = this.checkBoxList.getCheckedItems(); }
);
Panel panel = new Panel();
panel.setLayoutManager(new GridLayout(4));
panel.addComponent(this.checkBoxList);
Button button = new Button("Done", () -> this.bw.close());
button.addTo(panel);
this.bw = new BasicWindow("Choices");
this.bw.setComponent(panel);
this.mwtg.addWindowAndWait(this.bw);
I hope this may be useful for someone...
I'm using rundll32 url.dll,FileProtocolHandler my_file.dotx to open files under Windows.
It works fine with .docx documents, but when I try it with .dotx documents (template documents), it creates a new .docx based on the template.
Just as the normal behavior in the windows explorer : when you double-click on a .dotx template file, it creates a new .docx file based on it. If you want to open the real .dotx file, you have to right-click on it and select "open" instead of "new".
Question is: how to do the same with rundll32? Is there an option in the command to force the opening of the underlying template instead of creating a new document?
Edit: I need a way to do it without C functions, just plain text, in the command line (I'm using Java to do it).
Maybe you can wrap a simple C program around ShellExecute, passing the verb OPEN.
ShellExecute(NULL, TEXT("open"),
TEXT("rundll32.exe"), TEXT("url.dll,FileProtocolHandler pathToGadget"),
NULL, SW_SHOWNORMAL);
I found this example here.
edit:
Since you're doing this in Java - you could try a JNI wrapping of the ShellExceute function like this (from the example I found on The Wannabe Java Rockstar and butchered)
public static boolean execute(String file, String parameters) {
Function shellExecute =
Shell32.getInstance().getFunction(SHELL_EXECUTE.toString());
Int32 ret = new Int32();
shellExecute.invoke(ret, // return value
new Parameter[] {
new Handle(), // hWnd
new Str("open"), // lpOperation
new Str(file), // lpFile
new Str(parameters), // lpParameters
new Str(), // lpDirectory
new Int32(1) // nShowCmd
});
if(ret.getValue() <= 32) {
System.err.println("could not execute ShellExecute: " +
file + ". Return: " + ret.getValue());
}
return (ret.getValue() > 32);
}
public static void main(String[] args) {
ShellExecute.execute("rundll32.exe","url.dll,FileProtocolHandler pathToGadget" );
}
I am trying to use Java cli commanlineparser to parse the follwing arguments,
java -OC:\mydirectory -NMyfile
Option -O is for directory and -N is for the name of file.
I have been looking online but couldnt find a good example and this is what I am trying to do,
Option option = new Option()
option.addOpton("O",true, "output directory)
option.addOpton("N",true, "file name)
...
CommandLineParser parser = new BasicParser();
...
if (cmd.hasOption("O")
...
Basically, I am trying to add multiple options and be able to parse them. Is this correct way to run the program with above options?
Thanks.
Try the following:
...
Option opt1 = OptionBuilder.hasArgs(1).withArgName("output directory")
.withDescription("This is the output directory").isRequired(true)
.withLongOpt("output").create("O");
Option opt2 = OptionBuilder.hasArgs(1).withArgName("file name")
.withDescription("This is the file name").isRequired(true)
.withLongOpt("name").create("N")
Options o = new Options();
o.addOption(opt1);
o.addOption(opt2);
CommandLineParser parser = new BasicParser();
try {
CommandLine line = parser.parse(o, args); // args are the arguments passed to the the application via the main method
if (line.hasOption("output") {
//do something
} else if(line.hasOption("name") {
// do something else
}
} catch(Exception e) {
e.printStackTrace();
}
...
Also, you should leave a blank space between the argument and the value in the command line.
I've been making a program that uses a JFileChooser. I've set the application up with
UIManager.getSystemLookAndFeelClassName()
Which works just fine for pretty much everything under Ubuntu. The only problem I've run into so far is that the JFileChooser comes out looking pretty awful:
Is there a way to make this look like the default file chooser in Ubuntu? ie.
I've tried using
UIManager.getCrossPlatformLookAndFeelClassName()
Which makes the JFileChooser dialog look better, but still not native looking, and it ruins the rest off the application's feel too.
Thanks.
If I recall correctly, the stock JDK used gtk1, but ubuntu uses gtk2 currently. I forget where but i've come across gtk2 for java somewhere. Google? Probably not what you were hoping for, sorry.
You might see if FileDialog is any more appealing; here's an example.
The Nimbus look and feel has a decent file chooser. Although this will affect your entire application, you might like the look.
Also you can build your own file chooser if needed.
You can also use SWT instead of swing.
Does Swing support Windows 7-style file choosers?
The following code is from above link
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
public class SWTFileOpenSnippet {
public static void main (String [] args) {
Display display = new Display ();
Shell shell = new Shell (display);
// Don't show the shell.
//shell.open ();
FileDialog dialog = new FileDialog (shell, SWT.OPEN | SWT.MULTI);
String [] filterNames = new String [] {"All Files (*)"};
String [] filterExtensions = new String [] {"*"};
String filterPath = "c:\\";
dialog.setFilterNames (filterNames);
dialog.setFilterExtensions (filterExtensions);
dialog.setFilterPath (filterPath);
dialog.open();
System.out.println ("Selected files: ");
String[] selectedFileNames = dialog.getFileNames();
for(String fileName : selectedFileNames) {
System.out.println(" " + fileName);
}
shell.close();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}