Following my previous two posts here and another one here, the following code
opens the regular file browser instead of the expanded one:
public class GuiHandler extends javax.swing.JFrame {
// data members
private DataParser xmlParser = new DataParser();
private File newFile;
JFileChooser jfc = new JFileChooser();
// more code
public void launchFileChooser() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
e.printStackTrace();
}
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
jfc.setAcceptAllFileFilterUsed(false);
if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
newFile = jfc.getSelectedFile();
}
});
}
// more code
private void XMLfilesBrowserActionPerformed(java.awt.event.ActionEvent evt) {
launchFileChooser();
xmlParser.getNodeListFromFile(newFile);
// here the code has the below problems
Problems:
The code opens a regular file browser when I hit a button to open XML file; it still allows me to pick a file.
It throws an exception:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: File cannot be null
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:198)
Why does it open the regular browser if jfc is a data member, and when it's a local
variable, the expanded one opens?
Concerning the regular versus expanded file chooser, make sure to call UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); before calling new JFileChooser();. Actually, unless you allow users to change the look and feel (L&F) during application execution, set the L&F close to the beginning of application execution, like in the main method, before creating any Swing components. From my experience, not doing so can cause some odd UI behavior.
When you have JFileChooser as a local variable in launchFileChooser, UIManager.setLookAndFeel is called before new JFileChooser. When JFileChooser is a class member variable (a.k.a. data member), UIManager.setLookAndFeel is called after new JFileChooser; in the latter case, the JFileChooser is created when an instance of GuiHandler is instantiated.
Concerning the IllegalArgumentException use SwingUtilities.invokeAndWait in launchFileChooser instead of SwingUtilities.invokeLater. Better yet, if you're sure launchFileChooser will always occur on the event dispatch thread, there's no need to call either SwingUtilities.invokeAndWait or SwingUtilities.invokeLater.
You also may want to use a file filter:
jfc.setFileFilter(new FileNameExtensionFilter("XML files (*.xml)", "xml"));
The following is an SSCE that demonstrates the concepts discussed above:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.filechooser.FileNameExtensionFilter;
public class GuiHandler extends JFrame {
public static void main(String[] args) throws Exception {
// call UIManager.setLookAndFeel early in application execution
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JFrame frame = new GuiHandler();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private final JFileChooser jfc;
public GuiHandler() {
this.jfc = new JFileChooser();
this.jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
this.jfc.setFileFilter(new FileNameExtensionFilter("XML files (*.xml)", "xml"));
final JButton button = new JButton("Open XML file");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
xmlFilesBrowserActionPerformed();
}
});
add(button);
pack();
}
protected void xmlFilesBrowserActionPerformed() {
final File xmlFile = getXmlFile();
if (xmlFile != null) {
System.out.println(xmlFile); // process XML file
}
}
private File getXmlFile() {
// At this point we should be on the event dispatch thread,
// so there is no need to call SwingUtilities.invokeLater
// or SwingUtilities.invokeAndWait.
if (this.jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
return this.jfc.getSelectedFile();
}
return null;
}
}
I'm not exactly sure what you mean by 'expanded one' but I assume you are referring to the file filter. In absence of any file filter, I'm guessing it's defaulting to showing all files. Try adding the following code before opening the dialog.
jfc.setFileFilter(new javax.swing.filechooser.FileFilter(){
public boolean accept(File f){
return f.isDirectory() || f.getName().toLowerCase().endsWith(".xml");
}
public String getDescription(){
return "XML File";
}
})
Related
I have a java swing application which has a processWindowEvent method.
below is the snippet
#Override
protected void processWindowEvent(WindowEvent e) {
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
//exit application with proper error message
}
}
Now when my swing application is launched in windows.
close with the cross in swing UI. ==> proper error message is shown
close the application from taskbar ==>proper error message is shown
but now if the same step is done in mac.
close with the cross in swing UI. ==> proper error message is shown
close the application from taskbar ==>does not come inside above method. So no proper message.
I wanted to know what is the default method which will be called in mac when java swing app is closed from taskbar(the dock)
A world without com.apple.eawt.*
You need to look towards java.awt.Desktop instead.
For example...
Desktop.getDesktop().setQuitHandler(new QuitHandler() {
#Override
public void handleQuitRequestWith(QuitEvent e, QuitResponse response) {
// Do some stuff
//response.cancelQuit();
//response.performQuit();
}
});
Desktop.getDesktop().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
Original Answer
Welcome to the wonderful world of "Apple does everything differently"
Basically what's happening is, when you "Quit" the program, Apple is calling System.exit(0), basically the same thing that would occur if your used CMD+Q
Now, Apple provides an API which provides functionality which you can use to "configure" your App with MacOS and perform some functionality which is unique to Apple, the problem is, it's a complete pain in the ... code to find useful information about and use.
What you're looking for is com.apple.eawt.ApplictionsetQuitStrategy. This defaults to calling System.exit(0), but you can change it to "close all windows" instead.
In this case, it would allow you to trap the WindowEvent and do what ever it is you want to do
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.out.println("Closing");
System.exit(0);
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
try {
Class quitStrategies = Class.forName("com.apple.eawt.QuitStrategy");
Object quitStrategy = null;
for (Object o : quitStrategies.getEnumConstants()) {
if ("CLOSE_ALL_WINDOWS".equals(o.toString())) {
quitStrategy = o;
}
}
if (quitStrategy != null) {
Class appClass = Class.forName("com.apple.eawt.Application");
Class params[] = new Class[]{};
Method getApplication = appClass.getMethod("getApplication", params);
Object application = getApplication.invoke(appClass);
Method setQuitStrategy = application.getClass().getMethod("setQuitStrategy", quitStrategies);
setQuitStrategy.invoke(application, quitStrategy);
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassNotFoundException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
}
}
My general advice is, build a nice "Mac" utilities class which encapsulates the functionality you want to play with and call that.
Also beware, this functionality may disappear suddenly in future releases.
It should be noted that if you intend to have a "one for all" application, you will need to use reflection, as the required API is not available in the standard API, but if you wanted to make a "Apple" only release, you should have a look at this for more information about how you can compile the code on MacOS, because using...
Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
is hell of a lot easier to write and understand
To catch window close event you need to add WindowListener and override method windowClosing. Use this code:
JFrame frame = new JFrame(...);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener( new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
JFrame frame = (JFrame)e.getSource();
....................
}
}
Why can't I call the setModal() method?
I am working on GUI. I have two jframes. The following code is for a button and is supposed to open the other frame. But i get error that says:
cannot find method setModal(boolean)
private void jButton3_actionPerformed(ActionEvent e)
{
HR hr = new HR();
if(f == 1){ // condition
hr.setModal(true); // give me error here ?
hr.setVisible(true);
}else{
jLabel5.setText("You aren't connected...");
}
}
hr.java
import java.awt.Dimension;
import javax.swing.JFrame;
public class HR extends JFrame {
public HR() {
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
this.getContentPane().setLayout( null );
this.setSize( new Dimension(400, 300) );
}
}
I am working on GUI I have two jframes
An application should only have a single parent JFrame. Other child windows should be a JDialog and you specify the frame as the parent.
A JDialog DOES have the setModal(...) method.
You create a JDialog the same way you create a JFrame.
JFrame class has no setModal(boolean) method..
refer to the doc here
therefore you CAN NOT invoke that method, your HR class must instead have defined that method... but I see in the update that actually the HR class is not defining it...
I've programmed a DLL in C. The first function sends a pointer of the callback function that is called when new data is available.
So I use JNA to wrap this function.
In order to avoid the end of the app, I use an InputStreamReader that wait data from the standard input. And when new data are available the callback is called and data are printed in the console.
But, if I use a JFrame to avoid the end of the program before closing the window, it doesn’t work properly. In fact, if I don’t resize the JFrame window, the callback is called about 30 times and after that nothing (even if new data are available). If I resize the window, the callback if never called (even if new data are available).
Please could you help me?
Thanks
Edit : This is my main method.
package jsigmausblib;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import javax.swing.JFrame;
public class JSigmaUSBLib {
public static void main(String[] args) {
NativeSigmaUSBLibInterface nsuli = (NativeSigmaUSBLibInterface) Native.loadLibrary("SigmaUSBLib1.0", NativeSigmaUSBLibInterface.class);
ReadCallback rc = new ReadCallback() {
#Override
public void callbackFunction(Pointer readData, byte len) {
System.out.println("ok"+readData.getByte(0));
}
};
SigmaUSBLibConfigStruct.ByValue config = new SigmaUSBLibConfigStruct.ByValue();
nsuli.SigmaUSBLibInit(rc , config);
JFrame frame = new JFrame("Debug");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(80, 60);
frame.setVisible(true);
}
}
i write a method to create a form(3 buttons and a textBox), then i call it in main.
but when i run program, before i enter information in the form (method form6 ),
Other commands that are executed! "s4 and ontname chenged in the form".
this is a part of my code:::::::::::
//////////////////////////////////////////////////////////////////////////
public static void main(String[] args) {
System.out.println("*begin main*"); // call form method
String s4= form6(); // s4 is returned by method.
System.out.println("s3333*"+s4);
System.out.println("ont:"+ontname);//it's global }
//////////////////////////////////////////////////////////////////////////
i have 2 questions:::
1--- While the form is running, other commands are executed!
What is their order execution?
2. --- i want to define a button to when i click it,it closes the form.
thanks all.
If I get your code correctly, ontname is either (1) a class member (declared outside a method) or (2) a local variable, which is declared in the method that contains this code snippet.
In both cases there is no need to "return" ontname just because it is not declared inside the anonymous ActionListener instance.
The following example illustrates a typical pattern for this problem:
public void someMethod() {
// ...
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String filename = File.separator+"c:";
JFileChooser fc = new JFileChooser(new File(filename));
fc.showOpenDialog(null);
File selFile = fc.getSelectedFile();
setOntName(selFile.getPath()); // <-- here we call another method
}
});
// ...
}
void setOntName(String ontName) {
// do something with ontName
}
Alternativly: declare ontName as a static class member (only):
private static String ontName = ""; // <-- accessible from main method
public static void main(String[] args) {
// ...
}
// more methods.
You can't return a value in this Method because the ActionListenerInterface does not allow this. But you can call another method from within the actionPerformed() method and pass the ontname to it.
You can also close the third button in the new method. Or define the third button as final and use it in the actionPerformed() method.
E.g.
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String filename = File.separator+"c:";
JFileChooser fc = new JFileChooser(new File(filename));
fc.showOpenDialog(null);
File selFile = fc.getSelectedFile();
ontname=selFile.getPath();
System.out.println("filepath: "+ontname); //it works correctly.
anotherMethod(ontname);
}
});
private void anotherMethod(String path) {
//doSomething with the path
//close third button here
}
You could probably define your variable ontname as global, outside of your function:
var ontname = null;
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
// ...
ontname=selFile.getPath();
}
});
// ...
System.out.println("filepath: "+ontname);
If you want to remember the values, then they should be class level variables.
But, generally, you would want to pass these to some other method to do some processing on them (or, say, persist them in a file). You can pass these as parameters to the other method.
(The second one is better in most cases, I don't know much about your app, so I am unable to give one answer)
There are other problems with your code:
You need to check whether the use has clicked the "Ok" or "Cancel" button in the open dialog to decide whether to get the file or not.
String filename = File.separator+"c:"; does not really make sense. Perhaps you meant String filename = "c:"+File.separator; But even this is not very useful. File.separator is for getting the platform specific file separator char (\ in Windows, / on linux) but since you are hard coding c:, you are anyway constrainting your app to Windows. You might want to have a better platform independent way (start at the "default" path, new JFileChooser() without arguments, and then remember the path the user last used, and proceed from there)
If the argument to the showOpenDialog method is your parent frame, then the dialog would be centered on the parent frame, and would, in most cases, look nicer.
You might also want to relook your variable names.
button2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String filename = File.separator+"c:";
JFileChooser fc = new JFileChooser(new File(filename));
int option = fc.showOpenDialog(null);
if(option = JFileChooser.APROVE_OPTION)
{
File selFile = fc.getSelectedFile();
String ontname=selFile.getPath();
System.out.println("filepath: "+ontname); //it works correctly.
doSomeOperation(ontname); //Or, declare ontname as a class level variable.
}
}
});
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
Hey, I've been developing an application in the windows console with Java, and want to put it online in all of its console-graphics-glory.
Is there a simple web applet API I can use to port my app over?
I'm just using basic System.out and System.in functionality, but I'm happy to rebuild my I/O wrappers.
I think something along these lines would be a great asset to any beginning Java developers who want to put their work online.
Sure, just make into an applet, put a small swing UI on it with a JFrame with two components - one for writing output to, and one for entering inputs from. Embed the applet in the page.
I did as Lars suggested and wrote my own.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.awt.Font;
public class Applet extends JFrame {
static final long serialVersionUID = 1;
/** Text area for console output. */
protected JTextArea textArea;
/** Text box for user input. */
protected JTextField textBox;
/** "GO" button, in case they don't know to hit enter. */
protected JButton goButton;
protected PrintStream printStream;
protected BufferedReader bufferedReader;
/**
* This function is called when they hit ENTER or click GO.
*/
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
goButton.setEnabled(false);
SwingUtilities.invokeLater(
new Thread() {
public void run() {
String userInput = textBox.getText();
printStream.println("> "+userInput);
Input.inString = userInput;
textBox.setText("");
goButton.setEnabled(true);
}
}
);
}
};
public void println(final String string) {
SwingUtilities.invokeLater(
new Thread() {
public void run() {
printStream.println(string);
}
}
);
}
public void printmsg(final String string) {
SwingUtilities.invokeLater(
new Thread() {
public void run() {
printStream.print(string);
}
}
);
}
public Applet() throws IOException {
super("My Applet Title");
Container contentPane = getContentPane();
textArea = new JTextArea(30, 60);
JScrollPane jScrollPane = new JScrollPane(textArea);
final JScrollBar jScrollBar = jScrollPane.getVerticalScrollBar();
contentPane.add(BorderLayout.NORTH, jScrollPane);
textArea.setFocusable(false);
textArea.setAutoscrolls(true);
textArea.setFont(new Font("Comic Sans MS", Font.TRUETYPE_FONT, 14));
// TODO This might be overkill
new Thread() {
public void run() {
while(true) {
jScrollBar.setValue(jScrollBar.getMaximum());
try{
Thread.sleep(100);
} catch (Exception e) {}
}
}
}.start();
JPanel panel;
contentPane.add(BorderLayout.CENTER, panel = new JPanel());
panel.add(textBox = new JTextField(55));
textBox.addActionListener(actionListener);
panel.add(goButton = new JButton("GO"));
goButton.addActionListener(actionListener);
pack();
// End of GUI stuff
PipedInputStream inputStream;
PipedOutputStream outputStream;
inputStream = new PipedInputStream();
outputStream = new PipedOutputStream(inputStream);
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "ISO8859_1"));
printStream = new PrintStream(outputStream);
new Thread() {
public void run() {
try {
String line;
while ((line = bufferedReader.readLine()) != null) {
textArea.append(line+"\n");
}
} catch (IOException ioException) {
textArea.append("ERROR");
}
}
}.start();
}
}
This below code was in a separate class, "Input", which has a static "inString" string.
public static String getString() {
inString = "";
// Wait for input
while (inString == "") {
try{
Thread.sleep(100);
} catch (Exception e) {}
}
return inString;
}
Through-out the lifespan of the project I will probably maintain this code some more, but at this point - it works :)
As a premier example of a glorious and incredibly useful cnsole-like webapp, please see goosh, the Google Shell. I cannot imagine browsing the Net without it anymore.
Granted, there's no source code, but you might get out a bit of its magic by using Firebug or so.
Using a TextArea might be a bug-prone approach. Remember that you'll need to do both input and output to this TextArea and that you must thus keep track of cursor position. I would suggest that, if you really do this approach, you abstract away over a plain TextArea (inheritance, maybe?) and use a component that has, e.g. a prompt() to show the prompt and enable input and a also follows the usual shell abstraction of having stdin (an InputStream, that reads from the prompt, but can be bound to, let's say files or so) and stdout and possibly stderr, OutputStreams, bound to the TextArea's text.
It's not an easy task, and I don't know of any library to do it.
I remember seenig telnet client applet implementationa around years ago (back when people used telnet). Maybe you could dig them out and modify them.
System.out and System.in are statics and therefore evil. You'll need to go through your program replacing them with non-statics ("parameterise from above"). From an applet you can't use System.setOut/setErr/setIn.
Then you're pretty much sorted. An applet. Add a TextArea (or equivalent). Append output to the text area. Write key strokes to the input. Job done.