Ive implemented the jFileChooser in my command line program and it works, just as it should with only one annoying issue. It seems that it opens underneath every window with no alert of any kind. In fact I even missed it a couple of times at first leading me to believe that i had implemented it wrong.
I have implemented this as follows:
System.out.println("Please select the file");
JFileChooser fc = new JFileChooser();
int retValue = fc.showOpenDialog(new JPanel());
if(retValue == JFileChooser.APPROVE_OPTION){
g.inputFile = fc.getSelectedFile();
}else {
System.out.println("Next time select a file.");
System.exit(1);
}
Essentially I only want the jFileChooser in order to have the user select a file as an input file. This is the only component that has a need for a GUI implementation, so if i can avoid writing up an GUI, that would be helpful.
So after trying a variety of things from different stack overflow topics I ended up with a result that consistently and reliably opens above every window on Windows 7.
public class ChooseFile {
private JFrame frame;
public ChooseFile() {
frame = new JFrame();
frame.setVisible(true);
BringToFront();
}
public File getFile() {
JFileChooser fc = new JFileChooser();
if(JFileChooser.APPROVE_OPTION == fc.showOpenDialog(null)){
frame.setVisible(false);
return fc.getSelectedFile();
}else {
System.out.println("Next time select a file.");
System.exit(1);
}
return null;
}
private void BringToFront() {
frame.setExtendedState(JFrame.ICONIFIED);
frame.setExtendedState(JFrame.NORMAL);
}
}
As it stands in my program it is an inner class and is invoked by calling:
System.out.println("Please select the file");
g.inputFile = g.new ChooseFile().getFile();
I think of two possible causes for something like this:
You're trying to mix AWT and Swing GUI's in the same program, or
You're trying to mix a console program (i.e., using System.out.println(...) and getting input via a Scanner object) with a Swing GUI.
If you are doing either of these two things, then you should simplify and make it only a Swing GUI type program. If this information doesn't help, then you may wish to give us more information about your problem.
Edit 1
I just noticed the details of your code. The new JPanel() part below is a problem:
int retValue = fc.showOpenDialog(new JPanel());
To make the JFileChooser act as a dialog to your top level window (which it is currently not doing and which is your chief problem), you should instead pass a component that is in the parent top level window, such as a JPanel or JButton that is held inside of your JFrame or JApplet.
Edit 2
OK, you're trying to mix a Java console program with a Swing GUI program which is like eating ice cream with pickles -- they just don't go well together. There is no top-level window to offer to the JFileChooser's showOpenDialog method so that it will act as a true dialog.
The best solution is to not do this, to instead re-write your application to be a complete Swing GUI.
In my code, I can just use null and it works. I'm using Java 7 on Windows 7.
JFileChooser chooser = new JFileChooser(System.getProperty("java.class.path"));
FileNameExtensionFilter filter = new FileNameExtensionFilter("CSV files", "csv");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION) {
try {
Scanner inputFile= new Scanner(new File(chooser.getSelectedFile().getAbsolutePath()));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Related
I have a basic text based Java app. I want the user to be able to enter sensitive info (password) in a text editing session that only exists for that purpose.
A bit like with git you get a temporary session/file in vi (or another set editor) to edit comment and save/quit - then the git process resumes and consumes that file. The file is (probably) deleted or at least forgotten about.
Do not need any advanced editor capabilities, just basic typing, backspace etc.
I want the user to be able to see what they're typing BUT once they have typed a password, it must be erased from screen. So plain STDIN won't work as the input remains on the screen.
How can I do it in Java or for that matter in another language?
I have looked at Scanner (basically STDIN) and Console.readPassword (user cannot see what they type).
Perhaps a solution that involves STDIN and immediate erasure of the typed line could be acceptable. But emulating git/vi interplay is more attractive because it's arguably a bit more standard.
EDIT: I have implemented something close - create temp file and run notepad.exe on that, let user save and close notepad, read from temp file, delete it. Simple but it relies on an external tool, needs to be adjusted to run on linux as well.. I would like something more seamless where the behaviour is emulated within the java app itself
Swing is pretty consistently available, here is an example of a method that opens a window, waits until the window is closed, and returns the text.
import javax.swing.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.awt.EventQueue;
import java.awt.event.*;
public class EditMe{
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>(1);
public void showEditor(){
JFrame frame = new JFrame("edit text");
JEditorPane pane = new JEditorPane("txt", "");
frame.add(pane);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener( new WindowAdapter(){
#Override
public void windowClosed(WindowEvent evt){
try{
queue.put(pane.getText());
} catch(InterruptedException e){
//not really possible, but just incase.
throw new RuntimeException(e);
}
}
} );
frame.setSize( 640, 480 );
frame.setVisible(true);
}
public static String getText() throws InterruptedException{
EditMe me = new EditMe();
EventQueue.invokeLater( ()-> me.showEditor() );
return me.queue.take();
}
public static void main(String[] args) throws Exception{
System.out.println("waiting for response");
String s = getText();
System.out.println("response received: \n" + s);
}
}
This would be about equivalent to a notepad solution, but it uses swing that comes with standard jdk's. (There are headless jdk's that don't include swing.)
Background
So I've been trying to improve my code style and write a bit more functionally. I write software daily not as a requirement for my job (web design), but to expedite my responsibilities and automate them and save time (this approach has proven invaluable and made me somewhat of a superstar).
Issue
In one of my recent projects, I have tried to use a JFileChooser in the following way:
List<String> lines;
do {
lines = new ArrayList<>();
try {
lines = jFC.showOpenDialog(new JFrame() {
{
// originally setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}) == JFileChooser.APPROVE_OPTION
? Files.readAllLines(jFC.getSelectedFile().toPath())
: null;
} catch (Exception e) {
e.printStackTrace();
System.err.println("Error selecting File.");
}
System.out.println("Here we go");
} while (lines == null || lines.isEmpty());
However neither my original implementation nor my revised one actually work, which I tested using print statements (The reimplemented version was never called.) I then tried to do the following:
JFrame test = new JFrame();
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
lines = jFC.showOpenDialog(test) == JFileChooser.APPROVE_OPTION
? Files.readAllLines(jFC.getSelectedFile().toPath())
: null;
Which produced the same result. I've searched for duplicates but could not find something that reproduced my exact situation. Essentially, I want my program to completely terminate anytime a JFileChooser is canceled but I am reluctant to change my ternary statements as it does not fix my intended behavior but instead proposes a work around. My intuition tells me its a scope problem but for windowClosing not to be called raises a few questions for me.
tl;dr
System.exit(0) on JFrame for JFileChooser not working, not going to change flow control so don't bother asking.
Glad to be on this very helpful website. I have a problem with my Java program that will probably either be an easy fix, or impossible to fix.
You know how when you run a program that's open in NetBeans, it shows the output within the NetBeans application? I am trying to create a program that allows anybody who puts it on their computer to execute it, even if they have not installed an IDE like NetBeans or Eclipse. And when somebody executes my program, I want it to show the same thing as when I run it in NetBeans, with the same output and everything. The program doesn't use a GUI or anything like that. I managed to create an executable .jar file with the "Clean and build project" option, and I made a .bat file that successfully executes the program. This should achieve my goal of allowing anyone to run it. When I start up the .bat file, it works, and shows a white-text-black-background screen that runs the program exactly as it ran while in NetBeans.
The problem is that when I run the program (with the .bat file), the text is too small... I've tried looking everywhere for a solution to this, but I could only find discussion about how to make things work with GUIs, or other more complicated things than what my program needs. I am willing to work with GUI stuff if it is necessary, but I don't think it will help, due to what a GUI is. From my understanding, a GUI is not one big thing, but is a user interface composed of smaller parts (such as pop-up input prompts and scroll bars) that are each made by the programmer. I don't need any fancy scroll bars etc., I just need my program to execute like it does when ran in NetBeans (pretty sure this is called the console), and I need to change the text size of the program text when it executes.
I greatly appreciate any help, even if you aren't sure if it will work or not. If the answer requires a lengthy explanation and you don't feel like explaining, that's okay; just tell me what I'd have to learn to figure this out and I can research it if necessary.
I just created one. Try using this one and tell us if it helped or not.
EDIT Added a JTextField to read data. It is more advanced code than the previous one, since it uses concurrency. I tried to make it simple, these are the functions you can use:
MyConsole (): Constructor. Create and show the console
print (String s): Print the s String
println (String s) Print the s String and add a new line
read (): Makes you wait untill the user types and presses Enter
closeConsole (): Closes the console
Here is the code:
public class MyConsole implements ActionListener {
private JFrame frame;
private JTextArea myText;
private JTextField userText;
private String readText;
private Object sync;
/*
* Main and only constructor
*/
public MyConsole() {
// Synchronization object
sync = new Object();
// Create a window to display the console
frame = new JFrame("My Console");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setContentPane(createUI());
frame.setVisible(true);
}
/*
* Creates user interface
*/
private Container createUI() {
// Create a Panel to add all objects
JPanel panel = new JPanel (new BorderLayout());
// Create and set the console
myText = new JTextArea();
myText.setEditable(false);
myText.setAutoscrolls(true);
myText.setBackground(Color.LIGHT_GRAY);
// This will auto scroll the right bar when text is added
DefaultCaret caret = (DefaultCaret) myText.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
// Create the input for the user
userText = new JTextField();
userText.addActionListener(this);
panel.add(new JScrollPane(myText), BorderLayout.CENTER);
panel.add(userText, BorderLayout.SOUTH);
return panel;
}
/*
* Waits until a value is typed in the console and returns it
*/
public String read(){
print("==>");
synchronized (sync) {
try {
sync.wait();
} catch (InterruptedException e) {
return readText = "";
}
}
return readText;
}
/*
* Prints s
*/
public synchronized void print(String s){
// Add the "s" string to the console and
myText.append(s);
}
/*
* Prints s and a new line
*/
public synchronized void println(String s){
this.print(s + "\r\n");
}
/*
* Close the console
*/
public void closeConsole(){
frame.dispose();
}
#Override
public void actionPerformed(ActionEvent e) {
// Check if the input is empty
if ( !userText.getText().equals("") ){
readText = userText.getText();
println(" " + readText);
userText.setText("");
synchronized (sync) {
sync.notify();
}
}
}
}
Here is how to use it (an example). It just asks your age and writes something depending on your input:
public static void main(String[] args) {
MyConsole console = new MyConsole();
console.println("Hello! (Type \"0\" to exit)");
int age = 1;
do{
console.println("How old are you ?");
String read = console.read();
try {
age = Integer.valueOf(read);
if ( age >= 18){
console.println("Wow! " + age + " ? You are an adult already!");
}else if ( age > 0 ){
console.println("Oh! " + age + " ? You are such a young boy!");
}else if (age == 0){
console.println("Bye bye!");
}else{
console.println("You can't be " + age + " years old!");
}
}catch (Exception e) {
console.println("Did you write any number there ?");
}
} while ( age != 0 );
console.closeConsole();
}
And here is a image:
Question: Trying to get the same effect as the code below only with JTextArea so I want the JTextArea to be read and spelling suggestions to be recommended every time the user types a new misspelt word.
Below is the working example with 'System.in' which works well.
(Vars userField = JTextArea & dic.txt is a list of the english language for the system to use for suggestions)
CODE (1)
public SpellCheckExample() {
try {
SpellDictionary dictionary = new SpellDictionaryHashMap(new File(dic.txt));
spellCheck = new SpellChecker(dictionary);
spellCheck.addSpellCheckListener(this);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.print("Enter text to spell check: ");
String line = in.readLine();
if (line.length() <= 0)
break;
spellCheck.checkSpelling(new StringWordTokenizer(line));
}
} catch (Exception e) {
e.printStackTrace();
}
}
What I have Been trying:
CODE (2)
public void spellChecker() throws IOException{
String userName = System.getProperty("user.home");
SpellDictionary dictionary = new SpellDictionaryHashMap(new File(userName+"/NetBeansProjects/"+"/project/src/dic.txt"));
SpellChecker spellCheck = new SpellChecker(dictionary);
spellCheck.addSpellCheckListener(this);
try{
StringReader sr = new StringReader(userField.getText());
BufferedReader br = new BufferedReader(sr);
while(true){
String line = br.readLine();
if(line.length()<=0)
break;
spellCheck.checkSpelling(new StringWordTokenizer(line));
}
}catch(IOException e){
e.printStackTrace();
}
}
March 3rd 2016 (Update)
public void spellChecker() throws IOException{
// getting context from my dic.txt file for the suggestions etc.
SpellDictionary dictionary = new SpellDictionaryHashMap(new File("/Users/myname/NetBeansProjects/LifeSaver/src/dic.txt"));
SpellChecker spellCheck = new SpellChecker(dictionary);
// jt = JTextField already defined in constructors and attemtpting to pass this into system and
InputStream is = new ByteArrayInputStream(jt.getText().getBytes(Charset.forName("UTF-8")));
//spellCheck.checkSpelling(new StringWordTokenizer(line)); ""ORIGINAL"""
// reccomending cast to wordfinder
spellCheck.checkSpelling(new StringWordTokenizer(is);
}
You don't want to try to drop console UI code into an event-driven GUI, as it will never work like that. Instead you need to use GUI events to trigger your actions, not readln's.
The first thing you must decide on is which event you wish to use to trigger your spell check. For my money, I'd get the user's input in a JTextField, not a JTextArea since with the former, we can easily trap <enter> key presses by adding an ActionListener on the JTextField. You can always use both, and then once the text is spell checked, move it to the JTextArea, but this is exactly what I'd recommend:
use a JTextField,
add an ActionListener to the JTextField to be notified whenever the field has focus and enter is pressed,
within this listener, extract the text from the JTextField, by calling getText() on the field
Then run your spell check code on extracted text,
and output the result into a nearby JTextArea.
Take a look at Concurrency in Swing for reasons why your current approach won't work, then have a look at Listening for Changes on a Document and Implementing a Document Filter for some possible solutions
As someone is bound to mention it, DON'T use a KeyListener, it's not an appropriate solution for the problem
Put simpler, Swing is a single threaded, event driven framework. So anything you do which blocks the Event Dispatching Thread, will prevent it from processing new events, including paint events, making your UI unresponsive
As an event driven environment, you need to register interested in been notified when some event occurs (this is an example of Observer Pattern) and then take appropriate actions based on those events.
Remember though, you can not make changes to a Document via a DocumentListener, so be careful there
I'm writing a Java app that needs to run on a device with a very high screen resolution. The only UI component that I need to display is a JFileChooser.
Since the screen resolution so high, the FileChooser appears too small. Is there a simple command I can use to make it bigger? Ideally, I'd like to keep the proportions of the components the same, so that the icons grow just as much as the text.
Also, it's important that any changes modify only my application. A global approach to changing the size of the graphics, like using a lower resolution, or changing a system-wide font size, isn't an option for me.
Any ideas?
This class works fine, both resizing JFileChooser window and fonts.
public class JFileChooserArqs {
private Font font = new Font("monospaced",Font.BOLD,16);
private String fileName;
public JFileChooserArqs(String title)
{
fileName = null;
JFileChooser fc = new JFileChooser(".");
fc.setPreferredSize(new Dimension(800,600));
fc.setDialogTitle(title);
setFileChooserFont(fc.getComponents());
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
fileName = fc.getSelectedFile().getAbsolutePath();
}
}
private void setFileChooserFont(Component[] comp)
{
for(int x = 0; x < comp.length; x++)
{
if(comp[x] instanceof Container) setFileChooserFont(((Container)comp[x]).getComponents());
try{comp[x].setFont(font);}
catch(Exception e){}//do nothing
}
}
public String obtemNomeArquivo() {
return fileName;
}
}
I know the answer. Just use chooser.setPreferredSize(new Dimension(int width,int height)); method where chooser is your JFileChooser .
Example:
public class MyFrame extends JFrame(){
JFileChooser chooser = new JFileChooser();
chooser.setPreferredSize(new Dimension(800,600));
//Here show your dialog and do the rest
}
You need to choose suitable layouts to design the user interface. Have a look at CodeRanch thread.
I was going to suggest adding the JFileChooser to a container having a suitable layout, as #AVD suggests. For example, ImageDisplay adds the chooser to BorderLayout.WEST where it's free to grow vertically while adopting the UI delegate's preferred width. Before you abandon that approach, verify that you are not inadvertently defeating that design feature.
If you really need control over the display characteristics of the chooser's subcomponents, you may want to look at these variations of FileBrowser.