The following code displays an image when the button is pressed. Custom gui opens an internal frame that displays an image but when it does that it also displays another frame containing the same image, that is separate from the desktop pane that I have created. I don't want that frame to show though. I know ImageJ also displays the image but I don't know where in the code its calling that. I was wondering if anyone could spot out the mistake.
here is my code:
Open.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
FileOpener open = new FileOpener(file);
ImagePlus fopen = open.open(false);
if(fopen != null){
BufferedImage openImage = fopen.getBufferedImage();
//new ImagePlus(path,openImage).show(desktop);
ImagePlus newImage = new ImagePlus(path, openImage);
CustomGui gui = new CustomGui(newImage, path, desktop); //This is a customized gui class I created.
img = newImage;
}
}
Related
I am using NetBeans IDE 8.0.2 to create my project application. I have created my application's signup page using multiple panels in CardLayout. For users to upload their image I created a JLabel and added mouseClicked event to it which displays JFileChooser but the image chosen is not displayed in the label (even though the image path is stored). Please check the following code.
private void PrImgLabMouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
JFileChooser FileChooser = new JFileChooser();
int response = FileChooser.showOpenDialog(Panel1);
if(response == JFileChooser.APPROVE_OPTION){
File imgFile = FileChooser.getSelectedFile();
String Filepath = imgFile.getAbsolutePath();
ImgMeth.Resize(Filepath, PrImgLab);
}
else if(response == JFileChooser.CANCEL_OPTION);{
Icon defimg = new ImageIcon("DefImg.png"); //default image path
PrImgLab.setIcon(defimg);
}
}
This the label event class and the code below is the method used to resize the image and fit it into the JLabel.
public void Resize(String path,JLabel label){
ImageIcon img = new ImageIcon(path);
Image image = img.getImage();
Image imgScale = image.getScaledInstance(label.getWidth(), label.getHeight(), Image.SCALE_SMOOTH);
Icon icon = new ImageIcon(imgScale);
label.setIcon(icon);
}
After calling resize (Yes that should begin lower case) call validate on the Container containing the label.
I'm writing a little photo application (asked some questions before) and I have one problem which I cannot resolve. The idea is that there are two sections: the upper one is for an overview (using thumbnails) and the lower one shows the selected image in it's full size. I cannot use ImageIO (required by my lecturer).
I'm using a JList for the overview but most images are not visible. I chose a folder with about 20 images and only 2 show up. And one of them isn't even centered.
For some reason, if I delete those lines:
thumbnaillist.setFixedCellWidth(thumbW);
thumbnaillist.setFixedCellHeight(thumbH);
One image shows up that wasn't visible before, but now the other two disappear.
This is my code:
public class PVE extends JFrame {
private JFileChooser fileChoose;
//MenuBar
private JMenuBar menubar;
private JMenu file;
private JMenuItem openFolder;
private JMenuItem exit;
//Thumbnails
private JList thumbnaillist;
private DefaultListModel<ImageIcon> listmodel;
private JScrollPane tscroll;
private ImageIcon thumbs;
private int thumbW = 100;
private int thumbH = 100;
//for full size view
private JPanel imgview;
public PVE() {
setLayout(new BorderLayout());
//MenuBar
menubar = new JMenuBar();
file = new JMenu("File");
openFolder = new JMenuItem("Open folder...");
exit = new JMenuItem("Quit");
file.add(openFolder);
file.addSeparator();
file.add(exit);
menubar.add(file);
setJMenuBar(menubar);
fileChoose = new JFileChooser();
openFolder.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
fileChoose.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChoose.showOpenDialog(null);
File chosenDir = fileChoose.getSelectedFile();
loadToThumbView(chosenDir);
}
});
//Thumbnail view
listmodel = new DefaultListModel();
thumbnaillist = new JList(listmodel);
thumbnaillist.setLayoutOrientation(JList.HORIZONTAL_WRAP);
thumbnaillist.setFixedCellWidth(thumbW);
thumbnaillist.setFixedCellHeight(thumbH);
thumbnaillist.setVisibleRowCount(1);
tscroll = new JScrollPane(thumbnaillist, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
tscroll.setPreferredSize(new Dimension(0, 100));
add(tscroll, "North");
//for full size view
imgview = new JPanel();
imgview.setBackground(Color.decode("#f7f7f7"));
add(imgview, "Center");
setTitle("Photo Viewer");
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
} catch (Exception e) {
}
setSize(700, 700);
setLocation(200, 200);
setVisible(true);
}
public void loadToThumbView(File folder) {
listmodel.removeAllElements();
File[] imgpaths = folder.listFiles();
for (int j = 0; j < imgpaths.length; j++) {
listmodel.addElement(resizeToThumbnail(new ImageIcon(imgpaths[j].toString())));
}
}
public ImageIcon resizeToThumbnail(ImageIcon icon) {
Image img = icon.getImage();
BufferedImage bf = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = bf.createGraphics();
g.drawImage(img, 0, 0, thumbW, thumbH, null);
ImageIcon kB = new ImageIcon(bf);
return kB;
}
public static void main(String argv[]) {
PVE pv = new PVE();
}
}
Your problem is because of the way you're scaling your images.
I'm not exactly sure why but I guess it has something to do with the BufferedImage#createGraphics() call and that I was able to reproduce the problem with .jpg images while .png files were correctly painted.
However if you scale your images instead of converting them to a BufferedImage and getting a new ImageIcon from it, you get the correct output:
public ImageIcon resizeToThumbnail(ImageIcon icon) {
Image img = icon.getImage();
Image scaled = img.getScaledInstance(thumbW, thumbH, Image.SCALE_SMOOTH);
return new ImageIcon(scaled);
}
This is the folder I used to test:
And the outputs with your code and mine:
Important notes
And as as a recommendation don't make a window that big if all you're using is that little bar above. If you're adding something else below, then it's ok but for now it's not that "user friendly" (IMHO). Instead of JFrame#setSize() you could try using JFrame#pack() method so your frame resizes to it's preferred size.
Some other things I noted in your program:
You're not placing it inside the Event Dispatch Thread (EDT) which is dangerous since your application won't be Thread safe that way. You can change that if you change your main method as follows:
public static void main(String argS[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
PVE pv = new PVE();
}
});
}
You're setting the JScrollPane preferred size, instead you should override its getPreferredSize() method, see Should I avoid the use of setPreferred|Maximum|MinimumSize methods in Java Swing? (YES)
You're extending JFrame, you should instead create an instance of it unless you're overriding one of its methods (and you're not, so don't do it) or you have any good reason to do it. If you need to extend a Container you should extend JPanel instead, as JFrame is a rigid container which cannot be placed inside another one. See this question and this one.
I think I'm not missing anything, and hope this helps
Your “scaled” images are actually images which are the same size as the original image, but are blank except for a scaled version drawn in the upper left corner. That upper left corner is clipped out of view in each rendered cell (at least for the somewhat large images I tested with).
The scaled image needs to be created with the thumbnail size, not the size of the original image. Meaning, change this:
BufferedImage bf = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
to this:
BufferedImage bf = new BufferedImage(thumbW, thumbH, BufferedImage.TYPE_INT_ARGB);
I am having some trouble in ImageJ with one of its files. Basically set up a desktop pane that analyzes and opens images. But when the program opens the image it opens it as a separate JFrame. I would like to be an internal JFrame. So basically the image opens up in the desktop pane. I have tried a couple of things like creating a internal frame class and adding the win to the desktopPane but nothing seems to work it still opens it as a separate JFrame. I was wondering if anyone knows how to do this.
This is my code (this function is just calling .show() to display the image, the code for the actual JFrame that opens the window is in ImageWindow.java):
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
FileOpener open = new FileOpener(file);
ImagePlus fopen = open.open(false);
if(fopen != null){
BufferedImage openImage = fopen.getBufferedImage();
new ImagePlus(path,openImage).show(desktop); //This functions displays the image
ImagePlus newImage = new ImagePlus(path,openImage);
img = newImage;
}
frame.setVisible(false);
}
The creation of a new JFrame is hardcoded into ImageJ's ImagePlus class:
if (stackSize>1)
win = new StackWindow(this);
else
win = new ImageWindow(this);
If you want to adapt the GUI, you can extend the ImageWindow or StackWindow classes. See the Trainable Weka Segmentation plugin for a nice example.
Alternatively, use the data structures of ImageJ2, namely ImgLib's ImgPlus. These are designed to be independent of any user interface.
Code in Question
There isn't an actionListener for the image thumbnails, yet when clicked they update the image.
From this webpage.
Edit: I am currently importing images using JFileChooser and then creating a thumbnail and displaying the full image in a similar way to this, although not using ImageIcons. But would like to use this method so when I add an image it adds to the list and allows me to click the thumbnail to show that image.
However mine using actionListeners to change when something is pressed but this doesn't and can't understand the code where it does.
Thanks
Edit2:
Regarding the repaint option:
I have a class which extends component which then calls a repaint function.
public class Image extends Component {
private BufferedImage img;
//Print Image
public void paint(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}
I then have a class with all my Swing components which call methods from other classes.
Image importedImage = new Image(loadimageone.openFile());
Image scaledImage = new Image();
// Save image in Buffered Image array
images.add(importedImage.getImg());
// Display image
imagePanel.removeAll();
imagePanel.add(importedImage);
imagePanel.revalidate();
imagePanel.repaint();
previewPanel.add(scaledImage);
previewPanel.revalidate();
previewPanel.repaint();
If I remove the revalidate or repaint it wont' update the image on the screen.
Edit 3:
This is the code on how I implemented the dynamic buttons:
//Create thumbnail
private void createThumbnail(ImpImage image){
Algorithms a = new Algorithms();
ImpImage thumb = new ImpImage();
//Create Thumbnail
thumb.setImg(a.shrinkImage(image.getImg(), 75, 75));
//Create ImageIcon
ImageIcon icon = new ImageIcon(thumb.getImg());
//Create JButton
JButton iconButton = new JButton(icon);
//Create ActionListener
iconButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
bottomBarLabel.setText("Clicked");
imagePanel.removeAll();
imagePanel.add(images.get(position)); //Needs Fixing
imagePanel.revalidate();
}
});
//Add to previewPanel
previewPanel.add(iconButton);
previewPanel.revalidate();
previewPanel.repaint();
}
It looks like it uses ThumbnailAction instead which extends AbstractAction (at the very bottom of the code). Swing components can use Actions instead of ActionListeners. The advantage of Actions is that buttons can share an Action and they will automatically use the same key-bindings etc.
http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html
EDIT: I have added some code demonstrating that you do not need to explicitly repaint(). Give it a try.
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(2, 1));
final JLabel iconLabel = new JLabel();
JButton button = new JButton("Put Image");
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
JFileChooser fc = new JFileChooser();
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
iconLabel.setIcon(new ImageIcon(ImageIO.read(fc.getSelectedFile())));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
panel.add(iconLabel);
panel.add(button);
frame.add(panel);
frame.setVisible(true);
}
EDIT 2 (There is no Edit 2)
EDIT 3: Try this
public class MyActionListener implements ActionListener {
private JPanel imagePanel;
private Image image;
public MyActionListener(JPanel imagePanel, Image image) {
this.imagePanel = imagePanel;
this.image = image;
}
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Clicked");
imagePanel.removeAll();
imagePanel.add(image); //Needs Fixing
imagePanel.revalidate();
}
}
I need to choose image with file open dialog and then show it in window. But When I choose image it is not shown in the window.
I've created class which create window with jmenubar and 1 jmenuitem. When I click on menuitem JfileChooser appears and then I choose some file. But then happens nothing.
I think the problem is in actionListener for JFileChooser(ImageFilter is a filter from docs java)
public Frame(){
//create bars and window
mainframe = new JFrame("Window");
mainframe.setVisible(true);
mainframe.setSize(300, 300);
menubar = new JMenuBar();
mainer = new JMenu("Menu");
menubar.add(mainer);
//create items
item = new JMenuItem("Open",KeyEvent.VK_T);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
item.getAccessibleContext().setAccessibleDescription("open image");
//action listener
item.addActionListener(
new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//open file dialog
choser = new JFileChooser();
choser.addChoosableFileFilter(new ImageFilter());
final int returnval = choser.showOpenDialog(menubar);
//action listener for JFileChooser
choser.addActionListener(
new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (returnval == JFileChooser.APPROVE_OPTION){
fc = choser.getSelectedFile();
try{
Panel panel = new ShowImage(fc.getName());
mainframe.getContentPane().add(panel);
}catch(Exception exc){};
}
}
}
);
}
}
);
mainer.add(item);
mainframe.setJMenuBar(menubar);
}
ShowImage class
class ShowImage extends Panel{
BufferedImage image;
public ShowImage(String imagename) throws IOException {
File input = new File(imagename);
image = ImageIO.read(input);
}
public void paint(Graphics g){
g.drawImage(image,0,0,image.getWidth(),image.getHeight(),null);
}
}
P.S another problem is that it shows nothing until I change size of the window.
Extend JPanel instead of Panel, and override paintComponent method, ie:
class ShowImage extends JPanel{
public void paintComponent(Graphics g){
...
}
}
Also, there is no need to addActionListener on JFileChooser, just check the return value and act accordingly, ie:
final int returnval = choser.showOpenDialog(menubar);
if (returnval == JFileChooser.APPROVE_OPTION){
...
}
Im pretty sure this line will cause problems:
Panel panel = new ShowImage(fc.getName());
getName() will return the name of the file. So for example if you choose a image with JFileChooser named image.jpg, getName will return "image.jpg". This will make the image only show if the file you select is stored in the root folder of your project. I would change getName() to getAbsoultePath() which will return the full patch (e.i c:\desktop\image.jpg) which is most likley what you want.
Also as Max points out, you should override paintComponent rather then paint:
protected void paintComponent(Graphics g){
g.drawImage(image,0,0,image.getWidth(),image.getHeight(),null);
}