refresh the contents of frame in real time [duplicate] - java

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
When does one need to call revalidate() on a swing component to make it refresh, and when not?
i am making a Explorer program in Java it works as follows
i input the path from the user, a textbox after the user presses enter the path is set and the list is computed of the folder and corresponding labels are created which are supposed to be displayed on the window but the application doesn't display the new contents of the folder, if i change the text then it directs to a new directory so when i press enter then it must show the contents of the new directory loaded but only after resizing the window does it show the new contents of the frame
the code is as follows
package explorer;
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Explorer extends JFrame{
File file;
Scanner scan;
String path;
String [] listOfFiles;
JTextField txtPath;
JLabel lblLocation;
JLabel child[];
JPanel childPanel;
JPanel masterPanel;
public Explorer(){
lblLocation = new JLabel("Location: ");
/*
* the declaration of panels
*/
masterPanel = new JPanel();
childPanel = new JPanel();
JPanel panel = new JPanel();
/*declaration of other components*/
txtPath = new JTextField("",20);
/*addition of components to panel for layout*/
panel.add(lblLocation);
panel.add(txtPath);
/*adding to master panel, for sophisticated layout*/
masterPanel.add(panel, BorderLayout.NORTH);
masterPanel.add(childPanel, BorderLayout.SOUTH);
getContentPane().add(masterPanel);
/*this place from where address is fetched like /home/revolution/Desktop etc on ubuntu*/
txtPath.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
childPanel.removeAll();
path = new String(txtPath.getText());//the absolute path
file = new File(path);
File childFiles[];
String name = path.substring(path.lastIndexOf('/')+1, path.length());//the name of the directory being displayed
setTitle(name);
if(!file.isDirectory()){
JOptionPane.showMessageDialog(null, "Error file is not a directory");
} else {
listOfFiles = file.list();
child = new JLabel[listOfFiles.length];// labels equal to the number fo files and with name of the coresponding file/folder
childFiles = new File[listOfFiles.length];//references to files
childPanel.setLayout(new GridLayout(listOfFiles.length/2,listOfFiles.length/2));//setting grid layout
for(int i=0; i<listOfFiles.length;i++){
childFiles[i] = new File(listOfFiles[i]);
child[i] = new JLabel(listOfFiles[i]);
child[i].setToolTipText(childFiles[i].isFile()?"File":"Folder");
childPanel.add(child[i]);
}
childPanel.setVisible(true);
}
}
});
}
}
what is wrong? how can i 'refresh' the contents of the window??

I think you need to revalidate() the panel.
More precisely at the end of your action listener you can add childPanel.revalidate();
childPanel.setVisible(true);
}
}
childPanel.revalidate();
});

Related

How do I use a gif file in a Java program?

I'm trying to add a .gif image to a JButton, but can't seem to get the image to load when i run the code. I've included a screenshot. Included is the frame that's created. I'd really appreciate any help that can be provided. Stack is telling me I can't enter images yet, so it created a link for it. I'm also going to enclose the actual code here:
package java21days;
import javax.swing.*;
import java.awt.*;
public class ButtonsIcons extends JFrame {
JButton load, save, subscribe, unsubscribe;
public ButtonsIcons() {
super("Icon Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
//Icons
ImageIcon loadIcon = new ImageIcon("load.gif");
ImageIcon saveIcon = new ImageIcon("save.gif");
ImageIcon subscribeIcon = new ImageIcon("subscribe.gif");
ImageIcon unsubscribeIcon = new ImageIcon("unsubscribe.gif");
//Buttons
load = new JButton("Load", loadIcon);
save = new JButton("Save", saveIcon);
subscribe = new JButton("Subscribe", subscribeIcon);
unsubscribe = new JButton("Unsubscribe", unsubscribeIcon);
//Buttons To Panel
panel.add(load);
panel.add(save);
panel.add(subscribe);
panel.add(unsubscribe);
//Panel To A Frame
add(panel);
pack();
setVisible(true);
} //end ButtonsIcon Constructor
public static void main(String[] arguments) {
ButtonsIcons ike = new ButtonsIcons();
}
} //end ButtonsIcon Class
enter image description here
The easiest way is.
Label or Jbutton and what ever else supports HTML 3.5
JLabel a = new JLabel("");
add that to your container.
Haven't figured out how to enter code sorry

How do I make JFileChooser open in the current directory the user is in?

I do not want to specify a directory. I just want it to automatically "know" and open in the directory the user is working in. How do I do this?
This examples defaults to the user.dir on first showing. It then retains the instance of the chooser to automatically track the last load or save location, as suggested by MadProgrammer.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.io.*;
public class ChooserInCurrentDir {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new BorderLayout());
JFileChooser fileChooser;
private JTextArea output = new JTextArea(10, 40);
ChooserInCurrentDir() {
initComponents();
}
public final void initComponents() {
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
String userDirLocation = System.getProperty("user.dir");
File userDir = new File(userDirLocation);
// default to user directory
fileChooser = new JFileChooser(userDir);
Action open = new AbstractAction("Open") {
#Override
public void actionPerformed(ActionEvent e) {
int result = fileChooser.showOpenDialog(gui);
if (result == JFileChooser.APPROVE_OPTION) {
try {
File f = fileChooser.getSelectedFile();
FileReader fr = new FileReader(f);
output.read(fr, f);
fr.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
};
Action save = new AbstractAction("Save") {
#Override
public void actionPerformed(ActionEvent e) {
int result = fileChooser.showSaveDialog(gui);
throw new UnsupportedOperationException("Not supported yet.");
}
};
JToolBar tb = new JToolBar();
gui.add(tb, BorderLayout.PAGE_START);
tb.add(open);
tb.add(save);
output.setWrapStyleWord(true);
output.setLineWrap(true);
gui.add(new JScrollPane(
output,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
}
public final JComponent getGui() {
return gui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
ChooserInCurrentDir cicd = new ChooserInCurrentDir();
JFrame f = new JFrame("Chooser In Current Dir");
f.add(cicd.getGui());
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}
Basically, you can't. You need to tell it.
When constructed with a null currentDirectory (such as the default constructor), it will use FileSystemView#getDefaultDirectory.
You could create a single instance of JFileChooser for each base task (one for saving, one for opening for example) and simply maintain that instance, which will "remember" the last directory that it was using, you'd still need to seed it with a starting directory though
Another choice would be to construct some kind of library call that could load and save the last directory the user used based on some unique key. This means you could simply do something like...
File toFile = MyAwesomeLibrary.getSaveFile(APPLICATION_DOCUMENT_SAVE_KEY);
Which would load the last known directory for the supplied key and show the JFileChooser configured with that value and would be capable of returning the selected File or null if the user canceled the operation...for example...
If you want to set the directory they were in at the previous opening of the file chooser you need to set the current directory.
//This will set the directory to the directory they previously chose a file from.
fileChooser.setCurrentDirectory(fileChooser.getCurrentDirectory());
Im not sure if this is what you're looking for, But when they select a file then go to select another file, it will maintain the directory they were in from the previous selection.
If you want your application to look for the user's working directory, you can try this:
String curDir = System.getProperty("user.dir");

How to add an ImageIcon to a JToolBar

I am trying to add a icon to a toolbar but what is the best place to put it in? My desktop or should I make a new file in the project file or add all the pictures in because it is not showing and this is my code:
JToolBar toolBar = new JToolBar();
String[] iconFiles = {"pen-icon","",""};
String[] buttonLabels = {"New","Open","Save"};
icon = new ImageIcon[iconFiles.length];
Obutton = new JButton[buttonLabels.length];
for (int i = 0; i < buttonLabels.length; ++i) {
icon[i] = new ImageIcon(iconFiles[i]);
Obutton[i] = new JButton(icon[i]);
Obutton[i].setToolTipText(buttonLabels[i]);
if (i == 3)
toolBar.addSeparator();
toolBar.add(Obutton[i]);
}
I would use an Action. Here is the AbstractAction constructor
public AbstractAction(String name, Icon icon) - Creates an Action with the specified name and small icon.
Parameters:
name - the name (Action.NAME) for the action; a value of null is ignored
icon - the small icon (Action.SMALL_ICON) for the action; a value of null is ignored
The benefit of using an Action is that is can be reused for components with similar purposes. So say you want to have an icon button in the toolbar to open a file, and also have a JMenuItem in a JMenu that also opens a file. They could share the same action, thus sharing the same icon, action command, and action to perform.
Action action = new AbstractAction("someActionCommand", someIcon) {
#Override
public void actionPerformed(ActionEvent e) {
// do something.
}
};
toolbar.add(action);
The above will automatically put the icon for you, but not the String. In a JMenuItem it would put both the String and the icon.
Then just add the Action to the tool bar.
See more at How to use Actions
To answer you real question, as #MadProgrammer noted, you should be loading your images as an embedded resource, using
ImageIcon icon = new ImageIcon(MyClass.class.getResource("/resources/images/image.png"));
where the /resources/images directory is in the src, and getResource() returns a URL. Upon build, your IDE should copy the files into the class path for you.
ProjectRoot
src
resources
images
image.png
You'll come to find that when using a file from the file system, will not work upon time of deployment
Here's an example, where the JMenuItem and the JToolBar button share the same action. Notice that in the JToolBar all I have to do is add the Action, I don't need to create a button for it. The JToolBar automatically makes it a button, without the action command
I use this "open.gif" from the below file structure and use
ImageIcon icon = new ImageIcon(
ActionTest.class.getResource("/resources/image/open.gif"));
Here's the result
Here's the code. Enjoy!
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class ActionTest {
public ActionTest() {
ImageIcon openIcon = new ImageIcon(
ActionTest.class.getResource("/resources/image/open.gif"));
ImageIcon saveIcon = new ImageIcon(
ActionTest.class.getResource("/resources/image/save.gif"));
ImageIcon newIcon = new ImageIcon(
ActionTest.class.getResource("/resources/image/new.gif"));
Action openAction = new AbstractAction("Open", openIcon) {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Open File");
}
};
Action saveAction = new AbstractAction("Save", saveIcon) {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Save File");
}
};
Action newAction = new AbstractAction("New", newIcon) {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("New File");
}
};
JMenuItem openMenuItem = new JMenuItem(openAction);
JMenuItem saveMenuItem = new JMenuItem(saveAction);
JMenuItem newMenuItem = new JMenuItem(newAction);
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
fileMenu.add(openMenuItem);
fileMenu.add(saveMenuItem);
fileMenu.add(newMenuItem);
menuBar.add(fileMenu);
JToolBar toolBar = new JToolBar();
toolBar.add(Box.createHorizontalGlue());
toolBar.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));
toolBar.add(newAction);
toolBar.add(openAction);
toolBar.add(saveAction);
JFrame frame = new JFrame("Toolbar and Menu Test");
frame.setJMenuBar(menuBar);
frame.add(toolBar, BorderLayout.PAGE_START);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ActionTest();
}
});
}
}
Resources of this type are typically best contained within the application context (such as a jar file). This reduces the chances of someone tampering with it as it's much more time consuming to unpack, modify and repack a jar file then simply replace a file. It also reduces what you need to distribute as it becomes self-contained.
These are known as embedded resources.
Where you would put them within this context is up to up, many people use a "resources" folder to store these types of files, but sometimes, you may want something that is relative to the context of the class. It's up to you.
This raises issues with loading these resources, as you can no longer reference them using something like File.
In general you can use Class#getResource(String), which returns a URL or Class#getResourceAsStream(String) which returns a InputStream. This provides you with all you need to load these embedded resources.
ImageIcon(String) expects the value to be a file reference, which means it won't work for embedded resources, but ImageIcon provides a constructor that takes a URL as a reference, this means you would need to use
icon[i] = new ImageIcon(getClass().getResource(iconFiles[i]));
To load your images.
Based on your example, the images would need to be relative to the class (ie within a directory structure the same as your package structure). How you achieve this will depend on your development environment.
Remember, you can also specify relative paths to getResource and even an absolute path in some contexts. An absolute path basic prefixes the elements of class path to the specified path when it searches for the resources.

Failed to get my image loaded [duplicate]

This question already has answers here:
Displaying an ImageIcon
(2 answers)
Add a picture to a JFrame
(3 answers)
Closed 9 years ago.
I am trying to add a picture of a cow and eclipse is failing me. It won't allow any images, I think I may be doing my path wrong, but I am getting it straight from the properties that eclipse supplies upon right-clicking the image. So if anyone has any idea why my picture fails to load please tell me. NO ERROR MESSAGE!
package odin;
import java.awt.event.*;
import javax.swing.*;
public class Main extends JFrame implements ActionListener{
JPanel mypanel;
JButton mybutton;
JLabel mylabel;
int Counter = 0;
public Main(){
mypanel = new JPanel();
mybutton = new JButton("OK");
mybutton.addActionListener(this);
mylabel = new JLabel();
JLabel imgLabel = new JLabel(new ImageIcon("/GuiTest/src/odin/COW.png"));
mypanel.add(mybutton);
mypanel.add(mylabel);
mypanel.add(imgLabel);
this.add(mypanel);
}
public static void main(String[] args){
Main first = new Main();
first.setTitle("First Attempt");
first.setSize(800,600);
first.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
first.setVisible(true);
first.setResizable(false);
first.setLocationRelativeTo(null);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==mybutton)
{
Counter = Counter + 1;
mylabel.setText("My Clicks " + Counter);
}
}
}
The problem is the path to the image...
JLabel imgLabel = new JLabel(new ImageIcon("/GuiTest/src/odin/COW.png"));
Basically, ImageIcon(String) expects that the String represents a file. This means, that Java is look for the image starting from the root of the current drive...which probably isn't what you really want...
You should also not store resources within the src directory in Eclipse, as I understand it, Eclipse requires you to place these resources within the "resources" directory within the project. These will be included within the project when you build it...
Once you've move the image to this location, you should be able to access it as an embedded resource using something like...
JLabel imgLabel = new JLabel(new ImageIcon(getClass().getResource("/odin/COW.png")));

NullPointerException when trying to display image?

This applet is a simple about the developer page in a website i'm creating for a class project. I'm trying to display an image and a bio for each different JButton.
I'm having an Issue with compiling, I keep getting a NullPointerException error
on this line
danPic = new ImageIcon(getClass().getResource("pics/danSkaggs.jpg"));
Which i'm assuming it goes null because it can't find the image based on the directory i'm giving it. However I can't understand what I can do different, I can't see any problems with how the directory is written. The directory is pics/filename.jpg and the folder is in the same package as the Java code.
Here is the full source code.
import java.util.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Developers extends JApplet{
private JButton danButton = new JButton("Dan Skaggs");
private JButton brandonButton = new JButton("Brandon Shaw");
private JButton jamesButton = new JButton("James Simpson");
private JLabel bioLabel = new JLabel("Please click one of the buttons on the left.");
JPanel centerPanel = new JPanel(new GridLayout(1, 2));
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel westPanel = new JPanel(new GridLayout(1, 3));
private ImageIcon danPic;
private ImageIcon brandonPic;
private ImageIcon jamesPic;
private JLabel dLabel;
private JLabel bLabel;
private JLabel sLabel;
//This array carries the Bios of the group project members
String[] bio = new String[]{"Insert Bio",
"Insert Bio",
"Insert Bio"};
public Developers(){
mainPanel.add(westPanel, BorderLayout.WEST);
westPanel.add(danButton);
westPanel.add(brandonButton);
westPanel.add(jamesButton);
centerPanel.add(bioLabel);
mainPanel.add(centerPanel, BorderLayout.CENTER);
danButton.addActionListener(new Handler());
brandonButton.addActionListener(new Handler());
jamesButton.addActionListener(new Handler());
danPic = new ImageIcon(getClass().getResource("pics/danSkaggs.jpg"));
brandonPic = new ImageIcon(getClass().getResource("pics/brandonShaw.jpg"));
jamesPic = new ImageIcon(getClass().getResource("pics/jamesSimpson.jpg"));
dLabel = new JLabel (danPic);
bLabel = new JLabel (brandonPic);
sLabel = new JLabel (jamesPic);
centerPanel.add(dLabel);
add(mainPanel);
}
private class Handler implements ActionListener{
public void actionPerformed(ActionEvent event){
if(event.getSource()== danButton){
bioLabel.setText(bio[0]);
centerPanel.add(dLabel);
}
else if(event.getSource()== brandonButton){
bioLabel.setText(bio[1]);
centerPanel.add(bLabel);
}
else if(event.getSource()== jamesButton){
bioLabel.setText(bio[2]);
centerPanel.add(bLabel);
}
}
}//end Handler class
}//end Developer class
Use ImageIO instead, it will give the exception you can caught and process accordingly.
Or
danPic = new ImageIcon(getClass().getResource("pics/danSkaggs.jpg"));
You are missing the / as pics is package name, must use / to make url other wise pics will embed to the parent dir name to make mistake.So use (poor way)
danPic = new ImageIcon(getClass().getResource("/pics/danSkaggs.jpg"));
The Exception is on the first one because it is executed first also change other two statements that are getting the image.
I just tested that it is working fine.
So getResource is returning null: your path to the picture is wrong. Note that these are relative paths (relative to the class you fetched with getClass) so you are probably missing the initial slash which would make it an absolute path.
This should be:
danPic = new ImageIcon(getClass().getClassLoader().getResourceAsStream("danSkaggs.jpg"));
This will load the image from the class path assuming pics directory is on the class path.
getClass().getResource("pics/danSkaggs.jpg") is a relative path. If your class is at a package com.mydomain it expects to find the image in /com/mydomain/pics/danSkaggs.jpg
If the class and the image are in the same package just use getResource("danSkaggs.jpg"). For more details check this comment sample code that demonstrates loading resources using either a class or even better its classloader.

Categories