i am Brand new to OpenCV in java been trying to create an image capture program which both records the user and allows images to be moved to the captured image area on the GUI, my only issue is the recording seems to be cut off even when I specified a region for where it should be displayed, any help will be highly appricated.
package gesture.recognition;
import com.sun.xml.internal.ws.api.Component;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.*;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.videoio.VideoCapture;
import static org.opencv.videoio.Videoio.CV_CAP_PROP_FRAME_HEIGHT;
import static org.opencv.videoio.Videoio.CV_CAP_PROP_FRAME_WIDTH;
public class GestureRecognition extends javax.swing.JFrame {
private DaemonThread myThread = null;
int count = 0;
VideoCapture webSource = null;
Mat vid = new Mat();
MatOfByte mem = new MatOfByte();
int CANVAS_INITIAL_WIDTH =400;
int CANVAS_INITIAL_HEIGHT =500;
int Video_display=400;
int Button_Area=200;
float h,s,v;
int alpha,r,g,b;
BufferedImage img = null;
File f = null;
Mat hsv = new Mat();
class Canvas extends JPanel
{
// Called every time there is a change in the canvas contents.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
draw(g);
}
}
class DaemonThread implements Runnable
{
protected volatile boolean runnable = false;
#Override
public void run()
{
synchronized(this)
{
while(runnable)
{
if(webSource.grab())
{
try
{
webSource.retrieve(vid);
Imgcodecs.imencode(".jpg", vid, mem);
Image im = ImageIO.read(new ByteArrayInputStream(mem.toArray()));
BufferedImage buff = (BufferedImage) im;
Graphics g=freehandSliderPanel.getGraphics();
if (g.drawImage(im, 0, 0, null));
// if (g.drawImage(buff,0, 0, getWidth(), getHeight() -150 , 0 , 0, buff.getWidth(), buff.getHeight(),null))
if(runnable == false)
{
System.out.println("Going to wait()");
this.wait();
}
}
catch(IOException | InterruptedException ex)
{
System.out.println("Error");
}
}
}
}
}
}
private Canvas canvas;
private JPanel controlPanel;
private JPanel messageArea;
private JButton jButton1;
private JPanel freehandSliderPanel;
public GestureRecognition()
{
setTitle("Gesture Recognition");
setLayout(new BorderLayout()); // Layout manager for the frame.
// Canvas
canvas = new Canvas();
canvas.setBorder(new TitledBorder(new EtchedBorder(), "Video"));
canvas.setPreferredSize(new Dimension(CANVAS_INITIAL_WIDTH, CANVAS_INITIAL_HEIGHT));
add(canvas, BorderLayout.WEST);
controlPanel = new JPanel();
controlPanel.setBorder(new TitledBorder(new EtchedBorder(), "Picture"));
controlPanel.setPreferredSize(new Dimension(Video_display, CANVAS_INITIAL_HEIGHT));
// the following two lines put the control panel in a scroll pane (nicer?).
JScrollPane controlPanelScrollPane = new JScrollPane(controlPanel);
controlPanelScrollPane.setPreferredSize(new Dimension(Video_display + 30, CANVAS_INITIAL_HEIGHT));
add(controlPanelScrollPane, BorderLayout.EAST);
messageArea = new JPanel();
messageArea.setBackground(canvas.getBackground());
messageArea.setBorder(new TitledBorder(new EtchedBorder(), "Message Area"));
messageArea.setPreferredSize(new Dimension(Video_display + CANVAS_INITIAL_WIDTH, Button_Area));
add(messageArea, BorderLayout.SOUTH);
jButton1 = new JButton("Start Video");
jButton1.setPreferredSize(new Dimension(Button_Area - 10, 50));
messageArea.add(jButton1);
freehandSliderPanel = new JPanel();
freehandSliderPanel.setPreferredSize(new Dimension(CANVAS_INITIAL_WIDTH - 20, 90));
canvas.setLayout(new GridLayout(0, 1));
freehandSliderPanel.setBorder(new TitledBorder(new EtchedBorder(), "Display"));
canvas.add(freehandSliderPanel,BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
jButton1.setText("Video Capture");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
}
void draw(Graphics g)
{
}// end draw method
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
webSource =new VideoCapture(0);
myThread = new DaemonThread();
Thread t = new Thread(myThread);
t.setDaemon(true);
myThread.runnable = true;
t.start();
jButton1.setEnabled(false); //start button
// jButton2.setEnabled(true); // stop button
}
public static void main(String args[]) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
GestureRecognition GestureRecognitionInstance = new GestureRecognition();
/*Create and display the form */
/* java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
}
});
*/ }
}
So far it displays the GUI but as you can see it simply cuts off the image like so
Example image
Related
Hey all I am wondering if I can fix my animation issue.
Currently it does animate just fine but with one issue - it seems to leave training images behind as it animates.
This is my code I am using:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.io.File;
import java.io.FileInputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.io.*;
#SuppressWarnings("serial")
public class Display extends JFrame {
private static JPanel container = new JPanel();
JLabel insidePIV = new JLabel();
public static void main(String[] args) throws IOException {
Display blah = new Display();
}
public void addListeners() {
final Point offset = new Point();
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(final MouseEvent e) {
offset.setLocation(e.getPoint());
}
});
addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(final MouseEvent e) {
setLocation(e.getXOnScreen() - offset.x, e.getYOnScreen() - offset.y);
}
});
}
public Display() throws IOException {
JLabel outsidePIV = new JLabel(new ImageIcon(ImageIO.read(new File("c:/temp/pivReaderAlone.png"))));
MyJLabel antialias = new MyJLabel(
"<html><div style='text-align: center;'>Please insert your card into the reader.</div></html>");
antialias.setFont(new Font("Segoe UI", Font.BOLD, 10));
antialias.setBounds(13, 223, 170, 240);
container.setLayout(new BorderLayout());
container.setBackground(new Color(0, 0, 0, 0));
container.add(antialias, BorderLayout.CENTER);
container.add(outsidePIV, BorderLayout.CENTER);
JButton p = new JButton();
p.setText("Animate");
p.setBounds(30, 100, 120, 20);
outsidePIV.add(p, BorderLayout.CENTER);
p.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
File file = new File("c:/temp/pivbatman.gif");
Image image = Toolkit.getDefaultToolkit()
.createImage(org.apache.commons.io.IOUtils.toByteArray(new FileInputStream(file)));
ImageIcon icon = new ImageIcon(image);
outsidePIV.setDoubleBuffered(true);
outsidePIV.setIcon(icon);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
addListeners();
this.setTitle("PIV");
this.setSize(190, 390);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setAlwaysOnTop(true);
this.setUndecorated(true);
this.setBackground(new Color(0, 0, 0, 0));
this.setContentPane(container);
this.setVisible(true);
this.setResizable(false);
}
public class MyJLabel extends JLabel {
public MyJLabel(String str) {
super(str);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
super.paint(g);
}
}
}
If anyone can help me with this error then please do - been trying to fix it for hours now...
UPDATE
public static void main(String[] args) throws IOException {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
Display blah = new Display();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
Render images on Java Swing is trick, java has a main UI Thread called AWT that is not concurrent. It´s a good practice to use the method invokeLater from SwingUtilities class.
SwingUtilities.invokeLater takes a Runnable and invokes it in the UI thread later.
The syntax is:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
//some code that render in the UI here.
}
});
I want to add 100 buttons into an GridLayout and my code works but sometimes it only adds one button and if I click where the other buttons belong the button where I clicked appears.
it happens totally randomly and I don't get it.
Here is my code:
public class GamePanel extends JPanel {
GameUI controler;
GridLayout gameLayout = new GridLayout(10,10);
JButton gameButtons[] = new JButton[100];
ImageIcon ice;
JButton startButton;
JButton exitButton;
ImageIcon startIcon;
ImageIcon exitIcon;
URL urlIcon;
private int i;
public GamePanel(GameUI controler) {
this.setLayout(gameLayout);
this.controler = controler;
urlIcon = this.getClass().getResource("/icons/Overlay.png");
ice = new ImageIcon(urlIcon);
makeButtons();
}
#Override
public void paint(Graphics g) {
super.paint(g);
}
public void makeButtons() {
for(i = 0; i< 100; i++) {
gameButtons[i] = new JButton(ice);
this.add(gameButtons[i]);
revalidate();
}
repaint();
}
}
update:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.net.URL;
public class GameUI extends JFrame {
ImageIcon i;
Image jFrameBackground;
JButton startButton;
JButton exitButton;
ImageIcon startIcon;
ImageIcon exitIcon;
public GameUI() {
setResizable(false);
this.setSize(1200, 800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
BackGroundPanel backGroundPanel = new BackGroundPanel();
GamePanel panel = new GamePanel(this);
ButtonPanel buttonPanel = new ButtonPanel();
panel.setSize(500,500);
panel.setLocation(100, 150);
backGroundPanel.setSize(this.getWidth(),this.getHeight());
backGroundPanel.setLocation(0,0);
buttonPanel.setSize(390,50);
buttonPanel.setLocation(100,100);
this.add(backGroundPanel);
this.add(panel);
this.add(buttonPanel);
backGroundPanel.setBackground(Color.BLACK);
}
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
javax.swing.SwingUtilities.invokeAndWait(
new Runnable(){
#Override
public void run() {
GameUI ui = new GameUI();
ui.setVisible(true);
}
}
);
}
}
As I mentioned in comments, you're using a null layout, and this is the source of your problems.
You're using the null layout to try to layer JPanels, one on top of the other, and that is not how it should be used or what it is for, nor how you should create backgrounds. This is having the effect of the background covering your buttons until your mouse hovers over them.
Instead if you wish to create a background image, I would recommend that you:
create a JPanel, say called BackgroundPanel,
override its paintComponent method,
call its super.paintComponent(g); on your method's first line
then draw the image it should display
then give it a decent layout manager
and add your GUI components to it
Make sure that any JPanels added to it are made transparent via .setOpaque(false)
Other options include using a JLayeredPane, but you really don't need this just to have a background.
For example, the following code produces:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class GameUI2 {
private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/3/3f/"
+ "Butterfly_Nebula_in_narrow_band_Sulfur%2C_Hydrogen_and_Oxygen_Stephan_Hamel.jpg";
private static final String BTN_IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/5/54/Crystal_Project_Games_kids.png";
private static void createAndShowGui() {
BufferedImage bgImg = null;
BufferedImage btnImg = null;
try {
URL bgImgUrl = new URL(IMG_PATH);
URL btnImgUrl = new URL(BTN_IMG_PATH);
bgImg = ImageIO.read(bgImgUrl);
btnImg = ImageIO.read(btnImgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
BackgroundPanel2 mainPanel = new BackgroundPanel2(bgImg);
mainPanel.setLayout(new GridBagLayout());
GamePanel2 gamePanel = new GamePanel2(btnImg);
mainPanel.add(gamePanel);
JFrame frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class BackgroundPanel2 extends JPanel {
private Image backgroundImg;
public BackgroundPanel2(Image backgroundImg) {
this.backgroundImg = backgroundImg;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImg != null) {
g.drawImage(backgroundImg, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || backgroundImg == null) {
return super.getPreferredSize();
} else {
int w = backgroundImg.getWidth(this);
int h = backgroundImg.getHeight(this);
return new Dimension(w, h);
}
}
}
#SuppressWarnings("serial")
class GamePanel2 extends JPanel {
public static final int MAX_BUTTONS = 100;
private static final int IMG_WIDTH = 40;
JButton[] gameButtons = new JButton[MAX_BUTTONS];
public GamePanel2(Image buttonImg) {
setOpaque(false);
if (buttonImg.getWidth(this) > IMG_WIDTH) {
buttonImg = buttonImg.getScaledInstance(IMG_WIDTH, IMG_WIDTH, Image.SCALE_SMOOTH);
}
Icon icon = new ImageIcon(buttonImg);
setLayout(new GridLayout(10, 10, 4, 4));
for (int i = 0; i < gameButtons.length; i++) {
int finalIndex = i;
JButton btn = new JButton(icon);
btn.addActionListener(e -> {
String text = String.format("Button: %02d", finalIndex);
System.out.println(text);
});
add(btn);
gameButtons[i] = btn;
}
}
}
The resize and flip functions are supposed to produce the resulting image in the left panel. However, the resize function just produces the same image and the flip function gives a blacked out image. How do I fix this?
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;
public class ImgViewTester extends JFrame implements ActionListener
{
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem openItem = new JMenuItem("Open Image...");
JLabel imgLabel = new JLabel();
JLabel newImgLabel = new JLabel();
JPanel lblPanel = new JPanel();
JButton resizeBtn = new JButton("Resize");
JButton flipBtn = new JButton("Flip");
JPanel imagePanel;
JPanel btnPanel;
JPanel resizePanel;
JTextField widthTxt = new JTextField(10);
JTextField heightTxt = new JTextField(10);
JFileChooser fc = new JFileChooser();
File imgFile;
String imgFileName;
String imgTitle;
Image img;
//BufferedImage buffImg;
Graphics2D g2d;
Graphics gb;
public ImgViewTester()
{
initialize();
}
public void initialize()
{
this.setTitle("Image Editor");
this.setSize(700, 700);
this.setLayout(new BorderLayout());
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
setJMenuBar(menuBar);
menuBar.add(fileMenu);
fileMenu.add(openItem);
openItem.addActionListener(this);
imgLabel.setPreferredSize(new Dimension(500, 500));
newImgLabel.setPreferredSize(new Dimension(500, 500));
imagePanel = new JPanel();
imagePanel.add(imgLabel);
imagePanel.add(newImgLabel);
btnPanel = new JPanel();
btnPanel.add(resizeBtn);
btnPanel.add(flipBtn);
resizeBtn.addActionListener(this);
flipBtn.addActionListener(this);
resizePanel = new JPanel();
resizePanel.add(widthTxt);
resizePanel.add(heightTxt);
this.add(imagePanel, BorderLayout.CENTER);
this.add(btnPanel, BorderLayout.SOUTH);
this.add(resizePanel, BorderLayout.NORTH);
this.pack();
}
public static void main(String[] args){
new ImgViewTester();
}
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals(openItem))
{
JFileChooser imgFileChooser = new JFileChooser();
FileNameExtensionFilter imgFilter =
new FileNameExtensionFilter("GIF, PNG, JPEG or JPG files",
"gif", "png", "jpg", "jpeg");
imgFileChooser.setFileFilter(imgFilter);
int returnVal = imgFileChooser.showOpenDialog(null);
imgFile = imgFileChooser.getSelectedFile();
//variables for getting name of image
imgFileName = imgFile.getName();
imgTitle = imgFileName.substring(imgFileName.lastIndexOf("/") + 1);
if(returnVal == JFileChooser.APPROVE_OPTION)
{
try
{
img = ImageIO.read(imgFile);
img = img.getScaledInstance(500, -1, Image.SCALE_DEFAULT);
imgLabel.setIcon(new ImageIcon(img));
}
catch(IOException ioe)
{
System.out.println("Oops! Image I/O exception occurred!");
ioe.printStackTrace();
}
}
else if(returnVal == JFileChooser.CANCEL_OPTION)
{
System.out.println("Operation Cancelled!");
}
}
else if(e.getSource().equals(resizeBtn))
{
int newWidth= Integer.parseInt(widthTxt.getText());
int newHeight = Integer.parseInt(heightTxt.getText());
img.getScaledInstance(newWidth, newHeight, Image.SCALE_DEFAULT);
newImgLabel.setIcon(new ImageIcon(img));
System.out.println(imgFileName);
}
else if(e.getSource().equals(flipBtn))
{
ImageIcon currIcon = (ImageIcon)imgLabel.getIcon();
BufferedImage buffImg = new BufferedImage(currIcon.getIconWidth(), currIcon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
tx.translate(-buffImg.getWidth(null), 0);
AffineTransformOp op = new AffineTransformOp(tx,AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
buffImg = op.filter(buffImg, null);
newImgLabel.setIcon(new ImageIcon(buffImg));
System.out.println(newImgLabel);
}
}
}//end of class
img.getScaledInstance(newWidth, newHeight, Image.SCALE_DEFAULT);
imgLabel.setIcon(new ImageIcon(img));
Should be:
Image scaled = img.getScaledInstance(newWidth, newHeight, Image.SCALE_DEFAULT);
imgLabel.setIcon(new ImageIcon(scaled));
Whenever I've done a flip before I have done the translate before the scale:
import java.awt.*;
import javax.swing.*;
class MirrorImageIcon extends ImageIcon
{
public MirrorImageIcon(String filename)
{
super(filename);
}
#Override
public void paintIcon(Component c, Graphics g, int x, int y)
{
Graphics2D g2 = (Graphics2D)g.create();
g2.translate(0, getIconHeight());
g2.scale(1, -1);
super.paintIcon(c, g2, x, y);
g2.dispose();
}
private static void createAndShowUI()
{
ImageIcon io = new MirrorImageIcon("dukewavered.gif");
JLabel label = new JLabel(io);
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label, BorderLayout.SOUTH);
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
I want to achieve following functionality :
Eg :
When user selects "Profile Pic"item from JComboBox releted images from "Profile Pic" folder should be loaded on same frame.
Again when user selects "Product Img" item related images from "Product Img" folder should be loaded replacing previous images.
Following is code snippet , please suggest any changes
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class NewClass1 {
public static void main(String[] args) {
createAndShowJFrame();
}
public static void createAndShowJFrame() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = createJFrame();
frame.setVisible(true);
}
});
}
private static JFrame createJFrame() {
JFrame frame = new JFrame();
//frame.setResizable(false);//make it un-resizeable
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Test");
ArrayList<BufferedImage> images = null;
try {
images = getImagesArrayList();
} catch (Exception ex) {
ex.printStackTrace();
}
final ImageViewPanel imageViewPanel = new ImageViewPanel(images);
JScrollPane jsp = new JScrollPane(imageViewPanel);
jsp.setPreferredSize(new Dimension(400, 400));
frame.add(jsp);
final javax.swing.JComboBox filter = new javax.swing.JComboBox<>();
filter.addItem("All");
filter.addItem("Profile Pic");
filter.addItem("Company Logo");
filter.addItem("Product Img");
JPanel controlPanel = new JPanel();
JButton addLabelButton = new JButton("Delete Selected Image");
addLabelButton.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
imageViewPanel.removeFocusedImageLabel();
}
});
JLabel label =new JLabel("Filter By :");
filter.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
String cat=(String) filter.getSelectedItem();
createJFrame(cat);
}
});
controlPanel.add(addLabelButton);
controlPanel.add(label);
controlPanel.add(filter);
frame.add(controlPanel, BorderLayout.NORTH);
frame.pack();
return frame;
}
private static ArrayList<BufferedImage> getImagesArrayList(String cat) throws Exception {
System.out.println(cat);
ArrayList<BufferedImage> images = new ArrayList<>();
if(cat.equals("Profile Pic"))
images.add(resize(ImageIO.read(new URL("http://192.168.1.25:8080/pic/ProfilePic/1.jpg")), 100, 100));
else if(cat.equals("Product Img"))
{
images.add(resize(ImageIO.read(new URL("http://192.168.1.25:8080/pic/ProductImg/2.jpg")), 100, 100));
}
return images;
}
private static ArrayList<BufferedImage> getImagesArrayList() throws Exception {
ArrayList<BufferedImage> images = new ArrayList<>();
images.add(resize(ImageIO.read(new URL("http://localhost:8080/pic/All/a.jpg")), 100, 100));
images.add(resize(ImageIO.read(new URL("http://localhost:8080/pic/All/b.jpg")), 100, 100));
return images;
}
public static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
}
}
I would urge you to have another look at the code I posted (which you seem to be using) Deleting images from JFrame.
However:
In your code I see:
filter.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
String cat=(String) filter.getSelectedItem();
createJFrame(cat);
}
});
I cannot even find the method createJFrame(String cat);?
As far as I see you should be doing this:
filter.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
String cat=(String) filter.getSelectedItem();
ArrayList<BufferedImage> images=getImagesArrayList(cat);//get the new images for the selected item in combo
//refresh the layout by removing old pics and itertating the new array and adding pics to the panel as you iterate
layoutLabels(images);
}
});
....
private JLabel NO_IMAGES=new JLabel("No Images");
private void layoutLabels(ArrayList<BufferedImage> images) {
removeAll();//remove all components from our panel (the panel should only have the images on if not use setActionCommand("Image") on your images/JLabels and than use getComponents of JPanel and iterate through them looking for getActionCommand.equals("Image")
if (images.isEmpty()) {//if the list is empty
add(NO_IMAGES);//add Jlabel to show message of no images
} else {
remove(NO_IMAGES);
for (BufferedImage i : images) {//iterate through ArrayList of images
add(new JLabel(new ImageIcon(i)));//add each to the panel using JLabel as container for image
}
}
revalidate();
repaint();
}
My problem here is,
after clicking Browse button it displays all files in a directory to choose,
then the chosen image is displayed in GUI correctly. But When i click Browse button
for the second time, it shows the old image only instead of showing the new one. Please help me in this.
For reference, i uploaded the UI.
package GUI;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
#SuppressWarnings("serial")
public class MainAppFrame extends JFrame {
private JPanel contentPane;
File targetFile;
BufferedImage targetImg;
public JPanel panel,panel_1;
private static final int baseSize = 128;
private static final String basePath =
"C:\\Documents and Settings\\Administrator\\Desktop\\Images";
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainAppFrame frame = new MainAppFrame();
frame.setVisible(true);
frame.setResizable(false);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public MainAppFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 550, 400);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
panel = new JPanel();
panel.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true));
contentPane.add(panel, BorderLayout.WEST);
JButton btnBrowse = new JButton("Browse");
btnBrowse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
browseButtonActionPerformed(e);
}
});
JLabel lblSelectTargetPicture = new JLabel("Select target picture..");
JButton btnDetect = new JButton("Detect");
btnDetect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
JButton btnAddDigit = new JButton("Add Digit");
btnAddDigit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
JButton button = new JButton("Recognize");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
panel_1 = new JPanel();
panel_1.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true));
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(6)
.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addComponent(lblSelectTargetPicture)
.addGap(6)
.addComponent(btnBrowse))
.addGroup(gl_panel.createSequentialGroup()
.addGap(10)
.addComponent(btnDetect)
.addGap(18)
.addComponent(btnAddDigit))))
.addGroup(gl_panel.createSequentialGroup()
.addGap(50)
.addComponent(button))
.addGroup(gl_panel.createSequentialGroup()
.addContainerGap()
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 182, GroupLayout.PREFERRED_SIZE))
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(7)
.addComponent(lblSelectTargetPicture))
.addGroup(gl_panel.createSequentialGroup()
.addGap(3)
.addComponent(btnBrowse)))
.addGap(18)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 199, GroupLayout.PREFERRED_SIZE)
.addGap(22)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(btnDetect)
.addComponent(btnAddDigit))
.addGap(18)
.addComponent(button)
.addContainerGap())
);
panel.setLayout(gl_panel);
}
public BufferedImage rescale(BufferedImage originalImage)
{
BufferedImage resizedImage = new BufferedImage(baseSize, baseSize, BufferedImage.TYPE_INT_RGB);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, baseSize, baseSize, null);
g.dispose();
return resizedImage;
}
public void setTarget(File reference)
{
try {
targetFile = reference;
targetImg = rescale(ImageIO.read(reference));
} catch (IOException ex) {
Logger.getLogger(MainAppFrame.class.getName()).log(Level.SEVERE, null, ex);
}
panel_1.setLayout(new BorderLayout(0, 0));
panel_1.add(new JLabel(new ImageIcon(targetImg)));
setVisible(true);
}
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser fc = new JFileChooser(basePath);
fc.setFileFilter(new JPEGImageFileFilter());
int res = fc.showOpenDialog(null);
// We have an image!
try {
if (res == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
setTarget(file);
} // Oops!
else {
JOptionPane.showMessageDialog(null,
"You must select one image to be the reference.", "Aborting...",
JOptionPane.WARNING_MESSAGE);
}
} catch (Exception iOException) {
}
}
}
//JPEGImageFileFilter.java
package GUI;
import java.io.File;
import javax.swing.filechooser.FileFilter;
/*
* This class implements a generic file name filter that allows the listing/selection
* of JPEG files.
*/
public class JPEGImageFileFilter extends FileFilter implements java.io.FileFilter
{
public boolean accept(File f)
{
if (f.getName().toLowerCase().endsWith(".jpeg")) return true;
if (f.getName().toLowerCase().endsWith(".jpg")) return true;
if(f.isDirectory())return true;
return false;
}
public String getDescription()
{
return "JPEG files";
}
}
Each time a new image is selected, you're creating components unnecessarily and in error here:
public void setTarget(File reference) {
//....
panel_1.setLayout(new BorderLayout(0, 0));
panel_1.add(new JLabel(new ImageIcon(targetImg)));
setVisible(true);
Instead I would recommend that you have all these components created from the get-go, before any file/image has been selected, and then in this method, create an ImageIcon from the Image, and then simply use this Icon to set the Icon of an already existng JLabel rather than a new JLabel. This is done simply by calling myLabel.setIcon(new ImageIcon(targetImg));
Create an ImageViewer with method like ImageViewer.setImage(Image), display the image in a JLabel.
ImageViewer
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.util.Random;
public class ImageViewer {
JPanel gui;
/** Displays the image. */
JLabel imageCanvas;
/** Set the image as icon of the image canvas (display it). */
public void setImage(Image image) {
imageCanvas.setIcon(new ImageIcon(image));
}
public void initComponents() {
if (gui==null) {
gui = new JPanel(new BorderLayout());
gui.setBorder(new EmptyBorder(5,5,5,5));
imageCanvas = new JLabel();
JPanel imageCenter = new JPanel(new GridBagLayout());
imageCenter.add(imageCanvas);
JScrollPane imageScroll = new JScrollPane(imageCenter);
imageScroll.setPreferredSize(new Dimension(300,100));
gui.add(imageScroll, BorderLayout.CENTER);
}
}
public Container getGui() {
initComponents();
return gui;
}
public static Image getRandomImage(Random random) {
int w = 100 + random.nextInt(400);
int h = 50 + random.nextInt(200);
BufferedImage bi = new BufferedImage(
w,h,BufferedImage.TYPE_INT_RGB);
return bi;
}
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
#Override
public void run() {
JFrame f = new JFrame("Image Viewer");
// TODO Fix kludge to kill the Timer
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ImageViewer viewer = new ImageViewer();
f.setContentPane(viewer.getGui());
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
ActionListener animate = new ActionListener() {
Random random = new Random();
#Override
public void actionPerformed(ActionEvent arg0) {
viewer.setImage(getRandomImage(random));
}
};
Timer timer = new Timer(1500,animate);
timer.start();
}
};
SwingUtilities.invokeLater(r);
}
}
I modified your code , I hope it will fulfill your requirement. I use MigLayout (it is a Layout manager) to arrange the component.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
public class MyFileChooser
{
JFrame frame;
JPanel panel;
JButton btnBrowse;
JButton change;
JLabel imglabel;
File targetFile;
BufferedImage targetImg;
private static final int baseSize = 128;
private static final String basePath ="/images/fimage";
JPanel panel_1;
ImageIcon icon;
public MyFileChooser()
{
// TODO Auto-generated constructor stub
frame =new JFrame();
frame.setLayout(new MigLayout());
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel=new JPanel(new MigLayout());
panel_1 = new JPanel();
panel_1.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(5, 5, 5), 1, true));
panel_1.setBackground(Color.pink);
btnBrowse=new JButton("browse");
btnBrowse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
browseButtonActionPerformed(e);
}
});
change=new JButton("Delete");
change.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
changeButtonActionPerformed(e);
}
private void changeButtonActionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
imglabel.revalidate(); //ADD THIS AS WELL
imglabel.repaint(); //ADD THIS AS WELL
imglabel.setIcon(null);
System.out.println("delete button activated");
}
});
imglabel=new JLabel("Image");
imglabel.setSize(100, 100);
imglabel.setBackground(Color.yellow);
frame.add(panel_1,"span,pushx,pushy,growx,growy");
frame.add(btnBrowse);
frame.add(change,"");
//frame.pack();
}
protected void browseButtonActionPerformed(ActionEvent e)
{
JFileChooser fc = new JFileChooser(basePath);
fc.setFileFilter(new JPEGImageFileFilter());
int res = fc.showOpenDialog(null);
// We have an image!
try {
if (res == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
imglabel.setIcon(null);
setTarget(file);
} // Oops!
else {
JOptionPane.showMessageDialog(null,
"You must select one image to be the reference.", "Aborting...",
JOptionPane.WARNING_MESSAGE);
}
} catch (Exception iOException) {
}
}
public BufferedImage rescale(BufferedImage originalImage)
{
BufferedImage resizedImage = new BufferedImage(baseSize, baseSize, BufferedImage.TYPE_INT_RGB);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, baseSize, baseSize, null);
g.dispose();
return resizedImage;
}
public void setTarget(File reference)
{
try {
targetFile = reference;
targetImg = rescale(ImageIO.read(reference));
} catch (IOException ex) {
// Logger.getLogger(MainAppFrame.class.getName()).log(Level.SEVERE, null, ex);
}
panel_1.setLayout(new BorderLayout(0, 0));
icon=new ImageIcon(targetImg);
imglabel=new JLabel(icon);
panel_1.add(imglabel);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
new MyFileChooser();
}
});
}
}
JPEGImageFileFilter class , you can keep this class in same pakage
import java.io.File;
import javax.swing.filechooser.FileFilter;
public class JPEGImageFileFilter extends FileFilter implements FileFilter
{
public boolean accept(File f)
{
if (f.getName().toLowerCase().endsWith(".jpeg")) return true;
if (f.getName().toLowerCase().endsWith(".jpg")) return true;
if(f.isDirectory())return true;
return false;
}
public String getDescription()
{
return "JPEG files";
}
}