This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am trying to write a simple program to listen to clipboard copys and save them.
I wrote the following code:
package CopyPaste;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args){
JFrame frame = new JFrame("Copy Paste");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,600);
frame.setLocationRelativeTo(null);
MyPanel pane = new MyPanel();
frame.add(pane);
frame.setVisible(true);
}
}
package CopyPaste;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.TextArea;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.FlavorEvent;
import java.awt.datatransfer.FlavorListener;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.lang.Object;
import javax.swing.JButton;
import javax.swing.JPanel;
public class MyPanel extends JPanel implements ClipboardOwner{
private final static Font f = new Font("david", Font.BOLD,22);
private static TextArea text;
private JButton btnGet;
private Clipboard c;
public MyPanel(){
this.setLayout(new BorderLayout());
text = new TextArea();
text.setFont(f);
add(BorderLayout.CENTER,text);
add(BorderLayout.SOUTH,this.getSouthButton());
c.addFlavorListener(new FlavorListener() {
#Override
public void flavorsChanged(FlavorEvent e) {
proccessClipboard(c);
}
});
}
private static void proccessClipboard(Clipboard c){
String s = null;
c = Toolkit.getDefaultToolkit().getSystemClipboard();
try {
s = (String) c.getContents(null).getTransferData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException | IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
text.setText(s);
}
//return the south panel button
private JPanel getSouthButton(){
JPanel south = new JPanel();
btnGet = new JButton("Get");
ButtonLis lis = new ButtonLis();
btnGet.addActionListener(lis);
south.add(btnGet);
return south;
}
private class ButtonLis implements ActionListener{
public void actionPerformed(ActionEvent e) {
String s = null;
if (e.getSource()==btnGet){
c = Toolkit.getDefaultToolkit().getSystemClipboard();
try {
s = (String) c.getContents(null).getTransferData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException | IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
text.setText(s);
}
}
}
#Override
public void lostOwnership(Clipboard clipboard, Transferable contents) {
// TODO Auto-generated method stub
}
}
error:
Exception in thread "main" java.lang.NullPointerException
at CopyPaste.MyPanel.<init>(MyPanel.java:39)
at CopyPaste.Main.main(Main.java:13)
for some reason the eclipse don't show any errors but when i hit the "run" button i get some compile error.
someone know what can cause this?
This is an old post, but I am going to answer it for other people who search same thing. The right way is to initialize the Clipboard before define the FlavourListener. So "MyPanel" constructor has to be updated right this:
public MyPanel(){
this.setLayout(new BorderLayout());
text = new TextArea();
text.setFont(f);
add(BorderLayout.CENTER,text);
add(BorderLayout.SOUTH,this.getSouthButton());
c = Toolkit.getDefaultToolkit().getSystemClipboard();
c.addFlavorListener(new FlavorListener() {
#Override
public void flavorsChanged(FlavorEvent e) {
proccessClipboard(c);
}
});
}
Your error is occurring at line 39 of your Panel class as this line from your error message is telling you:
at CopyPaste.MyPanel.<init>(MyPanel.java:39)
Which is this line:
c.addFlavorListener(new FlavorListener() {
So, your clipboard variable, c, is null when you try to add a FlavorListener to it, and it must be initialized before you try to use it.
Related
Allright here is the error: java.awt.dnd.InvalidDnDOperationException: The operation requested cannot be performed by the DnD system since it is not in the appropriate state. The error appears when I drop some File inside the program (grabbed from the desktop). I am using Ubuntu 16.04 with Nautilus.
import javax.swing.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.*;
import java.io.File;
import java.util.List;
class UI extends JFrame {
List<File> droppedFiles;
UI(){
super("My Program");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(null);
this.setVisible(true);
this.setResizable(true);
this.setSize(800, 500);
this.setExtendedState(MAXIMIZED_BOTH);
JTextField dropArea = getDropArea();
this.add(dropArea);
}
private JTextField getDropArea(){
JTextField dropArea = new JTextField("Drop file here");
dropArea.setBounds(50, 50, 200, 200);
dropArea.setDropTarget(createNewDropTarget(dropArea));
return dropArea;
}
private DropTarget createNewDropTarget(JTextField dropArea) {
DropTarget dt = new DropTarget(){
#Override
public synchronized void drop(DropTargetDropEvent dtde) {
super.drop(dtde);
try {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
droppedFiles = (List<File>) dtde.getTransferable().
getTransferData(DataFlavor.javaFileListFlavor);
dropArea.setText(droppedFiles.get(0).getName());
}catch (Exception e){
e.printStackTrace();
}
}
};
return dt;
}
}
The Error appears on the line where droppedFiles is initialized. (in the try catch block).
In a way you set up DropTarget there is no need to call super.drop(dtde);. This is actually the reason for the exception. Here is the implementation of DropTarget.drop():
public synchronized void drop(DropTargetDropEvent dtde) {
clearAutoscroll();
if (dtListener != null && active)
dtListener.drop(dtde);
else { // we should'nt get here ...
dtde.rejectDrop();
}
}
Since you are not initializing DropTarget with a listener the drop is rejected, and the subsequent call getTransferable() fails with InvalidDnDOperationException. If you comment super.drop(dtde); the problem should go away. A cleaner alternative would be to create a listener and pass it to DropTarget. Here is a small example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class DDTest extends JPanel {
public DDTest() {
setLayout(new BorderLayout());
final JTextField dropArea = new JTextField("Drop file here");
add(dropArea);
new DropTarget(dropArea, new DropTargetAdapter() {
#Override
public void drop(DropTargetDropEvent dtde) {
try {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
List<File> droppedFiles = (List<File>) dtde
.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
dropArea.setText(droppedFiles.get(0).getName());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
private static void createAndShowGUI() {
final JFrame frame = new JFrame("DDTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DDTest());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
PS:
Note that using absolute layout can be complex and usually can be avoided. See A Visual Guide to Layout Managers for some ideas.
as title says, I need to change the font size of the menu bar and every item on it (and also the items of the ite,s) using SWING.
I have the following code which works but not on runtime, I need it to be when clicking on a menu item
Font f = new Font("sans-serif", Font.PLAIN, 12);
UIManager.put("Menu.font", f);
UIManager.put("MenuItem.font", f);
And the code I have for my menu is
private class foo{
private JMenu mnArchivo;
private JMenuBar menuBar;
menuBar = new JMenuBar();
frmAdministracinHospital.setJMenuBar(menuBar);
JRadioButtonMenuItem rdbtnmntmGrande = new JRadioButtonMenuItem("Grande");
rdbtnmntmGrande.addActionListener(new MiGrandeActionListener());
rdbtnmntmGrande.setIcon(new ImageIcon(PrincipalWindow.class.getResource("/presentacion/fontbig.png")));
buttonGroup.add(rdbtnmntmGrande);
mnTamanoFuente.add(rdbtnmntmGrande);
private class MiGrandeActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Font f = new Font(menuBar.getFont().getFontName(), menuBar.getFont().getStyle(), 12);
UIManager.put("Menu.font", f);
}
}
I haven't found any similar question which does it on run time, how could I achieve this?
EDIT. CODE ADD WITH NO WORKING THE FONT SIZE CHANGE MORE THAN ONCE.
package presentacion;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import dominio.Appointment;
import dominio.Patient;
import dominio.Specialist;
public class pepe {
private JFrame a;
private JTabbedPane tabbedPane;
private JMenuBar menuBar;
private final ButtonGroup buttonGroup = new ButtonGroup();
public pepe() {
initialize();
a.setVisible(true);
}
public static void main(String[] args) {
try {
// Set System L&F
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}
catch (UnsupportedLookAndFeelException e) {
// handle exception
}
catch (ClassNotFoundException e) {
// handle exception
}
catch (InstantiationException e) {
// handle exception
}
catch (IllegalAccessException e) {
// handle exception
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
pepe window = new pepe();
window.a.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void initialize() {
a = new JFrame();
a.setTitle("Administraci\u00F3n Hospital");
a.setBounds(100, 100, 1195, 710);
a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setBackground(SystemColor.info);
menuBar = new JMenuBar();
a.setJMenuBar(menuBar);
JMenu mnVer = new JMenu("Ver");
menuBar.add(mnVer);
JMenu mnTamanoFuente = new JMenu("Tama\u00F1o fuente");
mnVer.add(mnTamanoFuente);
JRadioButtonMenuItem rdbtnmntmPequeo = new JRadioButtonMenuItem("Peque\u00F1o");
rdbtnmntmPequeo.addActionListener(new MiPequenaActionListener());
buttonGroup.add(rdbtnmntmPequeo);
mnTamanoFuente.add(rdbtnmntmPequeo);
JRadioButtonMenuItem rdbtnmntmGrande = new JRadioButtonMenuItem("Grande");
rdbtnmntmGrande.addActionListener(new MiGrandeActionListener());
buttonGroup.add(rdbtnmntmGrande);
mnTamanoFuente.add(rdbtnmntmGrande);
}
private class MiPequenaActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Font f = new Font(a.getFont().getFontName(), a.getFont().getStyle(), 10);
UIManager.put("Label.font", f);
UIManager.put("Menu.font", f);
UIManager.put("MenuItem.font", f);
SwingUtilities.updateComponentTreeUI(a);
}
}
private class MiGrandeActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Font f = new Font(a.getFont().getFontName(), a.getFont().getStyle(), 13);
UIManager.put("Label.font", f);
UIManager.put("Menu.font", f);
UIManager.put("MenuItem.font", f);
SwingUtilities.updateComponentTreeUI(a);
}
}
}
With this it lets me change the font size just once, to big for example (grande) if then I click on small or normal it wont do anything.
Thank you.
I have the following code which works but not on runtime,
Font f = new Font(menuBar.getFont().getFontName(), menuBar.getFont().getStyle(), 12);
UIManager.put("Menu.font", f);
Basically you need to do a LAF change, so the above should be:
Font f = new FontUIResource(menuBar.getFont().getFontName(), menuBar.getFont().getStyle(), 12);
UIManager.put("Menu.font", f);
SwingUtilities.updateComponentTreeUI(frame);
You need to make sure the Font is a FontUIResource so the LAF can change the property.
Read the section from the Swing tutorial on Changing the LAF After Startup for more information and examples.
I'm working on this project and I need it run as an applet and an application. This is what I have but I stuck on where to go because I can't find anything on the internet. Are there any resources or does someone have some quick advice to give me?
public class Project extends JApplet {
public void init() {
try {
URL pictureURL = new URL(getDocumentBase(), "sample.jpg");
myPicture = ImageIO.read(pictureURL);
myIcon = new ImageIcon(myPicture);
myLabel = new JLabel(myIcon);
} catch (Exception e) {
e.printStackTrace();
}
add(label, BorderLayout.NORTH);
add(bio);
add(bio, BorderLayout.CENTER);
pane.add(play);
getContentPane().add(pane, BorderLayout.SOUTH);
play.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
FileInputStream FIS = new FileInputStream("sample.mp3");
player = new Player (FIS);
player.play();
} catch (Exception e1) {
e1.printStackTrace();
}}});
}
public static void main(String args[]) {
JFrame frame = new JFrame("");
frame.getContentPane().add();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}
private JPanel pane = new JPanel();
private TextArea bio = new TextArea("Bio");
private JButton play = new JButton("Play");
private Image myPicture;
private ImageIcon icon;
private JLabel label;
private Player player;
}
When trying to run something as an applet and as an application, there are several caveats.
Applets have a certain life cycle that must be obeyed. One can add the applet to the content pane of the JFrame and manually call init(), but in general, if the applet expects its start() or stop() methods to be called, things may become tricky...
More importantly: The way how resources are handled is different between applets and applications.
Handling files in applets (e.g. with a FileInputStream) may have security implications, and will plainly not work in some cases - e.g. when the applet is embedded into a website. (Also see What Applets Can and Cannot Do).
Conversely, when running this as an application, calling getDocumentBase() does not make sense. There simply is no "document base" for an application.
Nevertheless, it is possible to write a program that can be shown as an Applet or as an Application. The main difference will then be whether the main JPanel is placed into a JApplet or into a JFrame, and how data is read.
One approach for reading data that works for applets as well as for applications is via getClass().getResourceAsStream("file.txt"), given that the respective file is in the class path.
I hesitated a while, whether I should post an example, targeting the main question, or whether I should modify your code so that it works. I'll do both:
Here is an example that can be executed as an Applet or as an Application. It will read and display a "sample.jpg". (This file is currently basically expected to be "in the same directory as the .class-file". More details about resource handling, classpaths and stream handling are beyond the scope of this answer)
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class AppletOrApplicationExample extends JApplet
{
#Override
public void init()
{
add(new AppletOrApplicationMainComponent());
}
public static void main(String args[])
{
JFrame frame = new JFrame("");
frame.getContentPane().add(new AppletOrApplicationMainComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
class AppletOrApplicationMainComponent extends JPanel
{
public AppletOrApplicationMainComponent()
{
super(new BorderLayout());
InputStream stream = getClass().getResourceAsStream("sample.jpg");
if (stream == null)
{
add(new JLabel("Resource not found"), BorderLayout.NORTH);
}
else
{
try
{
BufferedImage image = ImageIO.read(stream);
add(new JLabel(new ImageIcon(image)), BorderLayout.NORTH);
}
catch (IOException e1)
{
add(new JLabel("Could not load image"), BorderLayout.NORTH);
}
}
JTextArea textArea = new JTextArea("Text...");
add(textArea, BorderLayout.CENTER);
JButton button = new JButton("Button");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
doSomething();
}
});
add(button, BorderLayout.SOUTH);
}
private void doSomething()
{
System.out.println("Button was clicked");
}
}
And here is something that is still a bit closer to your original code. However, I'd strongly recommend to factor out the actual application logic as far as possible. For example, your main GUI component should then not be the applet itself, but a JPanel. Resources should not be read directly via FileInputStreams or URLs from the document base, but only from InputStreams. This is basically the code that you posted, with the fewest modifications that are necessary to get it running as an applet or an application:
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Module5Assignment2 extends JApplet
{
public void init()
{
try
{
InputStream stream = getClass().getResourceAsStream("sample.jpg");
if (stream == null)
{
System.out.println("Resource not found");
}
else
{
myPicture = ImageIO.read(stream);
icon = new ImageIcon(myPicture);
label = new JLabel(icon);
add(label, BorderLayout.NORTH);
}
}
catch (Exception e)
{
e.printStackTrace();
}
add(bio);
add(bio, BorderLayout.CENTER);
pane.add(play);
getContentPane().add(pane, BorderLayout.SOUTH);
play.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
FileInputStream FIS = new FileInputStream("sample.mp3");
// player = new Player (FIS);
// player.play();
}
catch (Exception e1)
{
e1.printStackTrace();
}
}
});
}
public static void main(String args[])
{
JFrame frame = new JFrame("");
// ******PRETTY SURE I NEED TO ADD SOMETHING HERE*************
Module5Assignment2 contents = new Module5Assignment2();
frame.getContentPane().add(contents);
contents.init();
// *************************************************************
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}
private JPanel pane = new JPanel();
private TextArea bio = new TextArea(
"This is the bio of Christian Sprague; he doesn't like typing things.");
private JButton play = new JButton("Play");
private Image myPicture;
private ImageIcon icon;
private JLabel label;
// private Player player;
}
i am making a text editor, and this is the basic version of my code. I used UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); to make the whole thing look like the platform I am using, but the JFileChooser save is always the java look and feel. Can anybody help? I might be putting it in the wrong spot, but I don't know where
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
#SuppressWarnings("serial")
public class TextEditor extends JPanel {
static Container pane;
static Container paneText;
static BasicFrame frame;
static JTextArea textArea;
static JScrollPane areaScrollPane;
static FileFilter txtFile;
static JFileChooser save = new FileChooser(System.getProperty("user.home//documents"));
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException, IOException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
frame = BasicFrame.getInstance();
pane = frame.getContentPane();
paneText = new JPanel();
textArea = new JTextArea();
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
areaScrollPane = new JScrollPane(textArea);
areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(250, 250));
int hGap = 10;
int vGap = 20;
pane.setLayout(new FlowLayout(FlowLayout.LEFT, hGap, vGap));
Action SaveAs = new SaveAs("Save File", "Writes the text file");
JButton one = new JButton(SaveAs);
one.addActionListener(null);
txtFile = new FileNameExtensionFilter("Text File (.txt)", "txt");
save.addChoosableFileFilter(txtFile);
save.setFileFilter(txtFile);
save.setAcceptAllFileFilterUsed(true);
pane.add(areaScrollPane);
pane.add(one);
pane.add(paneText);
paneText.setLayout(new BoxLayout(paneText, BoxLayout.Y_AXIS));
frame.setSize(450, 320);
frame.setVisible(true);
}
static class SaveAs extends AbstractAction {
public SaveAs(String text, String desc) {
super(text);
putValue(SHORT_DESCRIPTION, desc);
}
public void actionPerformed(ActionEvent e) {
save.setFileHidingEnabled(false);
save.setApproveButtonText("Save");
save.setSelectedFile(new File("new 1"));
int actionDialog = save.showSaveDialog(null);
if (actionDialog != JFileChooser.APPROVE_OPTION) {
return;
} else {
log("Done!", true);
}
String name = save.getSelectedFile().getAbsolutePath();
if (!name.endsWith(".txt") && save.getFileFilter() == txtFile) {
name += ".txt";
}
BufferedWriter outFile = null;
try {
outFile = new BufferedWriter(new FileWriter(name));
textArea.write(outFile);
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (outFile != null) {
try {
outFile.close();
} catch (IOException ioee) {
}
}
}
}
private void log(String msg, boolean remove) {
JLabel label1;
label1 = new JLabel(msg);
if (remove) {
paneText.removeAll();
}
paneText.add(label1);
paneText.validate();
pane.validate();
new Thread() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
paneText.removeAll();
paneText.validate();
pane.validate();
}
}.start();
}
}
}
The JFileChooser in your code is static and therefore is instantiated before the Look and Feel is set in main.
Set the Look and Feel before instantiation. So, both in a static block since your JFileChooser is static.
...
static FileFilter txtFile;
static JFileChooser save;
static {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (ClassNotFoundException |
InstantiationException |
IllegalAccessException |
UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
save = new JFileChooser(System.getProperty("user.home//documents"));
}
public static void main(String[] args) {
frame = new JFrame();
pane = frame.getContentPane();
...
...
Instead of System.getProperty("user.home//documents"), type (System.getProperty("user.home") + "/documents") (Assuming your documents folder is called "documents"). The former would return null, setting the JFileChooser's location to its default -- the user's home directory.
This is because "user.home//documents" is not a defined key for System.getProperty(), while "user.home" is.
You should also set your JFileChooser to a new JFileChooser(<path>) rather than a new FileChooser(<path>)
The LookAndFeel declaration must be made before the initialization of the Object, otherwise the object won't take on those LookAndFeel properties.
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
THEN
save = new FileChooser(System.getProperty("user.home//documents"));
I tried to write a simple test program using Swing, all I want to do is load a text file and display the path of the chosen text file in a text area. I keep getting a warning on the process method "never used locally" and it is not appending any text to the textbox. Maybe I'm misunderstanding something, I hope someone can help me.
code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MyPanel3 extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextArea jcomp;
private JButton btn;
private String testfile;
public MyPanel3() {
//construct components
jcomp = new JTextArea (1, 1);
jcomp.setBorder(BorderFactory.createDashedBorder(Color.BLACK));
btn = new JButton ("open");
//adjust size and set layout
setPreferredSize (new Dimension (944, 575));
BoxLayout layout = new BoxLayout (this, BoxLayout.Y_AXIS);
setLayout(layout);
//add main components
add (jcomp);
add (btn);
new SwingWorker<Void, String>(){
protected Void doInBackground(){
//do processes...
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
final JFileChooser chooseFile = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt","txt");
chooseFile.setFileFilter(filter);
chooseFile.setAcceptAllFileFilterUsed(false);
chooseFile.setMultiSelectionEnabled(true);
if(ae.getSource().equals(btn))
{
System.out.println("do in background running");
int returnVal = chooseFile.showOpenDialog(MyPanel3.this);
if(returnVal == JFileChooser.APPROVE_OPTION)
{
File[] files = chooseFile.getSelectedFiles();
testfile = files[0].getPath();
publish(testfile);
}
}
}
});
return null;
}
protected void process(String s) {
jcomp.append(s);
}
protected void done() {
try
{
//System.out.println("The operation was completed");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}.execute();
}
public static void main(String[] args){
JFrame frame = new JFrame ("MyTest");
frame.getContentPane();
frame.add(new MyPanel3());
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible (true);
}
}
warning reads:
The method process(String) from the type new
SwingWorker(){} is never used locally
EDIT:
with help from MadProgrammer, program is now working (selecting 3 files and printing the paths as strings in the text box)
import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MyPanel4 extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextArea jcomp;
private JButton btn;
public MyPanel4() {
//construct components
jcomp = new JTextArea(1, 1);
jcomp.setBorder(BorderFactory.createDashedBorder(Color.BLACK));
btn = new JButton("open");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
final JFileChooser chooseFile = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
chooseFile.setFileFilter(filter);
chooseFile.setAcceptAllFileFilterUsed(false);
chooseFile.setMultiSelectionEnabled(true);
int returnVal = chooseFile.showOpenDialog(MyPanel4.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
final File[] files = chooseFile.getSelectedFiles();
new SwingWorker<Void, String>() {
private String testfile1 = files[0].getPath();
private String testfile2 = files[1].getPath();
private String testfile3 = files[2].getPath();
protected Void doInBackground() {
List<String> b = new ArrayList<String>();
b.add(testfile1);
b.add(testfile2);
b.add(testfile3);
publish(b.get(0));
publish(b.get(1));
publish(b.get(2));
return null;
}
#Override
protected void process(List<String> chunks) {
for (String pathname : chunks)
{
jcomp.append(pathname + "\n");
}
}
protected void done() {
try
{
System.out.println("Opration Completed");
} catch (Exception e) {
e.printStackTrace();
}
}
}.execute();
}
}
});
//adjust size and set layout
setPreferredSize(new Dimension(944, 575));
BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
setLayout(layout);
//add main components
add(jcomp);
add(btn);
}
public static void main(String[] args) {
JFrame frame = new JFrame("MyTest");
frame.getContentPane();
frame.add(new MyPanel4());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
The SwingWorker should be created inside the buttons actionPerformed method, so that when you click the button, it will run the SwingWorker
You should, also, make sure that all interactions with user interface are fine from within the context of the Event Dispatching Thread. This means you should ask the user to select the file fro within the context of the actionPerformed method and pass the result to the SwingWorked
Updated
Two additional things...
You're not actually reading the file, but simply passing the name of the file to the publish method
SwingWorker defines process as protected void process(List<V> chunks) but you've defined it as protected void process(String s)...mean that you are actually not overriding the SwingWorker's process method, but creating your own...
Take a look at this example to see how you might be able to use a SwingWorker to read a file...
And, update your process to have the corrected method signature...
#Override
protected void process(List<String> chunks) {
for (String line : chunks) {
output.append(line);
}
}
Remember, you should, as much as possible, use the #Override annotation when you think you are overriding a method, the compiler will tell you when you are mistaken, saving you a lot of head scratching...
It should be like this:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MyPanel3 extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextArea jcomp;
private JButton btn;
private String testfile;
public MyPanel3() {
//construct components
jcomp = new JTextArea(1, 1);
jcomp.setBorder(BorderFactory.createDashedBorder(Color.BLACK));
btn = new JButton("open");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
final JFileChooser chooseFile = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
chooseFile.setFileFilter(filter);
chooseFile.setAcceptAllFileFilterUsed(false);
chooseFile.setMultiSelectionEnabled(true);
int returnVal = chooseFile.showOpenDialog(MyPanel3.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File[] files = chooseFile.getSelectedFiles();
testfile = files[0].getPath();
new SwingWorker<Void, String>() {
protected Void doInBackground() {
publish(testfile);
return null;
}
protected void process(String s) {
jcomp.append(s);
}
protected void done() {
try {
//System.out.println("The operation was completed");
} catch (Exception e) {
e.printStackTrace();
}
}
}.execute();
}
}
});
//adjust size and set layout
setPreferredSize(new Dimension(944, 575));
BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
setLayout(layout);
//add main components
add(jcomp);
add(btn);
}
public static void main(String[] args) {
JFrame frame = new JFrame("MyTest");
frame.getContentPane();
frame.add(new MyPanel3());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
You are running worker when you are creating panel. But you should run it when button is clicked.