https://github.com/carlb710/myProgram
I'm using IntelliJ Swing GUI editor to make the front-end of my program. Based on the int value returned by a spinner, certain elements of the GUI are shown or hidden. Every time I change that int value and restart the program, one of many exceptions is thrown, all NullPointer Exceptions. I think they are always in the same thread, it's just the reason that varies.
Error usually looks something like these below:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot read field "top" because "topInsets" is null
at java.desktop/com.apple.laf.AquaTabbedPaneCopyFromBasicUI.rotateInsets(AquaTabbedPaneCopyFromBasicUI.java:2000)
at java.desktop/com.apple.laf.AquaTabbedPaneCopyFromBasicUI.getTabAreaInsets(AquaTabbedPaneCopyFromBasicUI.java:1681)
at java.desktop/com.apple.laf.AquaTabbedPaneUI$AquaTruncatingTabbedPaneLayout.superCalculateTabRects(AquaTabbedPaneUI.java:1133)
at java.desktop/com.apple.laf.AquaTabbedPaneUI$AquaTruncatingTabbedPaneLayout.calculateTabRects(AquaTabbedPaneUI.java:1091)
at java.desktop/com.apple.laf.AquaTabbedPaneCopyFromBasicUI$TabbedPaneLayout.calculateLayoutInfo(AquaTabbedPaneCopyFromBasicUI.java:2322)
at java.desktop/com.apple.laf.AquaTabbedPaneCopyFromBasicUI$TabbedPaneLayout.layoutContainer(AquaTabbedPaneCopyFromBasicUI.java:2226)
at java.desktop/java.awt.Container.layout(Container.java:1538)
at java.desktop/java.awt.Container.doLayout(Container.java:1527)
at java.desktop/java.awt.Container.validateTree(Container.java:1723)
at java.desktop/java.awt.Container.validate(Container.java:1658)
at java.desktop/com.apple.laf.AquaTabbedPaneCopyFromBasicUI.ensureCurrentLayout(AquaTabbedPaneCopyFromBasicUI.java:1335)
at java.desktop/com.apple.laf.AquaTabbedPaneUI.paint(AquaTabbedPaneUI.java:148)
at java.desktop/javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at java.desktop/javax.swing.JComponent.paintComponent(JComponent.java:797)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1074)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:907)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1083)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:907)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1083)
at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:907)
at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5271)
at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBufferedImpl(RepaintManager.java:1643)
at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1618)
at java.desktop/javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1556)
at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1323)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1060)
at java.desktop/java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at java.desktop/sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:75)
at java.desktop/sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:112)
at java.desktop/java.awt.Container.paint(Container.java:2003)
at java.desktop/java.awt.Window.paint(Window.java:3949)
at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:876)
at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:848)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:848)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:823)
at java.desktop/javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:772)
at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1884)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
The exceptions seem to be thrown when I run the following code in my main class to create the JFrame instance for my program:
App window = null;
try{
window = new App();
} catch(NullPointerException e){
e.printStackTrace();
}
JFrame frame = new JFrame("Java QA Checker");
frame.setContentPane(window.landing);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
Font font = new Font("Helvetica", Font.PLAIN, 16);
My GUI constructor looks like this where I think the issue is coming from:
//listener for spinner, changes number of elements on screen
spinner1.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
numOfFiles = (Integer) spinner1.getValue();
//switch statement sets number of elements for file settings visible or not based on spinner value up to 12
try {
switch(numOfFiles){
case 0:{
file1OriginLabel.setVisible(true);
file2OriginLabel.setVisible(true);
file3OriginLabel.setVisible(true);
file4OriginLabel.setVisible(true);
file5OriginLabel.setVisible(true);
file6OriginLabel.setVisible(true);
file7OriginLabel.setVisible(true);
file8OriginLabel.setVisible(true);
file9OriginLabel.setVisible(true);
file10OriginLabel.setVisible(true);
file11OriginLabel.setVisible(true);
file12OriginLabel.setVisible(true);
file1OriginInputted.setVisible(true);
file2OriginInputted.setVisible(true);
file3OriginInputted.setVisible(true);
file4OriginInputted.setVisible(true);
file5OriginInputted.setVisible(true);
file6OriginInputted.setVisible(true);
file7OriginInputted.setVisible(true);
file8OriginInputted.setVisible(true);
file9OriginInputted.setVisible(true);
file10OriginInputted.setVisible(true);
file11OriginInputted.setVisible(true);
file12OriginInputted.setVisible(true);
addFileButton1.setVisible(true);
addFileButton2.setVisible(true);
addFileButton3.setVisible(true);
addFileButton4.setVisible(true);
addFileButton5.setVisible(true);
addFileButton6.setVisible(true);
addFileButton7.setVisible(true);
addFileButton8.setVisible(true);
addFileButton9.setVisible(true);
addFileButton10.setVisible(true);
addFileButton11.setVisible(true);
addFileButton12.setVisible(true);
filePathLabel1.setVisible(true);
filePathLabel2.setVisible(true);
filePathLabel3.setVisible(true);
filePathLabel4.setVisible(true);
filePathLabel5.setVisible(true);
filePathLabel6.setVisible(true);
filePathLabel7.setVisible(true);
filePathLabel8.setVisible(true);
filePathLabel9.setVisible(true);
filePathLabel10.setVisible(true);
filePathLabel11.setVisible(true);
filePathLabel12.setVisible(true);
} break;
case 1:{
file1OriginLabel.setVisible(true);
file2OriginLabel.setVisible(false);
file3OriginLabel.setVisible(false);
file4OriginLabel.setVisible(false);
file5OriginLabel.setVisible(false);
file6OriginLabel.setVisible(false);
file7OriginLabel.setVisible(false);
file8OriginLabel.setVisible(false);
file9OriginLabel.setVisible(false);
file10OriginLabel.setVisible(false);
file11OriginLabel.setVisible(false);
file12OriginLabel.setVisible(false);
file1OriginInputted.setVisible(true);
file2OriginInputted.setVisible(false);
file3OriginInputted.setVisible(false);
file4OriginInputted.setVisible(false);
file5OriginInputted.setVisible(false);
file6OriginInputted.setVisible(false);
file7OriginInputted.setVisible(false);
file8OriginInputted.setVisible(false);
file9OriginInputted.setVisible(false);
file10OriginInputted.setVisible(false);
file11OriginInputted.setVisible(false);
file12OriginInputted.setVisible(false);
addFileButton1.setVisible(true);
addFileButton2.setVisible(false);
addFileButton3.setVisible(false);
addFileButton4.setVisible(false);
addFileButton5.setVisible(false);
addFileButton6.setVisible(false);
addFileButton7.setVisible(false);
addFileButton8.setVisible(false);
addFileButton9.setVisible(false);
addFileButton10.setVisible(false);
addFileButton11.setVisible(false);
addFileButton12.setVisible(false);
filePathLabel1.setVisible(true);
filePathLabel2.setVisible(false);
filePathLabel3.setVisible(false);
filePathLabel4.setVisible(false);
filePathLabel5.setVisible(false);
filePathLabel6.setVisible(false);
filePathLabel7.setVisible(false);
filePathLabel8.setVisible(false);
filePathLabel9.setVisible(false);
filePathLabel10.setVisible(false);
filePathLabel11.setVisible(false);
filePathLabel12.setVisible(false);
}break;
case 2:{
file1OriginLabel.setVisible(true);
file2OriginLabel.setVisible(true);
file3OriginLabel.setVisible(false);
file4OriginLabel.setVisible(false);
file5OriginLabel.setVisible(false);
file6OriginLabel.setVisible(false);
file7OriginLabel.setVisible(false);
file8OriginLabel.setVisible(false);
file9OriginLabel.setVisible(false);
file10OriginLabel.setVisible(false);
file11OriginLabel.setVisible(false);
file12OriginLabel.setVisible(false);
file1OriginInputted.setVisible(true);
file2OriginInputted.setVisible(true);
file3OriginInputted.setVisible(false);
file4OriginInputted.setVisible(false);
file5OriginInputted.setVisible(false);
file6OriginInputted.setVisible(false);
file7OriginInputted.setVisible(false);
file8OriginInputted.setVisible(false);
file9OriginInputted.setVisible(false);
file10OriginInputted.setVisible(false);
file11OriginInputted.setVisible(false);
file12OriginInputted.setVisible(false);
addFileButton1.setVisible(true);
addFileButton2.setVisible(true);
addFileButton3.setVisible(false);
addFileButton4.setVisible(false);
addFileButton5.setVisible(false);
addFileButton6.setVisible(false);
addFileButton7.setVisible(false);
addFileButton8.setVisible(false);
addFileButton9.setVisible(false);
addFileButton10.setVisible(false);
addFileButton11.setVisible(false);
addFileButton12.setVisible(false);
filePathLabel1.setVisible(true);
filePathLabel2.setVisible(true);
filePathLabel3.setVisible(false);
filePathLabel4.setVisible(false);
filePathLabel5.setVisible(false);
filePathLabel6.setVisible(false);
filePathLabel7.setVisible(false);
filePathLabel8.setVisible(false);
filePathLabel9.setVisible(false);
filePathLabel10.setVisible(false);
filePathLabel11.setVisible(false);
filePathLabel12.setVisible(false);
} break;
case 3:{
file1OriginLabel.setVisible(true);
file2OriginLabel.setVisible(true);
file3OriginLabel.setVisible(true);
file4OriginLabel.setVisible(false);
file5OriginLabel.setVisible(false);
file6OriginLabel.setVisible(false);
file7OriginLabel.setVisible(false);
file8OriginLabel.setVisible(false);
file9OriginLabel.setVisible(false);
file10OriginLabel.setVisible(false);
file11OriginLabel.setVisible(false);
file12OriginLabel.setVisible(false);
file1OriginInputted.setVisible(true);
file2OriginInputted.setVisible(true);
file3OriginInputted.setVisible(true);
file4OriginInputted.setVisible(false);
file5OriginInputted.setVisible(false);
file6OriginInputted.setVisible(false);
file7OriginInputted.setVisible(false);
file8OriginInputted.setVisible(false);
file9OriginInputted.setVisible(false);
file10OriginInputted.setVisible(false);
file11OriginInputted.setVisible(false);
file12OriginInputted.setVisible(false);
addFileButton1.setVisible(true);
addFileButton2.setVisible(true);
addFileButton3.setVisible(true);
addFileButton4.setVisible(false);
addFileButton5.setVisible(false);
addFileButton6.setVisible(false);
addFileButton7.setVisible(false);
addFileButton8.setVisible(false);
addFileButton9.setVisible(false);
addFileButton10.setVisible(false);
addFileButton11.setVisible(false);
addFileButton12.setVisible(false);
filePathLabel1.setVisible(true);
filePathLabel2.setVisible(true);
filePathLabel3.setVisible(true);
filePathLabel4.setVisible(false);
filePathLabel5.setVisible(false);
filePathLabel6.setVisible(false);
filePathLabel7.setVisible(false);
filePathLabel8.setVisible(false);
filePathLabel9.setVisible(false);
filePathLabel10.setVisible(false);
filePathLabel11.setVisible(false);
filePathLabel12.setVisible(false);
}break;
case 4:{..
} break;
//this goes until case 12, each just continues to make one more item .setVisible = true until all 12 elements are visible.
default: break;
}
} catch(NullPointerException e1){
e1.printStackTrace();
SwingUtilities.updateComponentTreeUI(landing);
}
SwingUtilities.updateComponentTreeUI(landing);
}
});
//additional code here that shouldn't be relevant to the issue
} ```
My issue was coming from the Main class that instantiated my GUI. I set the look and feel after creating the JFrame, when it should have been done before creating any GUI elements. This fixed my problem
Related
Description
A JFileChooser is used in a Java Swing application. Users are able to enter any filename permitted by the operating system, but from time to time they will enter erroneous filenames, such as names including invalid characters.
If a user enters a name ending with a space, such as
SomeName
an error message is shown. This is done by overriding JFileChooser#approveSelection, matching the filename to an undesired regex and then displaying an error dialog.
However when the user enters only a space, then an exception is thrown:
2022-10-18 12:34:54 SEVERE (CustomExceptionHandler::uncaughtException) Uncaught exception: java.nio.file.InvalidPathException: Trailing char < > at index 22: C:\X\Y\Z\ on [AWT-EventQueue-0]
Exception Stacktrace:
java.nio.file.InvalidPathException: Trailing char < > at index 22: C:\X\Y\Z\
at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:191)
at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:229)
at java.base/java.nio.file.Path.of(Path.java:147)
at java.base/java.nio.file.Paths.get(Paths.java:69)
at java.desktop/sun.awt.shell.ShellFolder.getShellFolder(ShellFolder.java:247)
at java.desktop/javax.swing.plaf.basic.BasicFileChooserUI.changeDirectory(BasicFileChooserUI.java:1353)
at java.desktop/javax.swing.plaf.basic.BasicFileChooserUI$ApproveSelectionAction.actionPerformed(BasicFileChooserUI.java:1142)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:297)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6635)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
at java.desktop/java.awt.Component.processEvent(Component.java:6400)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5011)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2772)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:117)
at java.desktop/java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:190)
at java.desktop/java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:235)
at java.desktop/java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:233)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.desktop/java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:233)
at java.desktop/java.awt.Dialog.show(Dialog.java:1070)
at java.desktop/javax.swing.JFileChooser.showDialog(JFileChooser.java:769)
at java.desktop/javax.swing.JFileChooser.showSaveDialog(JFileChooser.java:691)
at core.RetainerExportController.exportRetainer(RetainerExportController.java:156)
at core.RetainerExportController.lambda$1(RetainerExportController.java:64)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:297)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6635)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
at java.desktop/java.awt.Component.processEvent(Component.java:6400)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5011)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2772)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
This exception keeps popping up in our error logs, because while users are instructed not to enter spaces as filenames, they still will from time to time.
Investigation
After looking into this, the problem appears to be coming from the BasicFileChooserUI. There is a filter for missing or empty strings in the class:
if (filename == null || filename.length() == 0) {
// no file selected, multiple selection off, therefore cancel the approve action
resetGlobFilter();
return;
}
However there is no filter for a blank filename. So this name is not filtered by BasicFileChooserUI, but it is recognized to be ending on a space by the WindowsPathParser, which leads to the error.
There is more odd behavior as well. For example entering a name consisting purely of forbidden characters, such as
???
results in just nothing happening, i.e.
No exception is thrown
JFileChooser#approveSelection is also never reached
How to solve?
It is not clear how to solve it, because all of the erroneous behavior occurs in internal Swing and sun.nio.fs code. E.g. there are regex filters in our JFileChooser implementation, which trigger upon approveSelection and check for names consisting of spaces and invalid characters - however approveSelection is never called in this scenario. It is called if WindowsPathParser#parse and WindowsPathParser#normalize are passed, but otherwise the error handling is useless, because some weird internal error handling is done internally beforehand.
I've looked into extending the WindowsFileChooserUI or the BasicFileChooserUI, but not only would that introduce unnecessary explicit dependencies on the desktop package for the latter case, but it is (as far as I see) not possible to do, at least with anything close to clean software design, because both of those classes use private members that are crucial to the problem at hand. E.g. WindowsFileChooserUI holds the JTextField which handles the user input as a private member and sets it up and uses it in the same method, so accessing it and even modifying it in any class attempting to extend WindowsFileChooserUI is going to be a problem.
Long story short - how do I prevent an InvalidPathException from being thrown, when users open the JFileChooser dialog and enter only a space?
Notes
Because internal APIs are affected the used JDK may be relevant: 11.0.14_9
The dialog creation itself is not spectacular, it is created thusly:
JFileChooser dialog = new CustomFileChooser( file );
dialog.setDialogType( JFileChooser.SAVE_DIALOG );
dialog.setAcceptAllFileFilterUsed( false );
The only methods that are overridden by CustomFileChooser are
createDialog
approveSelection
Minimal reproducible example
Because an example has been requested, the error can be reproduced as follows:
Set up a swing application (e.g. in Eclipse)
Create a JFileChooser dialog as such:
JFileChooser dialog = new JFileChooser( file );
dialog.setDialogType( JFileChooser.SAVE_DIALOG );
dialog.setAcceptAllFileFilterUsed( false );
Run the application, make sure the dialog creation is triggered
In the dialog enter a space as filename:
Confirm
An InvalidPathException is thrown
Note that this error requires the JVM being run on Windows and my tests happened on Java 11.
While older file chooser versions stripped spaces from entered file names, they never cared about the validity of the names beyond spaces. E.g. entering something like \<\>\" gets accepted. Invalid path names didn’t cause exceptions, because java.io.File doesn’t check the syntax either.
In newer versions, the NIO FileSystem API is used at some places and the space is not always stripped. The specific exception occurs because new File(" ").getAbsoluteFile().isDirectory() evaluates to true for some reason (while new File(" ").isDirectory() doesn’t), so the file chooser tries to change the directory to the invalid path, instead of invoking approveSelection() which the application could override.
Since file chooser’s code can’t cope with exceptions for invalid files, I made this workaround which uses a special File subclass which reports not to be a directory and can be detected at approveSelection():
public class FileChooserTest {
static final class Invalid extends File {
final String originalName;
public Invalid(String pathname) {
super(pathname);
originalName = pathname;
}
#Override
public boolean isDirectory() {
return false;
}
#Override
public String getName() {
return originalName;
}
}
public static void main(String... args) {
if(!EventQueue.isDispatchThread()) {
EventQueue.invokeLater(FileChooserTest::main);
return;
}
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ReflectiveOperationException | UnsupportedLookAndFeelException e) {
throw new RuntimeException(e);
}
JFileChooser fc = new JFileChooser() {
#Override
public void approveSelection() {
if(getSelectedFile() instanceof Invalid) {
setSelectedFile(null);
return;
}
super.approveSelection();
}
};
fc.setFileSystemView(new FileSystemView() {
#Override
public File createFileObject(String path) {
try {
Paths.get(path);
} catch(InvalidPathException ex) {
return new Invalid(path);
}
return super.createFileObject(path);
}
#Override
public File createFileObject(File dir, String filename) {
try {
Paths.get(filename);
} catch(InvalidPathException ex) {
return new Invalid(filename);
}
return super.createFileObject(dir, filename);
}
#Override
public File createNewFolder(File containingDir) throws IOException {
return FileSystemView.getFileSystemView().createNewFolder(containingDir);
}
});
if(fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
System.out.println(fc.getSelectedFile());
}
else System.out.println("Not approved");
}
}
This does not only eliminate the exception but also prevents invalid files from getting approved. Of course, it could be improved, e.g. by providing feedback to the user. But it would be better if bugs like JDK-8196673 get fixed anyway.
Note: the reason why names containing * or ? are not rejected, is that they are converted to a file name filter. So when you enter, e.g. *.txt, it should show up in the filter combobox.
Maybe you could simply remove the leading/trailing spaces from the filename before file chooser processing is invoked:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Main
{
public static void main(String[] args) throws Exception
{
JFileChooser fc = new JFileChooser( );
JTextField tf = SwingUtils.getDescendantsOfType(JTextField.class, fc).get(0);
tf.addFocusListener( new FocusAdapter()
{
#Override
public void focusLost(FocusEvent e)
{
JTextField tf = (JTextField)e.getSource();
tf.setText( tf.getText().trim() );
System.out.println( tf.getText() );
}
});
tf.addKeyListener( new KeyAdapter()
{
#Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
JTextField tf = (JTextField)e.getSource();
tf.setText( tf.getText().trim() );
System.out.println( tf.getText() );
}
}
});
fc.showOpenDialog(null);
}
}
The above code requires the Swing Utils class.
I extended JFileChooser to add a confirmation dialog if the file I wanted to save has the same name as an existing file. Perhaps you can use this to start a more robust version of JFileChooser.
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
public class OSFileChooser extends JFileChooser {
private static final long serialVersionUID = 1L;
#Override
public void approveSelection() {
File f = getSelectedFile();
if (f.exists() && getDialogType() == SAVE_DIALOG) {
int result = JOptionPane.showConfirmDialog(this, f.getName() +
" exists, overwrite?",
"Existing file", JOptionPane.YES_NO_CANCEL_OPTION);
switch (result) {
case JOptionPane.YES_OPTION:
super.approveSelection();
return;
case JOptionPane.NO_OPTION:
return;
case JOptionPane.CLOSED_OPTION:
return;
case JOptionPane.CANCEL_OPTION:
cancelSelection();
return;
}
}
super.approveSelection();
}
#Override
public File getSelectedFile() {
File file = super.getSelectedFile();
if (file != null && getDialogType() == SAVE_DIALOG) {
String extension = getExtension(file);
if (extension.isEmpty()) {
FileTypeFilter filter = (FileTypeFilter) getFileFilter();
if (filter != null) {
extension = filter.getExtension();
String fileName = file.getPath();
fileName += "." + extension;
file = new File(fileName);
}
}
}
return file;
}
public String getExtension(File file) {
String extension = "";
String s = file.getName();
int i = s.lastIndexOf('.');
if (i > 0 && i < (s.length() - 1)) {
extension = s.substring(i + 1).toLowerCase();
}
return extension;
}
}
And the associated FileTypeFilter class.
import java.io.File;
import javax.swing.filechooser.FileFilter;
public class FileTypeFilter extends FileFilter {
private String extension;
private String description;
public FileTypeFilter(String description, String extension) {
this.extension = extension;
this.description = description;
}
#Override
public boolean accept(File file) {
if (file.isDirectory()) {
return true;
}
return file.getName().endsWith("." + extension);
}
#Override
public String getDescription() {
return description + String.format(" (*.%s)", extension);
}
public String getExtension() {
return extension;
}
}
I want to verify using assert statement that item is not being added to the cart. This is my selenium code:
public void verify_itemadded(String action) throws Exception {
WebDriverWait wait = new WebDriverWait(session.driver, 40);
switch(action) {
case "added":
case "not removed":
WebElement itemVerify = wait.until(ExpectedConditions.visibilityOf(element("ItemVerify")));
Assert.assertTrue("Item displayed in card",itemVerify.isDisplayed());
if (itemVerify.isDisplayed()) {
logger.info("Item displayed in cart");
}
break;
case "not added":
WebElement itemVerifyremove = wait.until(ExpectedConditions.visibilityOf(element("ScanOrLookup")));
Assert.assertTrue("Item not displayed in card",!itemVerifyremove.isDisplayed());
if (!itemVerifyremove.isDisplayed()) {
logger.info("Item not displayed in cart");
}
break;
}
I am getting as an error saying "Item not displayed in cart", whereas it should give that the test should pass.
Can someone please tell me where am I going wrong? Thank you :)
The 1st time program is loaded the arrow key selection in autocomplete combobox works. But after I clear and reload the values in it using a method below the arrow key navigation and selection of combobox items does not work.
I use TextFields.bindAutoCompletion method from ControlsFx 8 to bind combobox.
// load Auto Compleat nic,fname,lname,id values for search Combo Box
private void loadValuesToComboSearchBox() {
try {
// clear elements of Search Combo Box
comboSearch.getItems().clear();
// Disable Search Combo Box
comboSearch.setEditable(false);
// load Auto Compleat nic,fname,lname,id values for search Text Field
ResultSet getsearchElements = employeDao.getSearchemployeeByNicFnameLnmeId();
LinkedHashSet<String> addElements = new LinkedHashSet<>();
while (getsearchElements.next()) {
addElements.add(getsearchElements.getString("id"));
addElements.add(getsearchElements.getString("firstname"));
addElements.add(getsearchElements.getString("lastname"));
addElements.add(getsearchElements.getString("nic"));
}
// Add elements to Auto Compleat Text Field
TextFields.bindAutoCompletion(comboSearch.getEditor(), addElements);
// Enable Search Combo Box
comboSearch.setEditable(true);
} catch (Exception e) {
new Alert(Alert.AlertType.INFORMATION, e + "", ButtonType.OK).showAndWait();
e.printStackTrace();
}
}
I believe this issue occurs due to the several overlapping AutoCompletionBindings.
In order to fix that you should keep reference to the previous binding and dispose it upon reload. Also, note that to clear the selection in JavaFX combobox more steps should be performed.
private AutoCompletionBinding<String> completion;
....
private void loadValuesToComboSearchBox() {
try {
// clear selection
comboSearch.getItems().clear();
comboSearch.valueProperty().set(null);
comboSearch.getEditor().clear();
comboSearch.setEditable(false);
ResultSet getSearchElements = employeDao.getSearchemployeeByNicFnameLnmeId();
Set<String> addElements = new LinkedHashSet<>();
while (getSearchElements.next()) {
addElements.add(getSearchElements.getString("id"));
addElements.add(getSearchElements.getString("firstname"));
addElements.add(getSearchElements.getString("lastname"));
addElements.add(getSearchElements.getString("nic"));
}
if (completion != null) {
completion.dispose();
}
completion = TextFields.bindAutoCompletion(comboSearch.getEditor(), addElements);
comboSearch.setEditable(true);
} catch (Exception e) {
new Alert(Alert.AlertType.INFORMATION, e + "", ButtonType.OK).showAndWait();
e.printStackTrace();
}
}
I am trying to pass values from my database java file to my frame java file.BY creating a function like "frame java . get value (name ,phone, date ) " and receiving the value in the frame java file . I tried to print the passed value in the console it works fine, but when i try to set value to the text field it doesn't display the text in the text filed... I don't what's wrong can any one help me to sort out this issue.
Here is database java function
public void check_room(String roomno, String date) throws SQLException {
String sql = "select * from customerinfo where roomno='" + roomno
+ "'and cdate='" + date + "' ";
System.out.print("search method called \n ");
System.out.print("\n ");
try {
con = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:xe", "hotel", "hotel");
} catch (SQLException ex) {
// Logger.getLogger(checkout.class.getName()).log(Level.SEVERE,
// null, ex);
}
sate = con.createStatement();
rs = sate.executeQuery(sql);
int tmp = 0;
try {
while (rs.next()) {
System.out.print("search found \n ");
String name = rs.getString("GUEST_NAME");
String phono = rs.getString("GUEST_PHO");
String addr = rs.getString("G_ADDR");
String paid = rs.getString("PAID");
String total = rs.getString("TOTAL");
String balance = rs.getString("BALANCE");
System.out.println(name);
mainmenu menu = new mainmenu();
menu.getvalue(name, phono, addr, paid, total, balance);
tmp++;
}
} catch (SQLException ex) {
// Logger.getLogger(checkout.class.getName()).log(Level.SEVERE,
// null, ex);
}
if (tmp <= 0) {
JOptionPane.showMessageDialog(null, "no details found ");
}
}
==========================================================================
This is my frame java file
public void getvalue(String name, String phono, String addr, String paid,String total, String balance) {
nam.setText(name);
pho.setText(phono);
// mainmenu();
}
I edited as u said but getting error . I have attached my skeleton code
and the error i get, below
edited code.
database file
public class OracelThinconnection
{
private MainMenu menu;
public OracelThinconnection(MainMenu menu)
{
this.menu=menu;
..................
.................
.............
========================================================================
Error i get
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: Uncompilable source code - cannot find symbol
symbol: constructor OracelThinconnection()
location: class bookingapp.OracelThinconnection
at bookingapp.MainMenu.jButton1ActionPerformed(MainMenu.java:1438)
at bookingapp.MainMenu.access$300(MainMenu.java:33)
at bookingapp.MainMenu$4.actionPerformed(MainMenu.java:379)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6263)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6028)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
I don't understand the code you've not shown, but a guess as to your problem is that you're creating a new instance of your GUI, one not visualized, and trying to send information to it, while the visualized GUI sits unperturbed and un-updated.
The key is that you're creating a new instance of your mainmenu GUI, one that has no relationship to the one that is displayed. Passing data to this new instance will have no effect on the displayed GUI.
Here:
mainmenu menu= new mainmenu();
menu. getvalue (name, phono, addr, paid, total, balance);
You're creating a new mainmenu object (the class should be named MainMenu).
A solution, give your Database class a MainMenu field, and pass into this field a valid reference to the main gui, and then call methods on the GUI, but only on the Swing event thread. For example:
public class MyDataBase {
private MyGui gui;
// constructor gets passed a reference to the valid displayed GUI
public MyDataBase(MyGui gui) {
this.gui = gui;
}
public void someDataBaseMethod() {
// get database information
// now you can call methods on the actual displayed GUI
// but on the Swing event thread only. The SwingUtilities.invokeLater
// with the Runnable is required to be sure that you don't mess up
// Swing's threading model.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// this method below is being called on the
// displayed MyGui instance.
gui.updateGuiWithInformation(....); // some update method of the GUI
}
});
}
The key -- don't create a new GUI instance inside of the database code.
OK, you've changed your code and now have a constructor that looks like so:
public OracelThinconnection(MainMenu menu) {
// ....
}
Now you need to look at the line that the error is pointing to, MainMenu.java:1438, line 1438 (1438????) of the MainMenu class. On that line you likely call the OracelThinconnection constructor but are not passing the current MainMenu instance into it. The new constructor will accept a MainMenu reference, but when you call the constructor, you now have to remember to pass that reference in to the constructor.
Specifically, change it from
// not sure what you name the variable below
// but I just gave it thinConnection for now.
OracelThinconnection thinConnection = new OracelThinconnection();
to this:
OracelThinconnection thinConnection = new OracelThinconnection(this);
or if this doesn't work, then
OracelThinconnection thinConnection = new OracelThinconnection(MainMenu.this);
As an addendum, your code obviously has more than 1400 lines which tells you that you've got some huge God class that tries to do any thing and everything. I strongly urge you to refactor this code, to make smaller classes, each with their own sphere of responsibilities, else you will not be able to debug or enhance this program.
I'm new into Java... and I've got this idea of building a scientific calculator and after I implemented some of the actionListeners I've got the following error.
Exception in thread "main" java.lang.StackOverflowError
at java.awt.Insets.(Insets.java:103)
at sun.awt.windows.WToolkit.getScreenInsets(Native Method)
at sun.awt.windows.WToolkit.getScreenInsets(WToolkit.java:567)
at java.awt.Window.init(Window.java:498)
at java.awt.Window.(Window.java:536)
at java.awt.Frame.(Frame.java:420)
at javax.swing.JFrame.(JFrame.java:224)
at GUI.(GUI.java:29)
at actionListeners.(actionListeners.java:9)
at GUI.(GUI.java:9)
at actionListeners.(actionListeners.java:9)
at GUI.(GUI.java:9)
at actionListeners.(actionListeners.java:9)
at GUI.(GUI.java:9)
at actionListeners.(actionListeners.java:9)
at GUI.(GUI.java:9)
at actionListeners.(actionListeners.java:9)
and this error keeps showing alot . What could be the problem ?
Here is the code
public GUI() {
super("Calculator");
setLayout(new GridLayout(5,2));
result = new JTextArea();
result.setEditable(false);
add(result);
divide.addActionListener(actionListeners);
add(divide);
multiply.addActionListener(actionListeners);
add(multiply);
substract.addActionListener(actionListeners);
add(substract);
sum.addActionListener(actionListeners);
add(sum);
for(int i=0;i<=numberButtons.length-1;i++)
{
numberButtons[i]= new JButton(Integer.toString(i));}
add(numberButtons[7]);
add(numberButtons[8]);
add(numberButtons[9]);
add(C);
add(CE);
add(numberButtons[4]);
add(numberButtons[5]);
add(numberButtons[6]);
add(sqrt);
add(cubic);
add(numberButtons[1]);
add(numberButtons[2]);
add(numberButtons[3]);
add(percentage);
add(divideByOne);
add(numberButtons[0]);
add(point);
add(square);
add(OK);
}
public void setTextResult(String a) {
result.setText(a);
}
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.naming.spi.DirStateFactory.Result;
public class actionListeners implements ActionListener {
Functions fn = new Functions();
GUI go = new GUI();
public void actionPerformed(ActionEvent e) {
String x = e.getActionCommand();
switch (x) {
case "/":
fn.divide(fn.getA(), fn.getB());
go.setTextResult(Double.toString(fn.getResult()));
break;
case "*":
fn.multiply(fn.getA(), fn.getB());
break;
case "-":
fn.substract(fn.getA(), fn.getB());
break;
case "+":
fn.sum(fn.getA(), fn.getB());
break;
case "+-":
fn.divide(fn.getA(), fn.getB());
break;
case "C":
go.setTextResult(" ");
break;
case "CE":
go.setTextResult(" ");
fn.setResult(0);
break;
case "sqrt":
fn.sqrt(fn.getA());
break;
case "OK":
go.setTextResult(Double.toString(fn.getResult()));
break;
case "SQRT":
break;
case "%":
break;
case "x^2":
break;
case "x^3":
break;
case "1/x":
break;
default:
go.setTextResult("Eroare");
break;
}
}
}
You havent presented your complete code but you appear to have a cyclic dependency between the GUI and actionListeners classes. Each one requires the other to be instantiated resulting in the stacktrace as shown. Just create the required instance of actionListeners in GUI but not the other way around.
Suggestion:
Consider using an Action for shared functionality between buttons
first of all what is your java version you are using strings in switch statement.It is implemented in java 7 and in your code addActionListener(actionListeners) you have to pass the object of ActionListener object.check those two..