Problem with Java GridLayout and adding Buttons - java

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;
}
}
}

Related

JMenuItems not responding

I have created a 3x3 memory game with colors. The program runs and displays the colors, but the JMenuBar is not working correctly. The button new board, play and end game are not working. Is there something wrong with my Actionlistener?
This is how the code should be working : https://gyazo.com/9bf3e073a9c455e56d9b4403586bfaf5?fbclid=IwAR3Zk1BZvRj49CtAz01h95zic8tk74UmyUcU2HrY3VY8XcARoD14Ke6tcoQ
This is StartPlayer
import gui.MemoryGameWindow;
import gui.ColoredPanel;
import gui.GamePanel;
public class StartPlayer {
public static void main(String[] args) {
new MemoryGameWindow();
}
}
This is ColoredPanel
package gui;
import java.awt.Color;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
public class ColoredPanel extends JPanel {
private Color thisColor = null;
private Color challenge = null;
public ColoredPanel(Color color) {
this.thisColor = color;
setBackground(color);
}
public void setGameMode(Color c, MouseListener ml) {
setBackground(Color.LIGHT_GRAY);
this.challenge = c;
System.out.println("Coloredpanel says challenge is " + this.challenge);
addMouseListener(ml);
}
public void restoreBackground() {
setBackground(this.thisColor);
}
}
This is GamePanel
package gui;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GamePanel extends JPanel {
private Color[] colors = new Color[] { Color.GREEN, Color.YELLOW, Color.MAGENTA };
private Random r = new Random();
private int square = 9;
private Color challenge;
private int countOfPossibleHits = 0;
private int countOfWinnerHits = 0;
private JPanel challengeDisplay;
public GamePanel(JPanel cd) {
this.challengeDisplay = cd;
setLayout(new GridLayout(3, 0, 2, 2));
for (int i = 0; i < this.square; i++)
add(new ColoredPanel(this.colors[this.r.nextInt(this.colors.length)]));
}
public Color startGame() {
Color[] existingColors = new Color[getComponentCount()];
int i;
for (i = 0; i < getComponentCount(); i++)
existingColors[i] = ((ColoredPanel)getComponent(i)).getBackground();
this.challenge = existingColors[this.r.nextInt(existingColors.length)];
this.countOfPossibleHits = 0;
for (i = 0; i < getComponentCount(); i++) {
if (((ColoredPanel)getComponent(i)).getBackground() == this.challenge)
this.countOfPossibleHits++;
}
for (i = 0; i < getComponentCount(); i++)
((ColoredPanel)getComponent(i)).setGameMode(this.challenge, new TheMouselistener());
return this.challenge;
}
class TheMouselistener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
ColoredPanel clickedObject = (ColoredPanel)e.getSource();
clickedObject.restoreBackground();
if (clickedObject.getBackground() != GamePanel.this.challenge) {
clickedObject.add(new JLabel("Game Over!"));
GamePanel.this.challengeDisplay.add(new JLabel("Game Over!"));
System.out.println("Game Over");
GamePanel.this.updateUI();
} else {
GamePanel.this.countOfWinnerHits = GamePanel.this.countOfWinnerHits + 1;
if (GamePanel.this.countOfWinnerHits == GamePanel.this.countOfPossibleHits) {
clickedObject.add(new JLabel("You won!"));
GamePanel.this.challengeDisplay.add(new JLabel("You Won!"));
GamePanel.this.updateUI();
}
}
}
}
}
This is MemoryGameWindow
package gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class MemoryGameWindow extends JFrame implements ActionListener {
private JMenuItem newgame = null;
private JMenuItem playgame = null;
private JMenuItem exit = null;
private GamePanel gamepanel = null;
private JPanel challengeDisplay;
public MemoryGameWindow() {
setTitle("memory game");
setLayout(new BorderLayout(5, 5));
add(this.challengeDisplay = new JPanel() {
}, "North");
add(this.gamepanel = new GamePanel(this.challengeDisplay));
setJMenuBar(new GameMenubar(this));
setSize(600, 600);
setLocationRelativeTo((Component)null);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
Object s = e.getSource();
if (s == this.newgame) {
remove(this.gamepanel);
remove(this.challengeDisplay);
add(this.challengeDisplay = new JPanel() {
}, "North");
add(this.gamepanel = new GamePanel(this.challengeDisplay));
this.playgame.setEnabled(true);
this.gamepanel.updateUI();
}
if (s == this.playgame) {
Color challenge = this.gamepanel.startGame();
this.challengeDisplay.setBackground(challenge);
this.playgame.setEnabled(false);
this.gamepanel.updateUI();
}
if (s == this.exit)
System.exit(0);
}
class GameMenubar extends JMenuBar {
public GameMenubar(MemoryGameWindow memoryGameWindow) {
JMenu file;
add(file = new JMenu("File"));
MemoryGameWindow.this.newgame = new JMenuItem("new board");
file.add(new JMenuItem("new board"));
MemoryGameWindow.this.playgame = new JMenuItem("play");
file.add(new JMenuItem("play"));
MemoryGameWindow.this.exit = new JMenuItem("end program");
file.add(new JMenuItem("end program"));
MemoryGameWindow.this.newgame.addActionListener(memoryGameWindow);
MemoryGameWindow.this.playgame.addActionListener(memoryGameWindow);
MemoryGameWindow.this.exit.addActionListener(memoryGameWindow);
}
}
}
Have a look at these two lines:
MemoryGameWindow.this.playgame = new JMenuItem("play");
file.add(new JMenuItem("play"));
First, you set the value of playgame to new JMenuItem. Later in the code, you add an ActionListener to it. That is all correct.
The problem is, the JMenuItem with the ActionListener added to it is not what you’re adding to the menu bar. Instead, you’re adding a brand new JMenuItem, which has no ActionListeners added to it.
The fix is as simple as:
file.add(MemoryGameWindow.this.playgame);
Obviously, you will need to do this for your other menu items too.

Java OpenCV Video capture cut off

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

Swing: GlassPane and the custom painted semitransparent Buttons

I have a short toolbar at the left side of my application. When user points this toolbar, I open a semitransparent full toolbar (I use GlassPane to do it). All except semitransparency works fine.
Here is the screenshot of my example program:
As you see the first button is painted correctly, but all another have completly transparent background.
Here is my code (SSCCE):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.plaf.metal.MetalLookAndFeel;
/**
* <code>FlyOutExample</code>.
*/
public class FlyOutExample implements Runnable {
private static final String[] BUTTONS = {"First button", "Second", "Another button", "Last Button", "End"};
private static final Color HT_BLUE = new Color(0, 0, 255, 160); // half transparent blue
private JPanel shortPanel = new JPanel(new GridLayout(5, 1));
private JPanel fullPanel = new JPanel(new GridLayout(5, 1));
private JPanel fullPanelWrapper = new JPanel(new BorderLayout());
private JPanel shortPanelWrapper = new JPanel(new BorderLayout());
private JFrame frm;
public static void main(String[] args) {
SwingUtilities.invokeLater(new FlyOutExample());
}
#Override
public void run() {
try {
UIManager.setLookAndFeel(MetalLookAndFeel.class.getName());
} catch (Exception e) {
e.printStackTrace();
}
for (String s : BUTTONS) {
JButton b = new JButton(s.substring(0, 1));
b.setBackground(Color.BLUE);
b.setForeground(Color.RED);
b.setUI(new BasicButtonUI());
shortPanel.add(b);
b = new JButton(s);
b.setForeground(Color.RED);
b.setOpaque(false);
b.setHorizontalAlignment(SwingConstants.LEADING);
b.setBackground(HT_BLUE);
b.setUI(new BasicButtonUI() {
#Override
public void update(Graphics g, JComponent c) {
Color old = g.getColor();
g.setColor(HT_BLUE);
g.fillRect(0, 0, c.getWidth(), c.getHeight());
g.setColor(old);
paint(g, c);
}
});
fullPanel.add(b);
}
frm = new JFrame("Flyout example");
shortPanelWrapper.setOpaque(false);
shortPanelWrapper.add(shortPanel, BorderLayout.NORTH);
JPanel bluePanel1 = new JPanel();
bluePanel1.setOpaque(true);
bluePanel1.setBackground(Color.BLUE);
shortPanelWrapper.add(bluePanel1);
fullPanel.setOpaque(false);
fullPanelWrapper.setOpaque(false);
fullPanelWrapper.add(fullPanel, BorderLayout.NORTH);
JPanel bluePanel2 = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
Color old = g.getColor();
g.setColor(HT_BLUE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(old);
}
};
bluePanel2.setOpaque(false);
fullPanelWrapper.add(bluePanel2);
MouseListener openListener = new OpenSideBarListener();
for (Component c : shortPanel.getComponents()) {
c.addMouseListener(openListener);
}
bluePanel1.addMouseListener(openListener);
MouseListener closeListener = new CloseSideBarListener();
for (Component c : fullPanel.getComponents()) {
c.addMouseListener(closeListener);
}
bluePanel2.addMouseListener(closeListener);
JPanel topPanel = new JPanel();
topPanel.setBackground(Color.GREEN);
topPanel.setPreferredSize(new Dimension(0, 30));
JPanel bottomPanel = new JPanel();
bottomPanel.setBackground(Color.GREEN);
bottomPanel.setPreferredSize(new Dimension(0, 30));
frm.add(topPanel, BorderLayout.NORTH);
frm.add(bottomPanel, BorderLayout.SOUTH);
frm.add(shortPanelWrapper, BorderLayout.WEST);
frm.add(new JScrollPane(new JTable(40, 7)));
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private void openPopup() {
if (shortPanelWrapper.getMousePosition() != null) {
Container glassPane = (Container) frm.getGlassPane();
glassPane.setLayout(null);
fullPanelWrapper.setLocation(shortPanelWrapper.getLocation());
fullPanelWrapper.setSize(140, shortPanelWrapper.getHeight());
glassPane.add(fullPanelWrapper);
glassPane.setVisible(true);
}
}
private void closePopup() {
if (fullPanelWrapper.getMousePosition() == null) {
Container glassPane = (Container) frm.getGlassPane();
glassPane.removeAll();
glassPane.setVisible(false);
}
}
private class OpenSideBarListener extends MouseAdapter {
#Override
public void mouseEntered(MouseEvent e) {
openPopup();
}
}
private class CloseSideBarListener extends MouseAdapter {
#Override
public void mouseExited(MouseEvent e) {
closePopup();
}
}
}
My JDK is: 1.8_91, OS: Windows 7
My question is: what should I do to paint all my buttons correct?
P.S. In real application I have a custom UI for all buttons present in the left toolbar, so please don't remove the UI for my buttons.
UPDATE
I've started the app again (without any changes) and got another bug
Here ist the new picture:
Probably it's a bug of my graphic card?

Display Images in JFrame from JComboBox event

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();
}

JLabel unusable from other class

I got a problem with two problematics classes. One for drawing things, and other for implementing pan and zoom onto the previously drawn objects.
Imagine my interface as only two spitted panels, one empty(top) and one with a slider(bot):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import javax.swing.JSplitPane;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JSlider;
import java.awt.FlowLayout;
public class Interface {
private JFrame mainFrame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {Interface window = new Interface();window.mainFrame.setVisible(true);
} catch (Exception e) { e.printStackTrace();}
}
});
}
public Interface() {initialize();}
private void initialize() {
mainFrame = new JFrame();
mainFrame.setTitle("LXView");
mainFrame.setMinimumSize(new Dimension(800, 600));
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setExtendedState(mainFrame.getExtendedState()| JFrame.MAXIMIZED_BOTH);
mainFrame.getContentPane().setBackground(Color.WHITE);
mainFrame.getContentPane().setLayout(new BorderLayout(0, 0));
JSplitPane splitPane = new JSplitPane();
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
splitPane.setOneTouchExpandable(true);
splitPane.setBackground(Color.WHITE);
mainFrame.getContentPane().add(splitPane, BorderLayout.CENTER);
splitPane.setResizeWeight(0.99);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setEnabled(false);
splitPane.setLeftComponent(scrollPane);
Render topPane = new Render();
scrollPane.setViewportView(topPane);
topPane.setLayout(new BoxLayout(topPane, BoxLayout.X_AXIS));
JPanel botPane = new JPanel();
splitPane.setRightComponent(botPane);
botPane.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
JLabel zoomLevel = new JLabel("Zoom level:");
botPane.add(zoomLevel);
JSlider slider = new JSlider(JSlider.HORIZONTAL, 25, 100, 100);
slider.setMajorTickSpacing(15);
slider.setMinorTickSpacing(5);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setPreferredSize(new Dimension(600,40));
botPane.add(slider);
PanAndZoom zoomer=new PanAndZoom(topPane.getLabel());
slider.addChangeListener(zoomer);
}
The top panel uses the render class which was made to draw graphics. Simplifying:
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Render extends JPanel {
JLabel envContainer;
Render() {
super();
ImageIcon imageIcon = new ImageIcon("/path/to/img1");
JLabel envContainer = new JLabel(imageIcon);
super.add(envContainer);
}
#Override
public void paint(Graphics g) {
super.paint(g);
/*Render stuff*/
}
public JLabel getLabel() {
return envContainer;
}
}
And the third class which is giving me the trouble, listens on the slider and sets the JLabel icon according to it:
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class PanAndZoom implements ChangeListener {
private JLabel label;
private BufferedImage image;
public PanAndZoom(JLabel lab){
this.label=lab;
try {
image = ImageIO.read(new File("/path/to/img1"));
} catch (IOException e) {
e.printStackTrace();
}
label.setIcon(new ImageIcon("/path/to/img2"));//To test another img. It gives runtime errors.
}
public void stateChanged(ChangeEvent e) {
int value = ((JSlider) e.getSource()).getValue();
double scale = value / 100.0;
BufferedImage scaled = getScaledImage(scale); // It also gives runtime errors.
System.out.println("Scale:"+scale+" Value:"+value);
label.setIcon(new ImageIcon(scaled));
label.revalidate();
}
private BufferedImage getScaledImage(double scale) {
int w = (int) (scale * image.getWidth());
int h = (int) (scale * image.getHeight());
BufferedImage bi = new BufferedImage(w, h, image.getType());
Graphics2D g2 = bi.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);
AffineTransform at = AffineTransform.getScaleInstance(scale, scale);
g2.drawRenderedImage(image, at);
g2.dispose();
return bi;
}
}
Why cant i use the JLabel if it was successfully returned by the getLabel method?
You're local version of envContainer in class Render's constructor is overriding the class instance envContainer.
public class Render extends JPanel {
JLabel envContainer; //<---- class instance
Render() {
super();
ImageIcon imageIcon = new ImageIcon("/path/to/img1");
JLabel envContainer = new JLabel(imageIcon); //<---- overriden by local instance, hence class instance remains null
super.add(envContainer);
}
My guess is that you didn't mean to make it a local version since you're not using it within the constructor for anything. Make the following change to your Render constructor.
Render() {
..
this.envContainer = new JLabel(imageIcon);
...
}

Categories

Resources