The picture here is where the picture will be set.
private void btnOpenPic1ActionPerformed(java.awt.event.ActionEvent evt)
{
int pic1 = jFileChooser1.showOpenDialog(this);
if (pic1 == jFileChooser1.APPROVE_OPTION)
{
File f = jFileChooser1.getSelectedFile();
btnPic1.setIcon(new ImageIcon(""+ f));
btnPic1.setText("");
}
}
now after setting the picture. How will i be able to save that picture into the project java so that next time it loads, it will still appear there.
private void btnSavePic1ActionPerformed(java.awt.event.ActionEvent evt)
{
}
Related
i am trying to load image from specified path, and list of files are stored inside List<>.
at first time when i initialize image it display but when i am trying to display next image from List instance which contain list of files, it doesn't repaint the image.
what's wrong going is i am initializing image in constructor first time that overwrite
the new image, now where to initialize image first time outside constructor i don't know.
my code :
public void nextImage(int cnt)
{
System.out.println(cnt);
if (cnt < imageFiles.size())
{
System.out.println(imageFiles.size());
try
{
bg = ImageIO.read(new File((imageFiles.get(cnt)).toString()));
scaled = getScaledInstanceToFit(bg, new Dimension(600, 600));
setBackground(Color.BLACK);
}
catch(Exception e)
{
e.printStackTrace();
}
}
MouseHandler handler = new MouseHandler();
addMouseListener(handler);
addMouseMotionListener(handler);
System.out.println(cnt);
System.out.println(imageFiles.get(cnt).toString());
}
menu item click code :
JMenuItem mntmRestoreImage = new JMenuItem("Next Image");
final ImagePane st = new ImagePane();
mntmRestoreImage.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent arg0)
{
st.nextImage(k);
k++;
}
});
mnEdit.add(mntmRestoreImage);
class code & constructor :
private BufferedImage bg;
private BufferedImage scaled;
java.util.List<Path> imageFiles= getFilesFromDirectory(FileSystems.getDefault().getPath("D:\\New folder"));
public ImagePane()
{
try
{
bg = ImageIO.read(getClass().getResource("/images/src11.jpg"));
scaled = getScaledInstanceToFit(bg, new Dimension(600, 600));
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
counter also increments, now the code inside ImagePane() constructor
overwrites the image of nextImage() function, so idea what happen out
in this code ??
any suggestion ?
I think I have the perfect solution for you! I wrote a little program for you so it is easier to understand.
First I have a method for you to check if the file is a picture:
public Stack<File> getFilesInFolder(String startPath) {
File startFolder = new File(startPath);
Stack<File> picturestack = new Stack<File>();
String extension;
int dotindex;
// Go through the folder
for (File file : startFolder.listFiles()) {
extension = "";
dotindex = file.getName().lastIndexOf('.'); // Get the index of the dot in the filename
if (dotindex > 0) {
extension = file.getName().substring(dotindex + 1);
// Iterate all valid file types and check it
for (String filetype : validpicturetypes) {
if (extension.equals(filetype)) {
picturestack.add(file);
}
}
}
}
return picturestack;
}
Very easy! Take the folder and iterate his files. Take the extension of the file and check if it is a valid file type. Define the file types in a array at the begining of your code.
String[] validpicturetypes = {"png", "jpg", "jpeg", "gif"};
At the end I push every file into a stack. Remember to fill the stack into a variable, do not read the files more than once because than you get the same problem as before:
Stack<File> pictures = getFilesInFolder("C:\\Users\\Admin\\Desktop");
After that use a Action for your JMenuItem! In my example I do not have much, you have to put your methods in!
Action nextpictureaction = new AbstractAction("Next Picture") {
private static final long serialVersionUID = 2421742449531785343L;
#Override
public void actionPerformed(ActionEvent e) {
if (!pictures.isEmpty()) {
System.out.println(pictures.pop().getName());
}
}
};
Add the Action at your JMenu and set the properties of your Frame.
/*
* Add Components to Frame
*/
setJMenuBar(menubar);
menubar.add(toolsmenu);
toolsmenu.add(nextpictureaction);
/*
* Frame Properties
*/
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
setSize(1000, 700);
setTitle("PictureEditor");
setVisible(true);
At the end execute your program with the invokeLater method!
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new PictureEditor();
}
});
}
Summary
Basically you need a somthing to iterate through because values like integer are not saved the way you like. In my example I used a Stack and save at the beginning all pictures in it. Important is that, if you used or finished with the picture, you have to remove it (use stack.pop() for a Stack). I do not found a method where you check if the file is a picture (if it is the ImageIO catch it is bad). I wrote a method for that if you want you could use it.
This is not an answer, but I cannot paste that much code into a comment.
I would change your code to something along the lines of this piece of code. This seperates the image loading from the gui updating logic (like adding mousehandlers and the like, I pasted only image loading code).
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Arrays;
import java.util.Iterator;
import javax.imageio.ImageIO;
public class ImageLoader
{
public static class ImageContainer
{
BufferedImage bg = null;
BufferedImage scaled;
}
Iterator<File> imageFiles = Arrays.asList(
new File("D:\\New folder").listFiles()).iterator();
public ImageContainer nextImage(Dimension dimensionToFit) throws Exception
{
ImageContainer c = new ImageContainer();
if (imageFiles.hasNext())
{
File file = imageFiles.next();
//you might not need this, if only images are in this directory
if(file.isDirectory())
return null;
c.bg = ImageIO.read(file);
c.scaled = getScaledInstanceToFit(c.bg, dimensionToFit);
return c;
}
else
return null;
}
private BufferedImage getScaledInstanceToFit(BufferedImage bg,
Dimension dimensionToFit)
{
//do the risizing
}
}
This is not yet optimized though.
I am trying to load an image and set to background, but i get the error at selectionPanel method "Could not load background image".
It seems that something is going wrong with the image processing but i cant find out what.
public class selectionPanel extends JPanel
{
//Variable with the name of our pic
private static final String path = "selbkgrnd.jpg";
private ImageIcon imageIcon;
private Dimension windowSize;
private int imageHeight;
private int imageWidth;
protected selectionPanel()
{
this.imageIcon = new ImageIcon("selbkgrnd.jpg"); //Save image to imageIcon
Image image = this.imageIcon.getImage();
this.imageWidth = image.getWidth(null);
this.imageHeight = image.getHeight(null);
if ((this.imageWidth == -1) || (this.imageHeight == -1)) //Check if background image is succesfully loaded
{
JOptionPane.showMessageDialog(JOptionPane.getDesktopPaneForComponent(this), "Could not load background image", "Fatal error!", 0);
System.exit(-1);
}
this.windowSize = new Dimension(this.imageWidth, this.imageHeight);
}
protected void startScreen()
{
setOpaque(false);
setSize(this.windowSize);
}
protected int getImageHeight()
{
return imageHeight;
}
protected int getImageWidth()
{
return imageWidth;
}
#Override
public void paintComponent(Graphics g)
{
g.drawImage(this.imageIcon.getImage(), 0, 0, null);
super.paintComponent(g);
}
}
Usually this is due to your looking in the wrong location for your Image File. Try using the complete path to the image, either that or a path relative to the user's directory which can be found with:
System.out.println("user directory: " + System.getProperty("user.dir"));
Edit
You state:
Thank you it worked with the full path, but isnt it supposed to work with just the image name if it is inside the source code folder ?
No. Again, Java will look for the file relative to the user directory.
Note however that if the image is in the class file directory or in a directory relative to this and you make a jar file out of this and need to access the images, then you can't use files. You will need to get the images as a resource and the relative path will be different since it won't be related to the user.dir but rather will be relative to the location of the class files.
I'm developing a small photo editing application and would like the JButtons disabled until the user loads an image, at which point I want the buttons to become enabled(clickable). My thinking was to add a boolean imageFound, and an image checker method. If boolean is false, the buttons are disabled and if it is true they are enabled (the boolean is set to true in the load image actionPerformed method). The problem im having is that when running the app, the buttons are disabled as they should be, but when i load the image they would still be disabled. I dont know if maybe i am missing any piece of code to recheck whether the image is available, thus enabling the buttons (at runtime ofc). Thanks for any help.
...BufferedImage effects = null;
boolean bmpFound = false;
public GUI()
{
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.initComponents();
this.bmpChecker();
this.addListeners();
this.setTitle("PicTweak");
this.setSize(900, 600);
this.setVisible(true);
}
...else if(e.getSource() == loadItem)
{
try
{
imagePath = DialogIO.displayOpenDialog();
effects = ImageInOut.loadImage(imagePath);
imageHolder.setIcon(new ImageIcon(effects));
bmpFound = true;
}
....public void bmpChecker()
{
if(bmpFound)
{
grayScale.setEnabled(true);
blur.setEnabled(true);
reset.setEnabled(true);
brightDark.setEnabled(true);
horFlip.setEnabled(true);
verFlip.setEnabled(true);
verHorFlip.setEnabled(true);
}
else
{
grayScale.setEnabled(false);
blur.setEnabled(false);
reset.setEnabled(false);
brightDark.setEnabled(false);
horFlip.setEnabled(false);
verFlip.setEnabled(false);
verHorFlip.setEnabled(false);
}
}
When you load/unload the image, call bmpChecker() afterwards, i.e.
...
try
{
imagePath = DialogIO.displayOpenDialog();
effects = ImageInOut.loadImage(imagePath);
imageHolder.setIcon(new ImageIcon(effects));
bmpFound = true;
bmpChecker();
}
...
A better alternative would be t add listeners for the image loading, i.e. for each control or group of controls that needs to update its state accordingly, you'd register a listener that is notified whenever an image is loaded or unloaded. The listener could then trigger the updates of the corresponding controls.
Something like:
class ImageEvent {
private boolean imageLoaded; //plus getter/setter and maybe initialized in constructor
}
interface ImageListener {
void imageChanged(ImageEvent e);
}
...
List<ImageListener> listeners;
...
try
{
imagePath = DialogIO.displayOpenDialog();
effects = ImageInOut.loadImage(imagePath);
imageHolder.setIcon(new ImageIcon(effects));
bmpFound = true;
ImageEvent imgageEvent = new ImageEvent();
imageEvent.setImageLoaded(true);
for( ImageListener l : listeners ) {
l.imageChanged(imageEvent);
}
}
...
And an example listener:
class JButtonImageListener implements ImageListener {
private JButton button; //plus getter/setter
public void imageChanged(ImageEvent e) {
button.setEnabled(e.isImageLoaded());
}
}
I'm currently trying to use FileChooserBuilder from Netbeans Platform API. Following code is complete netbeans module action. When run, it doesn't show at the center of window/screen but somewhere in bottom left corner of the screen. Is there any possibility to make this dialog display in the middle of the screen?
public final class LoadProjectAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
File home = new File(
System.getProperty("user.home")
+ File.separator + "lib");
FileChooserBuilder fileChooserBuilder = new FileChooserBuilder(
LoadProjectAction.class);
fileChooserBuilder.setTitle("Load project");
fileChooserBuilder.setDefaultWorkingDirectory(home);
fileChooserBuilder.setApproveText("Load");
fileChooserBuilder.setDirectoriesOnly(true);
File directory = fileChooserBuilder.showOpenDialog();
if (directory != null) {
return; // nothing to do
}
// do some processing here
}
}
Thanks for your ideas.
Found the solution:
You have to obtain JFileChooser instance and set right parent component in it's showOpenDialog method (it's then positioned relatively to application's main window). But as NetBeans tries to work quite safely with the threads - it allows only one thread access the components, so the EventQueue.invokeLater has to be used.
public final class LoadProjectAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
// output window
InputOutput io = IOProvider.getDefault().getIO("File search", true);
io.select();
// start in user home directory
File initialDirectory = new File(
System.getProperty("user.home")
+ File.separator + "lib");
FileChooserBuilder fileChooserBuilder = new FileChooserBuilder(
"LoadProjectAction");
fileChooserBuilder.setTitle("Load project");
fileChooserBuilder.setDefaultWorkingDirectory(initialDirectory);
fileChooserBuilder.setApproveText("Load");
fileChooserBuilder.setDirectoriesOnly(true);
JFileChooser jfc = fileChooserBuilder.createFileChooser();
int value = jfc.showOpenDialog(WindowManager.getDefault().getMainWindow());
if (value != JFileChooser.APPROVE_OPTION) {
return; // nothing to do
}
// process selection
}
});
}
}
How can I display a series of images one by one every time the user clicks the next button?
I have few images stored in array. I used button next to go from image to image. How to programme the button? I used action listener but I just don't know how to get back to the array.
I know I'm being lazy here by not writing the entire code, but here goes anyway.
class whatEver implements ActionListener{
JButton btnNext = new JButton();
static int fileNumber = 0;
static int totalFiles;
void functionLoadInterface () //Function with
{
btnNext.addActionListener(this);
//Initialize array ImageArray with file paths.
}
public void cycleImage()
{
String file = ImageArray[fileNumber%totalFiles];
//Code to load the image wherever follows
}
public void actionPerformed(ActionEvent e)
{
filenumber++;
this.cycleImage();
}