I have problem with getting active JInternalFrame. I need to indicate an active ImageInternalFrame(my class, thats extend JInternalFrame) because I will perform some operations on it. I do not know how to solve it, can somebody help me?
Here is my code:
public class MainFrame extends javax.swing.JFrame {
ArrayList <ImageInternalFrame> imageInternalFrameList = new ArrayList();
private void openMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);
File f = chooser.getSelectedFile();
String filePath = f.getPath();
BufferedImage bufferedImage;
ImageInternalFrame imageInternalFrame;
String mimetype= new MimetypesFileTypeMap().getContentType(f);
String type = mimetype.split("/")[0];
if(type.equals("image")){
bufferedImage = null;
try {
bufferedImage = ImageIO.read(new File(filePath));
} catch (IOException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
imageInternalFrame = new ImageInternalFrame(filePath);
imageInternalFrame.setSize( bufferedImage.getWidth(), bufferedImage.getHeight() );
imageInternalFrame.setVisible(true);
imageInternalFrame.setLocation(imageInternalFrameList.size() * 25 , imageInternalFrameList.size() * 25);
add(imageInternalFrame);
imageInternalFrameList.add(imageInternalFrame);
}
else{
JOptionPane.showMessageDialog(null, "It's NOT an image");
}}
public class ImageInternalFrame extends javax.swing.JInternalFrame {
public ImageInternalFrame( String imagePath ) {
initComponents();
setImage(imagePath);
}
public void setImage(String imagePath){
imageLabel.setIcon( new ImageIcon(imagePath) );
imageLabel.paintImmediately(imageLabel.getVisibleRect());
}
}
You can use the getSelectedFrame() method of your JDesktop class.
imageLabel.setIcon( new ImageIcon(imagePath) );
imageLabel.paintImmediately(imageLabel.getVisibleRect());
Don't use paintImmeditately. Swing will automatically schedule the repainting of the label when you change the Icon.
Related
I have made a program in Java, that downloads an image from the internet, given a link, and saves it into a specific folder in my computer, upon the pressing of a button in the gui. What I want to do next is to display that image on the screen. Please note, the URL input is not necessarily the URL of the image itself, but of an HTML webpage containing the image. The problem is, I can't simply create an ImageIcon object preemptively, because the image file doesn't exist in the system yet in compile time.
Panel Class
public class AdditionPanel extends JPanel
{
// ...
static JTextPane textpane;
JLabel paneInstructions;
JButton linkOk;
public AdditionPanel() throws IOException
{
textpane = new JTextPane();
paneInstructions = new JLabel("Paste the link here:");
linkOk = new JButton(" OK ");
// ...
linkOk.addActionListener(new LinkOkPressed());
// ...
this.add(textpane);
this.add(paneInstructions);
this.add(linkOk);
}
}
An idea I've had is to create an ActionListener for that button, and try to access the file only after the button has been pressed, and thus the file has been downloaded. In this case, I don't know how to make an image display on a JPanel, from a different class.
Action Listener
public class LinkOkPressed implements ActionListener
{
JLabel test;
#Override
public void actionPerformed(ActionEvent e)
{
// ImageDownloader is a class I have created, that simply saves the image
// from the given URL in a predetermined directory
ImageDownloader.saveImage(ImageDownloader.getImageUrl(AdditionPanel.textpane.getText()));
ImageIcon poster = new ImageIcon(getClass().getResource("/resources/myimage.png"));
test= new JLabel(poster);
AdditionPanel.add(test); // Does not work
}
}
So, can I add an image to the panel from a different class, or is there a better way to access a file that is downloaded during the runtime of the app? Thanks for the help.
ImageDownloader
public class ImageDownloader
{
public static String getImageUrl(String imdbLink)
{
String imageLink = "";
try
{
Document doc = Jsoup.connect(imdbLink).get();
Elements divs = doc.getElementsByClass("poster");
Element poster = divs.first();
Elements image = poster.getElementsByTag("a");
Element downloadImage = image.first();
Elements img = downloadImage.getElementsByTag("img");
imageLink = img.attr("src");
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return imageLink;
}
public static void saveImage(String imageLink)
{
BufferedImage image = null;
try
{
URL url =new URL(imageLink);
image = ImageIO.read(url);
ImageIO.write(image, "png", new File("C:\\...\\resources\\myimage.png"));
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Elaborating on PM 77-1's comment.
public class LinkOkPressed implements ActionListener
{
JLabel test;
#Override
public void actionPerformed(ActionEvent e)
{
// ImageDownloader is a class I have created, that simply saves the image
// from the given URL in a predetermined directory
ImageDownloader.saveImage(ImageDownloader.getImageUrl(AdditionPanel.textpane.getText()));
ImageIcon poster = new ImageIcon(getClass().getResource("/resources/myimage.png"));
test= new JLabel(poster);
Object obj = e.getSource(); // "obj" is really "linkOk" from class "AdditionPanel"
java.awt.Container parent = ((JButton) obj).getParent(); // "parent" is instance of "AdditionPanel"
((JPanel) parent).add(test);
}
}
SwingWorker example.
Create a separate class like so...
public class SaveImage extends javax.swing.SwingWorker<Void, Void> {
private AdditionPanel additionPanel;
public SaveImage(AdditionPanel addPanel) {
additionPanel = addPanel;
}
#Override
protected Void doInBackground() throws Exception {
ImageDownloader.saveImage(ImageDownloader.getImageUrl(AdditionPanel.textpane.getText()));
// Wait until the image is saved.
// Since I don't have code for class "ImageDownloader", can't tell you how to do this.
return null;
}
#Override
protected void done() {
javax.swing.ImageIcon poster = new javax.swing.ImageIcon(getClass().getResource("/resources/myimage.png"));
javax.swing.JLabel test= new javax.swing.JLabel(poster);
additionPanel.add(test);
}
}
And change your LinkOkPressed class like so...
public class LinkOkPressed implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
Object obj = e.getSource(); // "obj" is really "linkOk" from class "AdditionPanel"
java.awt.Container parent = ((JButton) obj).getParent(); // "parent" is instance of "AdditionPanel"
SaveImage saveImage = new SaveImage((AdditionPanel) parent);
saveImage.execute();
}
}
I have a JPanel name "imagePanel" and a button name "browseBtn". All contained in a JFrame class. When pressing the browseBtn, a file chooser will open up and after choosing a PNG image file, the image will appear directly in the imagePanel.
This is the action event for the browseBtn
private void browseBtnActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
JFileChooser fc = new JFileChooser();
int result = fc.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
if (accept(file)) {
try {
ImageIcon image = new ImageIcon(file.getPath());
JLabel l = new JLabel(image);
imagePanel.add(l);
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Error reading file !");
}
}
else {
JOptionPane.showMessageDialog(this, "Choose png file only !");
}
}
}
public boolean accept(File file) {
return file.isDirectory() || file.getAbsolutePath().endsWith(".png");
}
I have choose the correct .png file but i don't understand why the image didn't show up in the imagePanel. Can you guy explain on that ?
Cheers.
You should avoid creating new objects everytime you want to display your image, imagine if you change it 5 times, you're creating 5 times an object while you display only one !
Like said in the comments, your best shot would be to create your label when you create your panel, add it to said panel, then simply change the icon of this label when you load your image.
browseBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser();
int result = fc.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
if (accept(file)) {
try {
ImageIcon image = new ImageIcon(file.getPath());
label.setIcon(image);
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, "Error reading file !");
}
}
else {
JOptionPane.showMessageDialog(this, "Choose png file only !");
}
}
}
public boolean accept(File file) {
return file.isDirectory() || file.getAbsolutePath().endsWith(".png");
}
});
Assuming label is the reference to said JLabel, created on components initialisation.
Or you might try this :
browseBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser();
int result = fc.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
if (accept(file)) {
try {
ImageIcon imageIcon = new ImageIcon(new ImageIcon(file.getPath()).getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT)); //resizing
label.setIcon(imageIcon);
/*try { // or try this
InputStream inStream = this.getClass().getClassLoader().getResourceAsStream(file.getPath());
BufferedImage img = ImageIO.read(inStream);
Image rimg = img.getScaledInstance(width, height, Image.SCALE_STANDARD);
label.setIcon(rimg);
} catch (IOException e) {}*/
} catch (Exception ex) {JOptionPane.showMessageDialog(this, "Error reading file !");}
} else {JOptionPane.showMessageDialog(this, "Choose png file only !");}
}
}
public boolean accept(File file) {
return file.isDirectory() || file.getAbsolutePath().endsWith(".png");
}
});
I'm trying to take a screenshot of what's behind of a JPanel but i get a black image after saving it.
Here's the code:
private void takeScreenshot(String print){
JFileChooser c = new JFileChooser(getRealDesktop());
FileFilter jpg = new FileNameExtensionFilter(".jpg", ImageIO.getReaderFileSuffixes());
FileFilter jpeg = new FileNameExtensionFilter(".jpeg", ImageIO.getReaderFileSuffixes());
FileFilter png = new FileNameExtensionFilter(".png", ImageIO.getReaderFileSuffixes());
c.setFileFilter(png);
c.setFileFilter(jpeg);
c.setFileFilter(jpg);
c.showSaveDialog(this);
if(c.getSelectedFile() != null){
String ssLoc = c.getSelectedFile().getAbsolutePath()+c.getFileFilter().getDescription();
System.out.println(ssLoc);
BufferedImage bufImg = new BufferedImage(ssWindow.getSize().width, ssWindow.getSize().height,BufferedImage.TYPE_INT_RGB);
ssWindow.paint(bufImg.createGraphics());
File imageFile = new File(ssLoc);
try{
imageFile.createNewFile();
ImageIO.write(bufImg, "JPG", imageFile);
}catch(Exception ex){
System.err.println(ex);
}
}
}
And the press action button looks like this:
this.setVisible(false);
takeScreenshot("ssTake");
this.setVisible(true);
How can make this work?
Thanks, Gilbert Le Blanc.
I reworked a bit the code to use the robot for this and now the code looks like this:
private void takeScreenshot(String print){
JFileChooser c = new JFileChooser(getRealDesktop());
FileFilter jpeg = new FileNameExtensionFilter("JPEG (*.jpg;*.jpeg;*.jpe;*.jfif)", "jpg", "jpeg", "jpe", "jfif");
c.setFileFilter(jpeg);
c.showSaveDialog(this);
if(c.getSelectedFile() != null){
ssLoc = c.getSelectedFile().getAbsolutePath()+".jpg";
try {
Thread.sleep(150);
Robot robot = new Robot();
BufferedImage screenShot = robot.createScreenCapture(new Rectangle(ssWindow.getX(),ssWindow.getY(),ssWindow.getWidth(),ssWindow.getHeight()));
ImageIO.write(screenShot, "JPG", new File(ssLoc));
System.out.println(print);
} catch (AWTException | IOException | InterruptedException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I have a simple JFrame where the user is changing the background color of it using a JPopupMenu. When the user exit the application, I want to save the changes made in the background.
I have tried to handle this with method windowClosing() from WindowAdapter class but when when I launch the application again, I don't see the changes I made earlier. I don't know what the problem is. I will appreciate any help. Here's my code.
/*i have removed unnnecessary codes*/
public class Popupframe extends JFrame{
private JRadioButtonMenuItem[] items;
private final Color[] colorvalues={Color.BLUE,Color.YELLOW,Color.RED};
static Color bgcolor=Color.CYAN;
JRadioButtonMenuItem[] cheek;
public Popupframe() {
super("using popups");
String[] colors = {"Blue","Yellow","Red"};
setBackground(bgcolor);
addMouseListener(new Handler());
}
private class Handler extends MouseAdapter implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
for(int i=0; i<items.length; i++) {
if(event.getSource()==items[i]) {
getContentPane().setBackground(colorvalues[i]);
bgcolor=colorvalues[i];
}
}
}
}
public static void main(String[] args) {
Popupframe frame=new Popupframe();
frame.setSize(width,height);
frame.setDefaultCloseOperation(Popupframe.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
int ok=JOptionPane.showConfirmDialog(frame,"are sure?","close",JOptionPane.WARNING_MESSAGE);
if(ok==JOptionPane.OK_OPTION) {
bgcolor=frame.getContentPane().getBackground();
System.out.println(bgcolor);
System.exit(0);
}
}
});
frame.setVisible(true);
}
You need to save the color code into a file(like settings file or shared preference) before System.exit(0) and read it in the main and set that color code. Then it works fine.
You are not persisting the color. Color is serializable, so you could just save the object in the program root directory. Put this code in your WindowClosing method :
//serialize the Color
try (
OutputStream file = new FileOutputStream("myBgColor.ser");
OutputStream buffer = new BufferedOutputStream(file);
ObjectOutput output = new ObjectOutputStream(buffer);
){
output.writeObject(bgColor);
}
catch(IOException ex){
log.log(Level.SEVERE, "Cannot perform output.", ex);
}
When you reload the application you need to get the color back. In the PopupFrame() constructor, before you call setBackground(color), put in this code here :
//deserialize the Color file
try(
InputStream file = new FileInputStream("myBgColor.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
){
//deserialize the List
bgColor = (Color)input.readObject();
}
catch(ClassNotFoundException ex){
fLogger.log(Level.SEVERE, "Cannot perform input. Class not found.", ex);
}
That should do the trick.
I am using this mmscomputing library as java applet to scan an image or document.
Using swings,awt i created one scan button which is acquiring scanner by calling scanner.acquire() method of mmscomputing jar..
and then placing that scanned image into jpanel for displaying.
Problem is, first time when i start my applet and hitting my scan button..scanning works fine..Twain states it goes into are: 3,4,5,6,7,5,4,3
then second time,hitting my scan button again ..
Twain states it goes into are: 3,4,5,4,3
It's not going into image transfer ready and transferring state and thus not into below CODE IF loop
if (type.equals(ScannerIOMetadata.ACQUIRED))
so i am not able to see the new scanned image into my jpanel second time...
then third time, hitting my scan button .. again it works fine.. getting into all states.
So i mean, For alternatively turns or restarting the java applet again ..it works.
what would be the issue.. ?
I want, every time when i hit scan button it should get me a new image into Jpanel.. but it's doing alternative times.
can i forcefully explicitly set or change twain states to come into 6th and 7th states..
or is there some twain source initialisation problem occurs second time?
because restarting applet is doing fine every time.. or some way to reinitialise applet objects everytime on clicking scan button..as it would feel like I am restarting applet everytime on clicking scan button...
I am not getting it..
Below is the sample code:
import uk.co.mmscomputing.device.twain.TwainConstants;
import uk.co.mmscomputing.device.twain.TwainIOMetadata;
import uk.co.mmscomputing.device.twain.TwainSource;
import uk.co.mmscomputing.device.twain.TwainSourceManager;
public class XXCrop extends JApplet implements PlugIn, ScannerListener
{
private JToolBar jtoolbar = new JToolBar("Toolbar", JToolBar.HORIZONTAL);
ImagePanel ipanel;
Image im =null;
BufferedImage imageforCrop;
ImagePlus imp=null;
int imageWidth;
int imageHeight;
private static final long serialVersionUID = 1L;
Container content = null;
private JPanel jContentPane = null;
private JButton jButton = null;
private JButton jButton1 = null;
JCheckBox clipBox = null;
JPanel crpdpanel=null;
JPanel cpanel=null;
private Scanner scanner=null;
private TwainSource ts ;
private boolean is20;
ImagePanel imagePanel,imagePanel2 ;
public static void main(String[] args) {
new XXCrop().setVisible(true);
}
public void run(String arg0) {
new XXCrop().setVisible(false);
repaint();
}
/**
* This is the default constructor
*/
public XXCrop() {
super();
init();
try {
scanner = Scanner.getDevice();
if(scanner!=null)
{
scanner.addListener(this);
}
} catch (Exception e)
{
e.printStackTrace();
}
}
/**
* This method initializes this
*
* #return void
*/
public void init()
{
this.setSize(1200, 600);
this.setLayout(null);
//this.revalidate();
this.setContentPane(getJContentPane());
}
private JToolBar getJToolBar()
{
jtoolbar.add(getJButton1());
jtoolbar.add(getJButton());
jtoolbar.setName("My Toolbar");
jtoolbar.addSeparator();
Rectangle r=new Rectangle(0, 0,1024, 30 );
jtoolbar.setBounds(r);
return jtoolbar;
}
private JPanel getJContentPane()
{
if (jContentPane == null)
{
jContentPane = new JPanel();
jContentPane.setLayout(null);
jContentPane.add(getJToolBar());
}
return jContentPane;
}
private JButton getJButton() {
if (jButton == null) {
jButton = new JButton();
jButton.setBounds(new Rectangle(4, 16, 131, 42));
jButton.setText("Select Device");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
if (scanner.isBusy() == false) {
selectDevice();
}
}
});
}
return jButton;
}
/* Select the twain source! */
public void selectDevice() {
try {
scanner.select();
} catch (ScannerIOException e1) {
IJ.error(e1.toString());
}
}
private JButton getJButton1()
{
if (jButton1 == null) {
jButton1 = new JButton();
jButton1.setBounds(new Rectangle(35,0, 30, 30));
jButton1.setText("Scan");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e)
{//jContentPane.remove(crpdpanel);
//jContentPane.removeAll();
//jContentPane.repaint();
//jContentPane.revalidate();
getScan();
}
});
}
return jButton1;
}
public void getScan()
{
try
{
//scanner = Scanner.getDevice();
//scanner.addListener(this);
scanner.acquire();
}
catch (ScannerIOException e1)
{
IJ.showMessage("Access denied! \nTwain dialog maybe already opened!");
e1.printStackTrace();
}
}
public Image getImage()
{
Image image = imp.getImage();
return image;
}
/*Image cimg;
public Image getCimg()
{
return cimg;
}*/
public void update(ScannerIOMetadata.Type type, ScannerIOMetadata metadata) {
if (type.equals(ScannerIOMetadata.ACQUIRED))
{
//imagePanel.revalidate();
//imagePanel.repaint();
//imagePanel.invalidate();
//jContentPane.remove(ipanel);
//ipanel.repaint();
if(imp!=null)
{
jContentPane.remove(ipanel);
jContentPane.remove(cpanel);
jContentPane.remove(crpdpanel);
}
imp = new ImagePlus("Scan", metadata.getImage());
//imp.show();
im = imp.getImage();
//imagePanel = new ImagePanel(im,imageWidth,imageHeight);
imagePanel = new ImagePanel(im);
imagePanel.updateUI();
imagePanel.repaint();
imagePanel.revalidate();
ClipMover mover = new ClipMover(imagePanel);
imagePanel.addMouseListener(mover);
imagePanel.addMouseMotionListener(mover);
ipanel = imagePanel.getPanel();
ipanel.setBorder(new LineBorder(Color.blue,1));
ipanel.setBorder(BorderFactory.createTitledBorder("Scanned Image"));
ipanel.setBounds(0, 30,600, 600);
ipanel.repaint();
ipanel.revalidate();
ipanel.updateUI();
jContentPane.add(ipanel);
jContentPane.getRootPane().revalidate();
jContentPane.updateUI();
//jContentPane.repaint();
// cimg=imagePanel.getCimg();
// ImagePanel cpanel = (ImagePanel) imagePanel.getUIPanel();
/*
cpanel.setBounds(700, 30,600, 800);
jContentPane.add(imagePanel.getUIPanel());
*/
cpanel = imagePanel.getUIPanel();
cpanel.setBounds(700, 30,300, 150);
cpanel.repaint();
cpanel.setBorder(new LineBorder(Color.blue,1));
cpanel.setBorder(BorderFactory.createTitledBorder("Cropping Image"));
jContentPane.add(cpanel);
jContentPane.repaint();
jContentPane.revalidate();
metadata.setImage(null);
try {
new uk.co.mmscomputing.concurrent.Semaphore(0, true).tryAcquire(2000, null);
} catch (InterruptedException e) {
IJ.error(e.getMessage());
}
}
else if (type.equals(ScannerIOMetadata.NEGOTIATE)) {
ScannerDevice device = metadata.getDevice();
try {
device.setResolution(100);
} catch (ScannerIOException e) {
IJ.error(e.getMessage());
}
try{
device.setShowUserInterface(false);
// device.setShowProgressBar(true);
// device.setRegionOfInterest(0,0,210.0,300.0);
device.setResolution(100); }catch(Exception e){
e.printStackTrace(); }
}
else if (type.equals(ScannerIOMetadata.STATECHANGE)) {
System.out.println("Scanner State "+metadata.getStateStr());
System.out.println("Scanner State "+metadata.getState());
//switch (metadata.ACQUIRED){};
ts = ((TwainIOMetadata)metadata).getSource();
//ts.setCancel(false);
//ts.getState()
//TwainConstants.STATE_TRANSFERREADY
((TwainIOMetadata)metadata).setState(6);
if ((metadata.getLastState() == 3) && (metadata.getState() == 4)){}
// IJ.error(metadata.getStateStr());
}
else if (type.equals(ScannerIOMetadata.EXCEPTION)) {
IJ.error(metadata.getException().toString());
}
}
public void stop(){ // execute before System.exit
if(scanner!=null){ // make sure user waits for scanner to finish!
scanner.waitToExit();
ts.setCancel(true);
try {
scanner.setCancel(true);
} catch (ScannerIOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I'm not an expert, but when ScannerIOMetadata.STATECHANGE shouldn't you check if the scanning is complete?
And if it is you should initialize the scanner again.
Something like that:
if (metadata.isFinished())
{
twainScanner = (TwainScanner) Scanner.getDevice();
}