Drag and Drop file path to Java Swing JTextField - java

Using this question, I created the class below, which handles drag and drop of files to a JTextField. The point of the application is to be able to drag a file into the text field, and have the text field's text set to the file's path (you can see the goal in the code pretty clearly).
My problem is the below code does not compile. The compilation error states Cannot refer to non-final variable myPanel inside an inner class defined in a different method. I haven't worked much with inner classes, so can seomeone show me how to resolve the error and get the code to behave as designed?
Code:
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.util.List;
import javax.swing.*;
public class Test {
public static void main(String[] args) {
JTextArea myPanel = new JTextArea();
myPanel.setDropTarget(new DropTarget() {
public synchronized void drop(DropTargetDropEvent evt) {
try {
evt.acceptDrop(DnDConstants.ACTION_COPY);
List<File> droppedFiles = (List<File>) evt
.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
for (File file : droppedFiles) {
/*
* NOTE:
* When I change this to a println,
* it prints the correct path
*/
myPanel.setText(file.getAbsolutePath());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
JFrame frame = new JFrame();
frame.add(myPanel);
frame.setVisible(true);
}
}

As the error message says, myPanel needs to be defined as final.
final JTextArea myPanel = new JTextArea();
This way the inner class can be given one reference pointer to the variable instance without concern that the variable might be changed to point to something else later during execution.

Another option is to declare the variable static.
static JTextArea myPanel = new JTextArea();

Related

Why don't two files get made if I run the program twice?

I have a program that makes a file. I assume that if I run that program twice, I will get two of the same files? Or will one file just override the other? I made some code that says if the file already exists(If I already ran the program once) than to display a window saying that. But, for some reason, the code is always successful in making the new file?
package Files;
import java.awt.Font;
import java.io.File; //The file class gives info about files, ex: length, existence, etc. (filename.exists();)
import java.util.*;
import javax.swing.*;
public class Myfirstfileclass {
public static void main(String[] args) {
File myfile = new File("C:\\creationfiles\\jfklda.txt"); //Always use two backslashes, because one backslash escapes a swing, it interprets two as one though.
if (! myfile.exists()) {
newwindowsinceexists object = new newwindowsinceexists();
final Formatter myformatter;
try{ //Saying try this, if it gets an error then go over to catch.
myformatter = new Formatter("Imadethisfileforyou.txt");
System.out.println("It should have worked!");
// This is the same as just making it all in one line, and writing:
//final Formatter myformatter = new Formatter("Imadethisfileforyou.txt");
}
catch(Exception e){ //Execption is a fancy word for error
Error error = new Error(); //Opens window saying you got an error
}
}
if (myfile.exists()){
alreadyexists existenceobj = new alreadyexists();
}
}
}
class alreadyexists extends JFrame{
public alreadyexists(){
super ("Did you run this program more than once?");
JLabel didyou = new JLabel("Did you run this program more than once?");
add(didyou);
setVisible(true);
setSize(getMaximumSize());
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
}
class newwindowsinceexists extends JFrame {
public newwindowsinceexists() {
super("I will create a new file for you!");
JLabel text = new JLabel("I will create you a new file");
text.setFont(new Font("Courier New", Font.ITALIC, 30));
add(text);
setSize(getMaximumSize());
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
}
}
class Error extends JFrame{
public Error(){
super("Sorry, there's an error!");
JLabel labelerror = new JLabel("There is an error, I am sorry");
labelerror.setFont(new Font("Courier New", Font.ITALIC, 30));
add(labelerror);
setSize(250, 250);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
}
}
Does it override the file that has been created, and how can I stop that and make class alreadyexists run if it already has been created? Thank you for the time you are taking for reading this, I really appreciate the effort you are putting into helping a fellow programmer.

contents of textarea to the printer

I am able to easily print the contents of a JTable mainly through using the statement below. However, this does not work for printing the contents of a textarea component. Is there a simple way of printing the contents of a textarea component? I've seen some pretty confusing examples on the web that use multiple classes. But I'm trying to find a simpler way of doing this.
I ADDED THE SECOND AREA OF CODE ABOUT 24 HOURS AFTER THE ORIGINAL POST. NOTE THAT IT SEEMS TO BE PROMISING BUT PRODUCES THE ERROR "ADD ARGUMENT TO MATCH PRINT(GRAPHICS)". HOW CAN THAT CODE BE FIXED?
table.print(JTable.PrintMode.NORMAL, header, footer);
JButton btnNewButton_7 = new JButton("Print");
btnNewButton_7.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
try{
boolean complete = textArea_2.print();
//The above line reads the error "Add argument to match print(Graphics)"
if(complete){
JOptionPane.showMessageDialog(null, "Printjob Finished", "Report",
JOptionPane.INFORMATION_MESSAGE);
}else{
JOptionPane.showMessageDialog(null, "Printing", "Printer", JOptionPane.ERROR_MESSAGE);
}
}catch(PrinterException e){JOptionPane.showMessageDialog(null, e);
}
}
});
Google and the JavaDocs are your friend
JTextArea#print
A convenience print method that displays a print dialog, and then
prints this JTextComponent in interactive mode with no header or
footer text. Note: this method blocks until printing is done. Note: In
headless mode, no dialogs will be shown.
This method calls the full featured print method to perform
printing.
Returns: true, unless printing is canceled by the user
JTextArea#print(MessageFormat headerFormat, MessageFormat footerFormat)
A convenience print method that displays a print dialog, and then
prints this JTextComponent in interactive mode with the specified
header and footer text. Note: this method blocks until printing is
done. Note: In headless mode, no dialogs will be shown.
This method calls the full featured print method to perform printing.
Parameters: headerFormat - the text, in MessageFormat, to be used as
the header, or null for no header footerFormat - the text, in
MessageFormat, to be used as the footer, or null for no footer
Returns: true, unless printing is canceled by the user
JTextArea#print(MessageFormat headerFormat, MessageFormat footerFormat, boolean showPrintDialog, PrintService service, PrintRequestAttributeSet attributes, boolean interactive) throws PrinterException
...You can look that one yourself, it's to long to post...
JTextArea#getPrintable(MessageFormat headerFormat, MessageFormat footerFormat)
Returns a Printable to use for printing the content of this
JTextComponent. The returned Printable prints the document as it looks
on the screen except being reformatted to fit the paper. The returned
Printable can be wrapped inside another Printable in order to create
complex reports and documents. The returned Printable shares the
document with this JTextComponent. It is the responsibility of the
developer to ensure that the document is not mutated while this
Printable is used. Printing behavior is undefined when the document is
mutated during printing.
Page header and footer text can be added to the output by providing
MessageFormat arguments. The printing code requests Strings from the
formats, providing a single item which may be included in the
formatted string: an Integer representing the current page number.
The returned Printable when printed, formats the document content
appropriately for the page size. For correct line wrapping the
imageable width of all pages must be the same. See
PageFormat.getImageableWidth().
This method is thread-safe, although most Swing methods are not.
Please see How to Use Threads for more information.
The returned Printable can be printed on any thread.
This implementation returned Printable performs all painting on the
Event Dispatch Thread, regardless of what thread it is used on.
Parameters: headerFormat - the text, in MessageFormat, to be used as
the header, or null for no header footerFormat - the text, in
MessageFormat, to be used as the footer, or null for no footer
Returns: a Printable for use in printing content of this
JTextComponent
Works just fine for me...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PrinterException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestPrint {
public static void main(String[] args) {
new TestPrint();
}
public TestPrint() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JTextArea ta = new JTextArea(20, 100);
try (FileReader reader = new FileReader(new File("C:/Script.txt"))) {
ta.read(reader, ta);
} catch (IOException ex) {
ex.printStackTrace();
}
JButton print = new JButton("Print");
print.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
MessageFormat header = new MessageFormat("Star Wars IV A new Hope");
MessageFormat footer = new MessageFormat("Page {0}");
try {
ta.print(header, footer);
} catch (PrinterException ex) {
ex.printStackTrace();
}
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(ta));
frame.add(print, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

Java Formatter append method within anon ActionListener

Sorry in advance if this has been answered elsewhere, i am probably just searching the wrong tags.
I wish to create a log file, of various variables, with the use of an anonymous inner class implementing ActionListener. This will be attached to a JButton.
Using the Formatter, gives me exactly what i require in a line, but i want to keep
all previous logs of this event (I dont care if its before or after the last entry).
After various methods of me hitting a wall I found through some surfing of this site and others you can possibly do this with an append method in a constructor with Formatter.
Is it possible to use append while in an inner class with Formatter?
If not can you suggest another Java writer that will still meet my needs?
I'm still a beginner so the less complicated the better...for now.
If it's possible within the inner class and with formatter without any additional
imports/packages, please give us a hint or a link and i will keep searching.
I have attached a small compilable sample code, that may help if anyone is interested in
having a play.
thanks,
weekendwarrior84
import java.awt.FlowLayout;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Formatter;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class TestProgram extends JFrame{
private FlowLayout lay;
public TestProgram(){
super("Sample Program");
lay = new FlowLayout();
setLayout(lay);
final JLabel label1 = new JLabel("Label One");
add(label1);
final TextField field1 = new TextField(8);
add(field1);
final JLabel label2 = new JLabel("Exception Label");
add(label2);
final JButton button1 = new JButton
("Log Data");
add(button1);
button1.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
if(button1.isSelected());
try{
Formatter fm = new Formatter("C:\\Test\\testlog.txt");
fm.format("%s%s%s%s", "Sample Value: ",label1.getText(),
" Sample Value2: ",field1.getText());
fm.close();
}
catch(Exception ee){
label2.setText("Make Sure Path exists, C:\\Test\\testlog.txt");
}
}
}
);
}
}
Main
import javax.swing.JFrame;
public class TestMain{
public static void main (String[] args){
TestProgram ts = new TestProgram();
ts.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ts.setSize(1200,500);
ts.setVisible(true);
}
}
Is there a specific reason why you want to do this with Formatter? It reads like you want to do some very basic logging, for which there are numerous implementations in Java to do the dirty work for you. Even the java.util.logging package would suffice to append log-lines to a file upon button-click. I'd personally suggest logback, but that's just a preference.
If you do insist on doing the file operations yourself this question's answers might be for you. The formatting can just be done with the MessageFormat-class before writing the complete line to the file.
As Promised, it is still a WIP but it solved my current problem. It was mainly confusion on what was possible with the writers, and the belief i required the formatter.
if(button1.isSelected());
String path = "C:\\Test\\testlog.txt";
String mylog = "\r\n"+"Sample Value: " + label1.getText()+" Sample Value2: "+field1.getText();
File file = new File(path);
FileWriter writer;
try {
writer = new FileWriter(file,true);
BufferedWriter buffer = new BufferedWriter(writer);
writer.append(mylog);
buffer.close();
}catch (IOException e1) {
label2.setText("Make Sure Path exists, C:\\Test\\testlog.txt");

How to show input of JTextField in JLabel ? how to fix error in reflection ?

i have to do this: i have one JTextField and button. And when i write to that TextField output must show result in JLabel.
Asks the user to provide the name of a class.
Uses Class.forName() to get an access to Java Reflection API.
Creates a new instance (i.e. object) of the class using the default constructor.
Finds and displays all fields of the class in the form including inherited fields:
field_type field_name: (field_value(JTextField))(Set(Button))
field_value must be a textbox, so that the user can change the value by pressing ‘Set’ button. The new value must be updated to the object. If the field contains values of complex types (objects, collections etc.) then the textbox and ‘Set’ button should not be created.
Finds and displays all methods of the class including inherited methods:
return_type method_name (param_type1 (param_value1(JTextField)), param_type2(param_value2(JTextField)) , ..) (Invoke(Button))
If a method has parameters of complex types (objects, collections etc.) then only parameters’ types are displayed, param_values’ textboxes and ‘invoke’ button are skipped.
When the user presses “invoke” button, the application must invoke the method. Make sure that if the method alters the fields’ values these changes are displayed.
and my code here:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.StringBuffer;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ReflectionTest {
private String class_name = "java.lang.StringBuffer";
public ReflectionTest() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
JLabel jl1 = null, jl2, jl3, jl4;
JFrame jf = new JFrame("New");
JPanel jp = new JPanel();
JTextField jtf = new JTextField(20);
JButton jb = new JButton("Press");
jtf.setVisible(true);
jp.add(jb);
jp.add(jtf);
jf.add(jp);
jf.setVisible(true);
jf.setSize(400, 550);
jf.setResizable(false);
String text = jtf.getText().toString();
Class cs = Class.forName(text);
jb.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
// THIS CODE IS EXECUTED WHEN RETURN IS TYPED
}
}
);
for(Constructor c: cs.getConstructors()){
for(Class p: c.getParameterTypes())
System.out.print(p.getName()+" ");
System.out.println();
}
Constructor c = cs.getConstructor(new Class[]{String.class});
Object list = c.newInstance("AA");
Field pub_fields[] = cs.getFields();
Field all_fields[] = cs.getDeclaredFields();
System.out.println("Public fields:");
for(Field f:pub_fields){
//Showing public fields
System.out.println();
jl1 = new JLabel(f.getType().getName() + " " + f.getName());
jp.add(jl1);
jl1.setVisible(true);
}
System.out.println("All declared fields:");
for(Field f:all_fields){
//Showing all declared fields
jl2 = new JLabel(f.getType().getName() + " "+f.getName()+" ");
jp.add(jl2);
jl2.setVisible(true);
f.setAccessible(true);
Object val = f.get(list);
if (val != null){
//System.out.println(val.toString());
jl3 = new JLabel(val.toString());
jp.add(jl3);
jl3.setVisible(true);
System.out.println();
}
else{
System.out.println("NULL");
//f.get(list1);
}
}
}
/**
* #param args
* #throws ClassNotFoundException
*/
public static void main(String[] args) {
try{
// TODO Auto-generated method stub
new ReflectionTest();
}
catch (Exception e){
e.printStackTrace();
}
}
}
and i have error. Eclipse show it in this line:
Class cs = Class.forName(text);
If you test the text String before the exception occurs, for instance by printing it out:
System.out.printf("text = \"%s\"%n", text);
Class cs = Class.forName(text);
Which returns:
text = ""
java.lang.ClassNotFoundException:
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at pkg.ReflectionTest.<init>(ReflectionTest.java:42)
at pkg.ReflectionTest.main(ReflectionTest.java:102)
You'll see that the text String is empty, "". This is because you have no text when you call the Class cs = Class.forName(text); since it's being called before the GUI has been rendered, much less give the user time to enter text. Only call this in code that is called due to a user-generated event of some sort such as an ActionListener's actionPerformed method.
In other words, add the critical code to where in your own commment you state you should add the code:
jb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// THIS CODE IS EXECUTED WHEN RETURN IS TYPED // *********!!!!
}
});
And I second the comment that you should show any and all information about the exception. Please don't make us guess what the problem is.
Edit
Also you will have a problem with using local variables, including the JLabels and JTextField, inside of the anonymous inner listener class. The easiest and best way to solve this is to make the variables that need to be accessed in this listener private class fields. So remove their declarations from the constructor and instead move them to the class itself.
Is it really an error or a "yellow" line? Class is a parametized type and if you do not use generics then eclipse will show a warning.
To eliminate such a warning, simply do a
Class<?> cs = Class.forName(text);
The wildcard is ok because you really don't know which "type" of Class you're going to load.

Java Combo Boxes + Image Icons

I'm trying to build a really basic program that will alternate between two pictures depending on which item from a dropdown box is selected. This is the code I'm trying to run, but I keep getting an error saying:
Exception in thread "main" java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(ImageIcon.java:181)
at Gui.<init>(Gui.java:10)
at Apples.main(Apples.java:7)
The images are in the src file.
Does anyone know what I am doing wrong??
Thanks,
Ravin
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Gui extends JFrame{
private JComboBox box;
private JLabel picture;
private static String [] filename = {"Ravinsface.png", "Wojs face.png"};
private Icon[] pics = {new ImageIcon(getClass().getResource(filename[0])), new ImageIcon(getClass().getResource(filename[1]))};
public Gui(){
super("The Title");
setLayout(new FlowLayout());
box = new JComboBox(filename);
box.addItemListener(
new ItemListener(){
public void itemStateChanged(ItemEvent event){
if(event.getStateChange()==ItemEvent.SELECTED);
picture.setIcon(pics[box.getSelectedIndex()]);
}
}
);
add(box);
picture = new JLabel(pics[1]);
add(picture);
}
}
Use getClass().getClassLoader().getResource(String)
/e1 I put an explanation of the different getResource(String) methods on the other answer.
It looks like one (or more) of the arguments you are passing into your ImageIcon constructor are null. This is because the resource is not being found here:
private Icon[] pics = {new ImageIcon(getClass().getResource(filename[0])), new ImageIcon(getClass().getResource(filename[1]))};
Why aren't you just using
new ImageIcon(String filename)
? I'm not 100% sure how getResource works, never having used it.
do this:
you must put your .png
beside your .class files
(in project_name/bin)
then your files path can recognize
then it will works
remember you are using class loader so if you put images beside .class files it will be correct

Categories

Resources