I would really appreciate your help;
I'm using java (netbeans ide), i'm working with filechooser, when i choose a directory, i need to display it's path on a jtextfield. However nothing appears until the program is over (untill all the files of the directory are parsed and treated), I would like it to appear as soon as the program starts.
Please help me out, here is my code:
JFileChooser fch = new JFileChooser("C:\\");
fch.addChoosableFileFilter(filter);
fch.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int ret = fch.showOpenDialog(null);
int apr=0;
if (ret==JFileChooser.APPROVE_OPTION)
{
apr=1;
jTextField1.setText(fch.getSelectedFile().toString());
}
else jTextField1.setText("Nothing clicked!!!");
.......... the rest of the code .........
when I don't click the msg appears, yet when i do, the path won't apprear till after the program is finished
The code of JFileChooser... probably resides in an ActionListener. This is handled on the sole event handling thread. So do an invokeLater.
#Override
public void actionPerformed(ActionEvent event) {
...
EventQueue.invokeLater(new Runnable() { // Added
... rest of the code
}); // Added
}
Here I think "rest of the code" might be causing the delay, but you might try differently.
Related
I'm currently making a reading app in Java, and this is my main menu.
What I want is that when I press the bottom button after selecting a book another window with the book opens. What I did now is a function that will open the other window while closing the one I'm currently in to free a little bit of memory.
I first close the current window after retrieving the necessary information from it (the index of the book) like this:
btnOuvrirLeLivre.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
int index = list.getSelectionIndex();
LiseuseController controller = new LiseuseController(null, null);
parent.dispose();
controller.viewBookController(index);
}
});
(I'm using the MVC method for my project), parent is just the composite used to open the frame.
public void viewBookController(int index) {
Display displayBook = new Display();
Shell shellBook = new Shell(displayBook);
shellBook.setLayout(new GridLayout(1, false));
index += 250;
LiseuseView lecture = new LiseuseView(shellBook, SWT.NONE, index);
shellBook.pack();
shellBook.open();
while(!shellBook.isDisposed()) {
if(!displayBook.readAndDispatch())
displayBook.sleep();
}
displayBook.dispose();
}
The index is just the book's number in my database, everything should be fine but I get this error when I do this after pressing the button to open the book:
Exception in thread "main" org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:4875)
at org.eclipse.swt.SWT.error(SWT.java:4790)
at org.eclipse.swt.SWT.error(SWT.java:4761)
at org.eclipse.swt.widgets.Display.checkDisplay(Display.java:824)
at org.eclipse.swt.widgets.Display.create(Display.java:887)
at org.eclipse.swt.graphics.Device.<init>(Device.java:126)
at org.eclipse.swt.widgets.Display.<init>(Display.java:563)
at org.eclipse.swt.widgets.Display.<init>(Display.java:554)
at Controller.LiseuseController.viewBookController(LiseuseController.java:133)
at View.LiseuseHome$4.widgetSelected(LiseuseHome.java:81)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:252)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4209)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1037)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4026)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3626)
at Controller.LiseuseController.viewController(LiseuseController.java:126)
at Main.Main.main(Main.java:59)
(LiseuseController.java:133) contains "Display displayBook = new Display();"
And (LiseuseController.java:126) contains
if(!display.readAndDispatch())
display.sleep();
This is from the other function used to open the first window.
I don't really understand what is causing this error and I can't just put one in "visible" and the other one "invisible" like if I'm using Jframe because the 2 windows are on 2 different .java files.
Do you have any idea on how to fix this?
From the API documentation of org.eclipse.swt.widgets.Display
Applications which are built with SWT will almost always require only
a single display. In particular, some platforms which SWT supports
will not allow more than one active display. In other words, some
platforms do not support creating a new display if one already exists
that has not been sent the dispose() message.
You should therefore adapt your application to use only one instance of Display. Since the class LiceuseController already manages opening the initial window and the supplementary window(s), it seems fitting for it to manage an instance of Display for both uses.
This instance should be created at the application's start, maintained by the LiceuseController class and finally disposed when the application shuts down.
Another problem is that none of the methods in LiceuseController actually returns. As you can see from the stack trace, Display.readAndDispatch from LiseuseController.viewController is still active when you are creating the new window. I guess you also want to reopen the original window when the supplementary window is closed. Opening and closing windows in this manner will, however, endlessly increase your call stack until you end up with a StackOverflowException.
Instead, the LiceuseController should be able to create windows without outside interference. Therefore, instead of actively calling a method in the controller class to open another window, the listener should only tell the controller what window it should open next when the current window was closed.
An example could look like
public enum WindowType {
MAIN, BOOK, NONE
}
public class LiceuseController {
Display display;
WindowType nextToOpen = WindowType.MAIN;
public LiceuseController() {
display = new Display();
}
public void setNextToOpen(WindowType value) {
nextToOpen = value;
}
public void run() {
for (boolean run = true; run;) {
switch(nextToOpen) {
case MAIN:
viewController();
break;
case BOOK:
viewBookController();
break;
case NONE:
run = false;
break;
default:
throw new RuntimeException("unexpected enum constant");
}
}
/*
* Depending on how you want to manage the instance of this class,
* you could also extract this into a separate method.
*/
display.dispose();
}
private void viewController() {
// open main window using 'display'
}
private void viewBookController() {
// open book window using 'display'
}
}
so that a listener only needs to call LiceuseController.setNextToOpen and then close the current window. This will cause either viewController or viewBookController to return after which the loop will reenter and open the requested window. To shut down the application, call setNextToOpen with WindowType.NONE.
For school, I'm attempting to recreate Microsoft's Notepad program using Java's Swing. I'm working on the saving and opening of .txt files, and I'm trying to figure out a way for the program to detect when a change has been made to the document. If a change has been detected and the user chooses to open or create a new file, I want the program to prompt the user if they would like to save their changes before continuing.
My thought for this was to create a flag, called documentChanged, that would initially be false, and which would be set to true whenever a change was made to the JTextArea. To detect this change, I thought of using a TextListener as follows:
public class JNotepad implements ActionListener
{
boolean documentChanged;
JTextArea notepad;
JNotepad()
{
documentChanged = false;
notepad = new JTextArea();
notepad.addTextListener(new TextListener() {
public void textValueChanged(TextEvent te) {
documentChanged = true;
}
});
}
}
However, I learned that Java classes are unable to implement multiple interfaces at once, and I'm already using ActionListeners to implement the items of my notepad's menu bar.
My question is, is there any way to use both TextListener and ActionListener (or any other listener) simultaneously in the same class? If not, what would be my best plan of action for detecting a change in the document?
It was answer in another post. See Text Changed event in JTextArea? How to?
And also see How to Write a Document Listener (DocumentListener) in Oracle, you will see an applet example.
How does your this even compile
notepad = new JTextArea();
notepad.addTextListener(new TextListener() {
// ....
}
since TextListeners are not defined to work with JTextAreas but rather with TextAreas, a completely different beast.
You should add a DocumentListener to your JTextArea's Document.
notepad.getDocument().addDocumentListener(new DocumentListener() {
void insertUpdate(DocumentEvent e) {
documentChanged = true;
}
void removeUpdate(DocumentEvent e) {
documentChanged = true;
}
void changedUpdate(DocumentEvent e) {
documentChanged = true;
}
});
Regarding
My question is, is there any way to use both TextListeners and ActionListeners (or any other listener) simultaneously in the same class?
Use of a DocumentListener has nothing to do with ActionListeners used elsewhere in your program since their domains are orthogonal to each other, i.e., the one has absolutely nothing to do with the other.
can anybody tell me whats wrong?
i keep getting the numberformatexception when i try to run this program.
here is my action listener.
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
String s = t2.getText();
int r = Integer.parseInt("s");
if (t1.getText().equals("1") && (r <= 19)){
JOptionPane.showMessageDialog(null, "sdskd");
}
The image is accessible as an URL from either the class-path or the document base. An applet will typically not be able to load an image from the client PC, which is what that applet is trying to do.
Other tips:
For better help sooner, post an SSCCE.
Ensure the Java Console is configured to show for applets & JWS apps. If there is no output at the default level, raise it and try again.
Few notes about your code
Your code is not extending the JApplet
You are not implementing the public void sart() method.
You are not implementing the public void init() method.
And most importantly you are missing this
This is for a kiosk application where this message is not desired. It's odd because Mac doesn't display this message in either browser -- seems to only happen on Ubuntu.
Using this example applet on Ubuntu 10, Firefox 12, I was able to reproduce the message "Applet initialized," illustrated below. It doesn't appear to be from an overridden init(), and the super implementation is empty; I presume it's a feature of either the plug-in or the browser itself. Oddly, the message actually moves from one lower corner of the browser window to the other, as the mouse cursor approaches it.
For embedded use, consider starting the applet (or hybrid application) via java-web-start as shown in the example.
Addendum: Andrew's example produces the message "Applet started."
Seems like futzing to me, but if by 'status bar' you mean the little bar at the bottom of older browsers, try using Applet.showStatus("") at the end of init() or start().
Edit: Using the following command produces the expected result in appletviwer.
$ appletviewer NoMessageApplet.java
Code:
// intended only to show attributes - view in browser
// <applet code='NoMessageApplet' width=400 height=400></applet>
import java.awt.BorderLayout;
import javax.swing.*;
public class NoMessageApplet extends JApplet {
String noMessage = " Nobody Here But Us Chickens..";
JTextArea output;
#Override
public void init() {
try {
SwingUtilities.invokeAndWait( new Runnable() {
public void run() {
initGui();
}
});
} catch(Exception e) {
e.printStackTrace();
}
}
public void initGui() {
JPanel gui = new JPanel(new BorderLayout(5,5));
output = new JTextArea(5,20);
gui.add(new JScrollPane(output));
setContentPane(gui);
setMessage("initGui()" + noMessage);
}
#Override
public void start() {
setMessage("start()" + noMessage);
}
/** Both sets the message as the 'status' message &
appends it to the output control */
public void setMessage(final String message) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
output.append(message + "\n");
}
});
showStatus(message);
}
}
This is not a direct answer to your question but definitely a possible solution to your problem (Was a comment. Added as an answer as suggested by #Andrew Thompson):
If it is a kiosk application then why is there a status bar at all?
If you have control over the system where the application is used from (or where the browser is installed), you can either deactivate the status bar in the browser or make the browser to be displayed always in full screen mode.
Most kiosk applications operate this way.
FF13 fixed it (so does the most recent version of Chrome). Both now currently do not enable status bar's by default (they did when I made this initial post). Not quite an answer, but an answer that worked for me.
hi i have a full screen program which i dont want people to close unless they have a password i have this code at the moment
public void windowClosing(WindowEvent arg0)
{
System.out.println("HERE");
String inputValue = JOptionPane.showInputDialog("Please input the closeword");
if (inputValue != "closeplz")
{
}
}
in the if statement i want it to stop the method so that the program doesent close. any help would be greatly aprecheated thanks ste
You have to call
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
on (or within) the JFrame instance. Then the frame will not close unless you do it manually, though windowClosing() will still be called. Inside it, you can then conditionally call
System.exit(1);
which will end the application. Be sure to do any necessary cleanup first.
Check out Closing an Applicaton for a simple class to help you with this. You would need to provide the custom close action that prompts the user for the password.
Using your simple example the code would be:
Action ca = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
JFrame frame = (JFrame)e.getSource();
String inputValue = JOptionPane.showInputDialog("Please input the closeword");
if (! inputValue.equals("closeplz"))
{
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
}
};
CloseListener cl = new CloseListener(ca);