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);
}
Related
Need to display selected in FileDialog image, but thats somewhy didnt work. When i try to choose image it throws exception javax.imageio.IIOException: Can't create an ImageInputStream!
I think problem is in getDirectory() , but dont know how to fix.
public ImageShow() throws IOException {
super("Pictures");
setSize(1024,768);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonOpen = new JButton("Open file");
buttonPanel.add(buttonOpen);
actions();
fileDialog();
add(buttonPanel);
image = ImageIO.read(new File(fd.getDirectory()));
imageLabel = new JLabel(new ImageIcon(image));
buttonPanel.add(imageLabel);
}
public void fileDialog() {
fd = new FileDialog(new JFrame(), "Choose file");
fd.setVisible(true);
}
public void actions() {
buttonOpen.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fileDialog();
}
});
}
}
image = ImageIO.read(new File(fd.getDirectory()));
A directory is not an image! Try instead getFile() which:
Gets the selected file of this file dialog. If the user selected CANCEL, the returned file is null.
But as I said in comments..
Use the Swing based JFileChooser rather than the AWT based FileDialog.
And be sure to consult the avialable documentation when using methods.
I can't manage to display menu and textarea with awt (see the code below). What could be the problem? I think I'm doing everything correctly, but could it be caused by the fact, that Frame object isn't instantiated while I'm trying to add TextArea and Menu to it?
BTW. I know AWT is obsolete, but I want to gain some knowledge of it before moving onto Swing or JavaFX. Also point me to any mistakes I've made while creating this post (as it's the first of mine).
class Notepad extends Frame{
Notepad(String name){
super(name);
TextArea text = new TextArea(" ", 10, 30, SCROLLBARS_VERTICAL_ONLY);
add(text);
MenuBar mbar = new MenuBar();
setMenuBar(mbar);
Menu file = new Menu("File");
MenuItem New, Open, Save, Close;
file.add(New = new MenuItem("New"));
file.add(Open = new MenuItem("Open"));
file.add(Save = new MenuItem("Save"));
file.add(Close = new MenuItem("Close"));
mbar.add(file);
Menu edit = new Menu("Edit");
MenuItem Find, Replace, ReplaceAll;
edit.add(Find = new MenuItem("Find"));
edit.add(Replace = new MenuItem("Replace"));
edit.add(ReplaceAll = new MenuItem("ReplaceAll"));
mbar.add(edit);
MenuHandler menuHandler = new MenuHandler(this);
New.addActionListener(menuHandler);
Open.addActionListener(menuHandler);
Save.addActionListener(menuHandler);
Close.addActionListener(menuHandler);
Find.addActionListener(menuHandler);
Replace.addActionListener(menuHandler);
ReplaceAll.addActionListener(menuHandler);
MyWindowAdapter w_listener = new MyWindowAdapter(this);
addWindowListener(w_listener);
//this.setVisible(true);
}
public void paint(Graphics g){
}
public static void main(String[] foo){
Notepad notepad = new Notepad("Notepad");
notepad.setSize(500, 500);
notepad.setVisible(true);
}
}
class MyWindowAdapter extends WindowAdapter{
Notepad notepad;
MyWindowAdapter(Notepad notepadframe){
this.notepad = notepad;
}
public void windowClosing(WindowEvent we){
notepad.setVisible(false);
System.exit(0);
}
}
class MenuHandler implements ActionListener{
Notepad notepad;
public MenuHandler(Notepad notepad){
this.notepad = notepad;
}
public void actionPerformed(ActionEvent ae){
String arg = ae.getActionCommand();
if(arg.equals("New")){
}
}
}
I am trying to create a function which can preview the image that the user selected from a customized JFileChooser. The following are the code snippets from the test frame and the customized JFileChooser.
Test.java
public class Test extends JFrame {
private JPanel contentPane;
private FileChooser file;
private static JLabel lblPicPreview;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Test frame = new Test();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Test() {
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("main menu");
setBounds(100, 100, 960, 540);
setLocationRelativeTo(null);
contentPane = new JPanel();
setContentPane(contentPane);
contentPane.setLayout(new FlowLayout(FlowLayout.LEADING));
lblPicPreview = new JLabel();
lblPicPreview.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
file.setPic();
}
});
lblPicPreview.setBorder(new TitledBorder(new LineBorder(new Color(0, 0, 0)), "Preview", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
lblPicPreview.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
lblPicPreview.setToolTipText("Click to change profile picture");
file= new FileChooser();
contentPane.add(file);
contentPane.add(lblPicPreview);
}
// Method to update image
public static void updatePicture(ImageIcon icon){
lblPicPreview.setIcon(icon);
}
public void refresh(){
repaint();
revalidate();
}
}
FileChooser.java
public class FileChooser extends JPanel implements ActionListener {
/**
* Constructor FileChooser to place the UI for customized JFileChooser
*/
// actionPerformed for the "select" button in the custom UI
public void actionPerformed(ActionEvent e){
returnVal= fileChooser.showOpenDialog(button);
if(returnVal==JFileChooser.APPROVE_OPTION){
file= fileChooser.getSelectedFile();
fileLabel.setText(file.getAbsolutePath());
img= new ImageIcon(file.getAbsolutePath());
/** caller object to chg icon when user chooses new image
* i want to make this to update the image from its caller
* something like this
* {sourceLabel}.setIcon(img);
*/
Test.updatePicture(img);
}
}
}
The code works fine for the application. The problem is that i wish to make the customized JFileChooser to be reusable for all other frames/ classes. I want to make my custom JFileChooser smart enough to get any caller's class's JLabel (eg. lblPicPreview) to be updated with the chosen image instead of calling Test.java's lblPicPreview.setIcon() from the FileChooser class itself. This is done so that I can use FileChooser for other instances of frames/class.
One problem is that Test.java's lblPicPreview is an instance variable, so i cannot directly use it from FileChooser class.
All helps are appreciated. Thank you in advance.
Just add a method to specify the label to set:
public class FileChooser extends JPanel implements ActionListener {
protectedJLabel activeLabel;
public void setActivelabel( JLabel label ) {
activeLabel = label;
}
}
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 want to start by saying that I'm new to swing. So all that I am trying to do if use a JFileChooser to select a directory. I can open, navigate and select a directory. The problem comes when I press any button that closes the dialog. When I do that then my application freezes. When ever it freezes just the panel that the dialog box is returning to turns white. When I step with the debugger the hang happens immediately aftet the dialog closes and the if statement is not reached. Also I am doing this inside of an Eclipse plugin if that makes a different. In particular it is hosted inside of a View. Code below:
public class TexturePacker extends ViewPart {
public void createPartControl(Composite parent) {
Composite composite = new Composite(parent, SWT.EMBEDDED | SWT.NO_BACKGROUND);
frame = SWT_AWT.new_Frame(composite);
frame.add(new TexturePackerPanel(frame));
}
}
public class TexturePackerPanel extends JPanel {
//This is called from initialize(), which is called in the constructor
private void initializeConfigPanel() {
JPanel configPanel = new JPanel();
JTextBoxk outputDirectory = new JTextField();
configPanel.add(inputDirectory);
JButton fileButton = new JButton("Folder");
fileButton.addMouseListener(new MouseListener(){
#Override
public void mouseClicked(MouseEvent arg0) {
JFileChooser file = new JFileChooser(outputDirectory.getText());
file.setDialogTitle("Select Output Directory");
file.setDialogType(JFileChooser.OPEN_DIALOG);
file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = file.showDialog(frame, "Choose");
if(returnVal == JFileChooser.APPROVE_OPTION) {
outputDirectory.setText(file.getSelectedFile().getAbsolutePath());
}
}
//Other blank MouseListener methods//
});
configPanel.add(fileButton);
}
}
System Info:
Windows 8 64bit
Java 7
Eclipse 4.2 SR1 EE Edition
I'm pretty sure that the problem is caused by Swing not playing nice inside of eclipse. I have successfully gotten it working using SWT Directory Dialog. So I am going to just convert the whole JPanel to SWT. Thanks everyone's help, I now know a lot more about how Swing works.
For this you really should be using an ActionListener instead of a MouseListener.
Aside from that I think this is a threading issue. You should read the documents on concurrency in swing.
Surround the JFileChooser part with
SwingUtilities.invokeLater(new Runnable() {
public void run() {
\\Your JFileChooser bit
}
Edit 1:
I've run the following slightly edited code but can't reproduce your problem
public static void main(final String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final JPanel configPanel = new JPanel();
final JButton fileButton = new JButton("Folder");
final JFrame frame = new JFrame();
frame.setVisible(true);
frame.add(configPanel);
// JButton outputDirectory = new JButton("XX");
fileButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent arg0) {
final JFileChooser file = new JFileChooser();
file.setDialogTitle("Select Output Directory");
file.setDialogType(JFileChooser.OPEN_DIALOG);
file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
final int returnVal = file.showDialog(frame, "Choose");
if(returnVal == JFileChooser.APPROVE_OPTION) {
// outputDirectory.setText(file.getSelectedFile().getAbsolutePath());
System.out.println(returnVal);
}
}
});
configPanel.add(fileButton);
}
});
}