Why arent the squares being painted? - java

I started a Chess Project reusing some older code to paint a map everything basically has been copy pasted. The problem is the squares dont show up? I tried fixing it for a while now and got to no solution. Here are probably the three most important methods and a zip with the whole project. Some of it is in German.
https://drive.google.com/file/d/1nnZHLB0Ycy04eMyYbEmduMwbGhVLZ2VB/view?usp=sharing
public SchachFrame() {
super();
contentPane = new JPanel();
setContentPane(contentPane);
setBounds(0, 0, window.width, window.height);
contentPane.setBackground(Color.darkGray);
contentPane.setVisible(true);
ge = new GameEnvironment(this);
ge.setBounds(window.width/2 - 500, window.height/2 - 500, 1000, 1000);
ge.setVisible(true);
contentPane.add(ge);
Thread gameEnvironment = new Thread(ge);
gameEnvironment.start();
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void createMap(int width, int length, GameEnvironment ge) {
map = new Spielfeld[length][width];
Spielfeld.width = 1000/width;
Spielfeld.height = 1000/length;
for(int i = 0; i < length; i++) {
for(int j = 0; j < width; j++) {
this.map[i][j] = new Spielfeld(j, i, null);
this.map[i][j].setBounds(ge.getX() + j * Spielfeld.width, ge.getY() + i * Spielfeld.height, Spielfeld.width, Spielfeld.height);
this.map[i][j].setVisible(true);
ge.add(this.map[i][j]);
}
}
}
public void paintComponent(Graphics g) {
if((this.px + this.py) % 2 == 0) {
g.setColor(Color.blue);
} else {
g.setColor(Color.cyan);
}
g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
repaint();
}

Do not call repaint() in paintComponent. Otherwise you will never exit the EDT and lock up your code. And the first statement in paintComponent(Graphics g) should be super.paintComponent(g);
Updated to include an example
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DrawSquareComponent extends JPanel {
static int WIDTH = 600;
static int HEIGHT = 600;
JFrame frame = new JFrame();
public static void main(String[] args) {
new DrawSquareComponent().start();
}
public void start() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
setBackground(Color.white);
MyComponent my =new MyComponent();
add(my); // add my component to panel
Random r = new Random();
for (int i = 0; i < 20; i++) {
int size = r.nextInt(50)+50;
int x = r.nextInt(WIDTH-size)+1;
int y = r.nextInt(HEIGHT-size)+1;
my.setBounds(x,y,size,size);
frame.repaint();
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
}
}
}
public Dimension getPreferredSize() {
return new Dimension(WIDTH, HEIGHT);
}
}
class MyComponent extends JPanel {
#Override
public void paintComponent(Graphics g) {
Graphics gg = g.create();
super.paintComponent(gg);
// location relative to parent's.
// used to check location in parent's coordinate space.
Point p = getLocation();
if ((p.x + p.y) % 2 == 0) {
gg.setColor(Color.blue);
} else {
gg.setColor(Color.cyan);
}
// paint this component so location is always 0,0.
// all you're doing is painting this squares background
gg.fillRect(0,0, this.getWidth(), this.getHeight());
gg.dispose();
}
}

Related

G2D updating with lists of coordinates

I want to make a program to simulate ants.Let's say I have 100 ants and every one of them has coordinates (2 integers). I use the Java Graphics (Graphics2D).
Now I want a class that reads a list like that:
List<List<Integer>> list = new ArrayList();
This list has for example:
[100,200],[200,100]
as coordinates in it. Now I want the class to update al the time and delete all "dots" (ants) and after that draw them new with the coordinates out of the List.
Right now this won't work.
public class FrameHandler {
Panel panel = new Panel();
public FrameHandler() {
//initialize frame
frame.repaint();
List<List<Integer>> test = new ArrayList();
List<Integer> t1 = new ArrayList();
t1.add(100);
t1.add(200);
test.add(gunther);
frame.add(panel);
panel.setList(test);
//the thread sleeps for 5 seconds
List<Integer> t2 = new ArrayList();
t2.add(100);
t2.add(100);
test.add(gunther2);
panel.removeAll();
panel.setList(olaf);
}
public void setList(List<Integer> list) {
panel.setList(list);
}
public void setSize(int width, int height) {
frame.setSize(width, height);
}
private class Panel extends JPanel {
List<List<Integer>> antList = new ArrayList();
private void doDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for(int i = 0; i < antList.size(); i++) {
g2d.fillRect(antList.get(i).get(0), antList.get(i).get(1), 2, 2);
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
public void setList(List<List<Integer>> list) {
antList = list;
}
}
}
If you have another idea how to solve the problem, maybe with an API or another method of doing graphics I would be happy to hear it.
Now I want the class to update al the time and delete all "dots" (ants) and after that draw them new with the coordinates out of the List.
This is basically how painting works in Swing, on each paint cycle, you are expected to repaint the entire state of the component from scratch. See Painting in AWT and Swing for more details.
So the question becomes, how do you update the List. While there are a number ways you might do this, using a Swing Timer might be the simplest (and generally the safest). See How to use Swing Timers for more details.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FrameHandler {
public static void main(String[] args) {
new FrameHandler();
}
public FrameHandler() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
protected static final Random RANDOM_DELTA = new Random();
private List<List<Integer>> ants;
public TestPane() {
Random rnd = new Random();
ants = new ArrayList<>(25);
for (int index = 0; index < 10; index++) {
List<Integer> ant = new ArrayList<>(2);
// You should also have a look at the java.awt.Point class :P
ant.add(rnd.nextInt(200 - 2)); //x
ant.add(rnd.nextInt(200 - 2)); //y
ants.add(ant);
}
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (List<Integer> ant : ants) {
int xDelta = randomDelta();
int yDelta = randomDelta();
int x = ant.get(0) + xDelta;
int y = ant.get(1) + yDelta;
if (x < 0) {
x = 0;
} else if (x + 2 > getWidth()) {
x = getWidth() - 2;
}
if (y < 0) {
y = 0;
} else if (y + 2 > getHeight()) {
y = getHeight() - 2;
}
ant.set(0, x);
ant.set(1, y);
}
repaint();
}
});
timer.start();
}
protected int randomDelta() {
int delta = 0;
do {
double rnd = Math.random();
delta = rnd < 0.5d ? -1 : 1;
} while (delta == 0);
return delta;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (List<Integer> ant : ants) {
g2d.fillRect(ant.get(0), ant.get(1), 2, 2);
}
g2d.dispose();
}
}
}
This example basically generates a random delta (change in direction) for each ant's x & y coordinate. I suspect you might need to have something a little more sophisticated

Removing a rectangle with color on mouse release

I am developing a game and in some part of my game I want the rectangle to disappear on mouse release. I have placed 26 rectangles in an arrayList and remove the particular rectangle clicked as the mouse is released. So if I remove the fill methods, the rectangle disappears successfully but if the fill methods are there, it does not work anymore.
Here is my paint method:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Image img = Toolkit.getDefaultToolkit().getImage(Rectangles2.class.getResource("background.jpg"));
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle s : rectanglesList) {
g2.draw(s);
}
g2.setColor(bColor);
g2.fill(box1);
g2.fill(box2);
g2.fill(box3);
g2.fill(box4);
g2.fill(box5);
g2.fill(box6);
g2.fill(box7);
g2.fill(box8);
g2.fill(box9);
g2.fill(box10);
g2.fill(box11);
g2.fill(box12);
g2.fill(box25);
g2.setColor(wColor);
g2.fill(box13);
g2.fill(box14);
g2.fill(box15);
g2.fill(box16);
g2.fill(box17);
g2.fill(box18);
g2.fill(box19);
g2.fill(box20);
g2.fill(box21);
g2.fill(box22);
g2.fill(box23);
g2.fill(box24);
g2.fill(box26);
}
Here is how I did the removing of the rectangle (Just an excerpt):
if (box1.getBounds().contains(x, y)) {
pickedPanelNum = 0;
rectanglesList.remove(box1);
panelsPane.repaint();
}
Here are the values of the bColor and wColor:
Color bColor = Color.BLACK;
Color wColor = Color.WHITE;
NOTE:
The pickedPanelNum is just for assigning an int value and has no connection to the problem.
I think it is because when I repaint, the fill methods are still there. However I have no idea for an alternate way of painting the rectangles.
I hope my problem is stated clearly. If you have ideas how I could solve this, please tell me. Thank you!
UPDATE:
Here is a shorter, runnable version of my program. (Background image isn't included though):
import java.awt.*;
import java.awt.Color.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.geom.Rectangle2D;
public class Rec extends JComponent
{
public ArrayList<Rectangle> rectanglesList = new ArrayList<Rectangle>();
public int arrx[] = new int[120];
public int arry[] = new int[120];
JFrame frame = new JFrame();
public int xSize = 2000;
public int ySize = 1000;
public int x;
public int y;
public int pickedPanelNum = 0;
public String pickedPanelDash = "";
public String pickedPanelColor = "";
Color bColor = Color.BLACK;
Color wColor = Color.WHITE;
boolean removedPanel = false;
public void launchFrame()
{
Random rand = new Random();
for(int x = 0;x<120;x++)
{
arrx[x] = rand.nextInt(640);
arry[x] = rand.nextInt(590);
}
Rectangle box1 = new Rectangle(arrx[103],arry[59],80,90);
Rectangle box2 = new Rectangle(arrx[105],arry[3],80,90);
rectanglesList.add(box1);
rectanglesList.add(box2);
JPanel mainPanel = new JPanel();
JPanel panelsPane = new JPanel()
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Image img = Toolkit.getDefaultToolkit().getImage(Rectangles2.class.getResource("background.jpg"));
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle s : rectanglesList) {
g2.draw(s);
}
g2.setColor(bColor);
g2.fill(box1);
g2.setColor(wColor);
g2.fill(box2);
}
};
JPanel rightPane = new JPanel();
panelsPane.addMouseListener (new MouseAdapter ()
{
public void mousePressed(MouseEvent event)
{
x = event.getX();
y = event.getY();
}
public void mouseReleased(MouseEvent event)
{
if (box1.getBounds().contains(x, y)) {
pickedPanelNum = 0;
rectanglesList.remove(box1);
panelsPane.repaint();
}
if (box2.getBounds().contains(x, y)) {
pickedPanelNum = 1;
rectanglesList.remove(box2);
panelsPane.repaint();
}
}
});
panelsPane.addMouseMotionListener (new MouseAdapter ()
{
public void mouseDragged(MouseEvent event)
{
Rec obj = new Rec();
int dx = event.getX() - x;
int dy = event.getY() - y;
if (box1.getBounds().contains(x, y)) {
box1.x += dx;
box1.y += dy;
panelsPane.repaint();
}
if (box2.getBounds().contains(x, y)) {
box2.x += dx;
box2.y += dy;
panelsPane.repaint();
}
x += dx;
y += dy;
}
public void mouseReleased(MouseEvent event) {}
public void mouseClicked(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
});
panelsPane.setPreferredSize(new Dimension (800, ySize-315));
rightPane.setPreferredSize(new Dimension (530, ySize-315));
mainPanel.setPreferredSize(new Dimension (xSize, ySize));
frame.setPreferredSize(new Dimension (xSize, ySize));
rightPane.setBackground(Color.gray);
mainPanel.add(panelsPane);
mainPanel.add(rightPane);
frame.add(mainPanel);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
}
public static void main(String args[])
{
Rec obj = new Rec();
obj.launchFrame();
}
}
Even if you remove box1 from the List, there is nothing stopping it from getting filled in your paintComponent method, the for-loop is only drawing the outline of the rectangles within the list, but you code implicitly fills them anyway.
So, first, get rid of all the box{n} variables. Next change the paintComponent method...
public void paintComponent(Graphics g) {
super.paintComponent(g);
//Image img = Toolkit.getDefaultToolkit().getImage(Rectangles2.class.getResource("background.jpg"));
//g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle s : rectanglesList) {
g2.setColor(bColor);
g2.fill(s);
g2.setColor(wColor);
g2.draw(s);
}
}
So, this just uses the rectanglesList to first draw the rectangles and the fill them
Then, lets update the mouseReleased...
public void mouseReleased(MouseEvent event) {
// Because the rectangles are painted in order, the later
// rectangles are painted over the eailer ones, so, we reverse
// the list so we can check for the higher positioned
// rectangles
List<Rectangle> copy = new ArrayList<>(rectanglesList);
Collections.reverse(copy);
for (Rectangle r : copy) {
if (r.contains(event.getPoint())) {
rectanglesList.remove(r);
break;
}
}
event.getComponent().repaint();
}
Okay, this is little more funky, but basically, we reverse the list of rectangles (because those rectangles that appear later in the list are painted over those that appear before them) and checks to see if the mouse was clicked within any one of them. The moment we find a match, we break out of the loop and repaint the component which generated the event
And, because it's nice to see this stuff running, a complete example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Rec extends JComponent {
public ArrayList<Rectangle> rectanglesList = new ArrayList<Rectangle>();
public int arrx[] = new int[120];
public int arry[] = new int[120];
JFrame frame = new JFrame();
public int xSize = 2000;
public int ySize = 1000;
public int x;
public int y;
public int pickedPanelNum = 0;
public String pickedPanelDash = "";
public String pickedPanelColor = "";
Color bColor = Color.BLACK;
Color wColor = Color.WHITE;
boolean removedPanel = false;
public void launchFrame() {
Random rand = new Random();
for (int x = 0; x < 10; x++) {
arrx[x] = rand.nextInt(640);
arry[x] = rand.nextInt(590);
rectanglesList.add(new Rectangle(arrx[x], arry[x], 80, 90));
}
JPanel mainPanel = new JPanel();
JPanel panelsPane = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Image img = Toolkit.getDefaultToolkit().getImage(Rectangles2.class.getResource("background.jpg"));
// g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle s : rectanglesList) {
g2.setColor(bColor);
g2.fill(s);
g2.setColor(wColor);
g2.draw(s);
}
}
};
JPanel rightPane = new JPanel();
panelsPane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
x = event.getX();
y = event.getY();
}
public void mouseReleased(MouseEvent event) {
// Because the rectangles are painted in order, the later
// rectangles are painted over the eailer ones, so, we reverse
// the list so we can check for the higher positioned
// rectangles
List<Rectangle> copy = new ArrayList<>(rectanglesList);
Collections.reverse(copy);
for (Rectangle r : copy) {
if (r.contains(event.getPoint())) {
rectanglesList.remove(r);
break;
}
}
event.getComponent().repaint();
}
});
panelsPane.addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent event) {
}
public void mouseReleased(MouseEvent event) {
}
public void mouseClicked(MouseEvent event) {
}
public void mouseEntered(MouseEvent event) {
}
public void mouseExited(MouseEvent event) {
}
});
panelsPane.setPreferredSize(new Dimension(800, ySize - 315));
rightPane.setPreferredSize(new Dimension(530, ySize - 315));
mainPanel.setPreferredSize(new Dimension(xSize, ySize));
frame.setPreferredSize(new Dimension(xSize, ySize));
rightPane.setBackground(Color.gray);
mainPanel.add(panelsPane);
mainPanel.add(rightPane);
frame.add(mainPanel);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Rec obj = new Rec();
obj.launchFrame();
}
});
}
}

Show video stream from multiple cameras in jpanel grids in java opencv

My current code for grid to show video stream is as follow
//Function for displaying grid window//
public void createMap(int maxX, int maxY) {
gameGrid = new JPanel(new GridLayout(maxX, maxY, 1, 1));
gameGrid.setBackground(Color.GREEN);
for (int i = 0; i < maxX; i++) {
for (int j = 0; j < maxY; j++) {
JPanel panel = new JPanel();
panel.setPreferredSize(PREF_SIZE);
String name = String.format("[%d, %d]", i, j);
panel.setName(name);
panel.setBackground(Color.black);
gameGrid.add(panel);
}
}
}
I call this function as createMap(2,2) so it create grid for 2x2(4 window).
I want to show video stream in each of these grid.
I receiving the video stream through 4 cctv cameras attached with DVR.
I used following code for Showing video streams using opencv
package cctvmonitorsystem;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
// DB connectivity classes
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.SQLException;
import java.sql.ResultSet;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
import org.opencv.imgproc.Imgproc;
import java.util.Arrays;
public class Video {
public static void main(String args[]) throws SQLException {
int maxCamNo = 4;
//create connection
DbConnect dbcon = new DbConnect();
Connection con = dbcon.openCon();
Statement stmt = con.createStatement();
String getDevice="select * from device order by d_id limit 1";
ResultSet res=stmt.executeQuery(getDevice);
// DECLARE VARIABLES FOR DEVICE ADDRESS & PORT
String devAddress = null;
int httpPort=0;
while (res.next())
{
devAddress=res.getString("d_address");
httpPort=res.getInt("d_http_port");
}
dbcon.closeCon(con); // Connection closed
VideoCapture vcam[] = new VideoCapture[maxCamNo];
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
for (int i = 0; i < vcam.length; i++) {
try {
vcam[i] = new VideoCapture();
vcam[i].open("http://"+devAddress+":"+httpPort+"/cgi-bin/view.cgi?chn=" + i + "&u=admin&p=");
//vcam[i]=new VideoCapture(i);
} catch (Exception e) {
e.printStackTrace();
}
if (!vcam[i].isOpened()) {
System.out.println("Camera " + i + " error");
}
}
AccessVideo av = new AccessVideo(vcam);
//Initialize swing components
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(av);
//frame.setSize(1024,768);
frame.setMaximumSize(null);
frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
frame.setVisible(true);
while (vcam[0].isOpened()) {
av.repaint();
}
}
}
class AccessVideo extends JPanel {
VideoCapture[] camera = new VideoCapture[6];
AccessVideo(VideoCapture[] camView) {
camera = camView;
}
public BufferedImage Mat2BufferedImage(Mat m) {
System.out.println("Channels - "+m.channels());
int type = BufferedImage.TYPE_BYTE_GRAY;
if (m.channels() > 1) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = m.channels() * m.cols() * m.rows();
byte[] b = new byte[bufferSize];
m.get(0, 0, b); // get all the pixels
BufferedImage img = new BufferedImage(m.cols(), m.rows(), type);
final byte[] targetPixels = ((DataBufferByte) img.getRaster().getDataBuffer()).getData();
System.arraycopy(b, 0, targetPixels, 0, b.length);
return img;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Mat[] mat = new Mat[camera.length];
int width=400;
int height=300;
int xpos = 0;
int ypos = 0;
int y = 1;
for (int i = 0; i < camera.length; i++) {
mat[i] = new Mat();
camera[i].read(mat[i]);
BufferedImage image = Mat2BufferedImage(mat[i]);
g.drawImage(image, xpos, ypos, width, height, null);
xpos = xpos + width;
if (y == 3) {
xpos = 0;
ypos = ypos + height;
y = 0;
}
y++;
}
}
}
Here the video streams will show according to x & y co-ordinates.
But I want to show these video streams in grids which i mention above.
Can anyone help me to resolve this issue.
I did something similar here is my code, but this is hardcoded to only 6 cameras.
This is the main function where I called the addComponentsToPane.
public static void main(String[] args) {
CamtestMonitor f = new CamtestMonitor("Monitor");
f.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//Set up the content pane.
f.addComponentsToPane(f.getContentPane());
//Display the window.
f.pack();
f.setVisible(true);
}
This is the addComponentsToPane function where we add 6 different ServerUI's. Each one extends the JLabel class and implements DataListener.
public void addComponentsToPane(final Container pane) {
final JPanel jp = new JPanel();
jp.setLayout(gl);
//Set up components preferred size
jp.add(new ServerUI(8880));
jp.add(new ServerUI(8891));
jp.add(new ServerUI(8892));
jp.add(new ServerUI(8893));
jp.add(new ServerUI(8894));
jp.add(new ServerUI(8895));
jp.setPreferredSize(new Dimension(1600, 900));
//Set up the horizontal gap value
gl.setHgap(gapSize);
//Set up the vertical gap value
gl.setVgap(gapSize);
//Set up the layout of the buttons
gl.layoutContainer(jp);
pane.add(jp, BorderLayout.NORTH);
pane.add(new JSeparator(), BorderLayout.SOUTH);
}
There you have the Constructor of the ServerUI:
public ServerUI(int port) {
SocketServer server = new SocketServer(port);
server.setOnDataListener(this);
server.start();
}
Finally, here we have the overrrided function that refresh the image on each JLabel.
#Override
public void paint(Graphics g) {
synchronized (queue) {
if (queue.size() > 0) {
lastFrame = queue.poll();
}
}
if (lastFrame != null) {
g.drawImage(lastFrame, 0, 0, null);
}
}
You can have one thread for each camera, and also you extend JPanel class and override the paintComponent() method, like example below
public class MyJPanel extends JPanel {
private BufferedImage image;
public MyJPanel() {
super();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (image != null) {
g2.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);
}
}
public void refresh(BufferedImage image) {
this.image = image;
this.repaint();
}
}
public class CameraHandler implements Runnable {
VideoCapture vCapture;
MyJPanel mPanel;
public CameraHandler(VideoCapture vCapture, MyJPanel mPanel) {
this.vCapture = vCapture;
this.mPanel = mPanel;
}
public void run() {
while(vCapture.canReadFrame...) {
then convert the Mat to BufferedImage;
then call this:
mPanel.refresh(convertedImage);
}
}
}
public class MainClass {
public static void main(String[] args) {
VideoCapture vcam[] = new VideoCapture[maxCamNo];
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
for (int i = 0; i < vcam.length; i++) {
try {
vcam[i] = new VideoCapture();
vcam[i].open("http://"+devAddress+":"+httpPort+"/cgi-bin/view.cgi?chn=" + i + "&u=admin&p=");
//vcam[i]=new VideoCapture(i);
if(vcam[i].isOpen) {
new Thread(new CameraHandler(vcam[i], and you MyJPanel reference)).start();
}
} catch (Exception e) {
e.printStackTrace();
}
if (!vcam[i].isOpened()) {
System.out.println("Camera " + i + " error");
}
}
}
}
The code above is just an example to show the way, if you use this then need to arrange the code as your need. Hope this code help you!

Scaling image through thread - JAVA

Let say I have an image. I put the image in a JPanel and add the JPanel inside a JFrame. The image moves from the bottom part of the frame to top of the frame while its size is also decreased using AffineTransform. The variable changes using thread.
So here's the following code:
public class SplashScreen extends JFrame{
Image img1;
int w=1,h=1;
int x=0,y=0;
Thread th = new Thread(new Runnable() {
#Override
public void run() {
while(true){
w-=0.05;
h-=0.05;
y-=2;
x+=1;
if(y==-100){
new MainMenu_BlueJay().setVisible(true);
dispose();
}
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(SplashScreen.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
});
JPanel p = new JPanel();
public SplashScreen(){
setLayout(new BorderLayout());
p.setPreferredSize(new Dimension(900,600));
p.setBackground(Color.black);
p.setLayout(new GridLayout());
add(p);
setTitle("BlueJay");
setSize(900,600);
getContentPane().setBackground(Color.black);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
th.start();
requestFocus();
setFocusable(true);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
img1 = new ImageIcon("images/Intro/BJ Production 2013.png").getImage();
AffineTransform at = new AffineTransform();
at.scale(w,h);
g2d.setTransform(at);
g2d.drawImage(img1, x, y, p);
}
public static void main(String[] args) {
new SplashScreen();
}
However what I get from code above is only black screen. What's the matter? Anyway, If I don't use the AffineTransform function (just move it from bottom to top), the image is shown and moves BUT the frame is flickered (blinking) rapidly.
Any idea to solve this problem so I could move the image while decrease its size and also solve the flickered/rapid blinking frame?
You should not override the paint method of the JFrame. If you want to paint anything, you should paint this in a class that extends JPanel, where you override the paintComponent method.
You should NOT load the image in the painting method. This is horribly inefficient. You should load the image only ONCE, probably in a constructor.
You should not call Graphics2D#setTransform(). Have a look at the JavaDoc at http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html#setTransform%28java.awt.geom.AffineTransform%29 , which explicitly states
WARNING: This method should never be used to apply a new coordinate transform on top of an existing transform
You should think about your w and h values. Should they be the size of the image that is painted, or used as scaling factors for the image? Setting them as the scaling factors of an AffineTransform will NOT have the effect of scaling an image to the desired size. At the moment, they are declared as int values, so something like w-=0.05 does not really make sense anyhow.
You should have a clear idea of how you are going to describe the animation that the image should perform.
One could possibly summarize this:
You should not write code and assume it is "correct" only because there are no compilation errors ;-)
However, the following snippet may be a first step towards your goal:
package stackoverflow;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class SplashScreen extends JFrame
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new SplashScreen();
}
});
}
private PaintPanel paintPanel;
public SplashScreen()
{
setTitle("BlueJay");
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().setBackground(Color.BLACK);
getContentPane().setLayout(new BorderLayout());
paintPanel = new PaintPanel();
getContentPane().add(paintPanel, BorderLayout.CENTER);
setSize(900,600);
setLocationRelativeTo(null);
setFocusable(true);
requestFocus();
setVisible(true);
startAnimation();
}
void startAnimation()
{
Thread thread = new Thread(new Runnable()
{
int x = 100;
int y = 100;
int w = 0;
int h = 0;
#Override
public void run()
{
try
{
Thread.sleep(500);
}
catch (InterruptedException ex)
{
Thread.currentThread().interrupt();
return;
}
while (true)
{
if (y == 200)
{
// new MainMenu_BlueJay().setVisible(true);
dispose();
}
x += 2;
y += 1;
w += 1;
h += 1;
paintPanel.setImageCoordinates(x, y, w, h);
repaint();
try
{
Thread.sleep(10);
}
catch (InterruptedException ex)
{
Thread.currentThread().interrupt();
return;
}
}
}
});
thread.start();
}
}
class PaintPanel extends JPanel
{
private final Image image;
private int imageX, imageY;
private int imageW, imageH;
PaintPanel()
{
image = new ImageIcon("Clipboard02.jpg").getImage();
imageX = 0;
imageY = 0;
imageW = 0;
imageH = 0;
}
void setImageCoordinates(int imageX, int imageY, int imageW, int imageH)
{
this.imageX = imageX;
this.imageY = imageY;
this.imageW = imageW;
this.imageH = imageH;
repaint();
}
#Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
float scalingX = (float) imageW / image.getWidth(null);
float scalingY = (float) imageH / image.getHeight(null);
g.scale(scalingX, scalingY);
int ix = (int)(imageX / scalingX);
int iy = (int)(imageY / scalingY);
g.drawImage(image, ix, iy, null);
}
}
Don't paint on top-level containers like JFrame. Instead use a JPanel and override its paintComponent method and call super.paintComponent
No need to call Thread.sleep(). Instead Use a javax.swing.Timer.
Run your program from the EDT
Don't create a new ImageIcon in the paint method. It will create new ImageIcon object every time repaint() is called. Instead, instantiate it in the constructor.
Here's a refactor of the code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SplashScreen extends JFrame {
Image img1;
int w = 900, h = 600;
int x = 0, y = 0;
public SplashScreen() {
setLayout(new BorderLayout());
add(new MyPanel());
setTitle("BlueJay");
setSize(900, 600);
getContentPane().setBackground(Color.black);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
requestFocus();
setFocusable(true);
}
private class MyPanel extends JPanel {
public MyPanel() {
img1 = new ImageIcon(SplashScreen.class.getResource("/resources/stackoverflow5.png")).getImage();
setBackground(Color.black);
setLayout(new GridLayout());
Timer timer = new Timer(20, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
w -= 5;
h -= 5;
y -= 2;
x += 1;
if (y == -250) {
new MainMenu_BlueJay().setVisible(true);
dispose();
}
repaint();
}
});
timer.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//AffineTransform at = new AffineTransform();
// at.scale(w, h);
// g2d.setTransform(at);
g2d.drawImage(img1, x, y, w, h, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(900, 600);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new SplashScreen();
}
});
}
}
I'm not too familiar with Graphics2D so I commented out the AffirmTransformation stuff, but fixed your other problems.

Repeating an image based on random integers

I created a background using a relatively bland texture (it repeats well, so that's a bonus). However, on top of that, I am trying to add two images in random positions, each five times. So I tried that out with this -
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class RepeatDiagonals {
public static Image whiteOverlayStreak;
public static Image blackOverlayStreak;
public static JFrame framePanel;
public static DiagonalImages diagTest;
public static void createAndInitGUI() {
diagTest = new DiagonalImages();
framePanel = new JFrame("Diagonal Testing");
framePanel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
framePanel.setPreferredSize(new Dimension(1020, 720));
framePanel.add(diagTest);
framePanel.pack();
framePanel.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndInitGUI();
} // public void run() Closing
}); // SwingUtilities Closing
}
}
// TODO Add in constructor for better image import
class DiagonalImages extends JPanel {
public static final String IMAGE_PATH_WHITESTREAK = "imageFolder/whiteBackgroundStreakOverlay.png";
public static final String IMAGE_PATH_BLACKSTREAK = "imageFolder/blackBackgroundStreakOverlay.png";
public static Image whiteOverlayStreak;
public static Image blackOverlayStreak;
public static Image overlayStreak;
DiagonalImages() {
loadImages();
setVisible(true);
setOpaque(false);
};
public void loadImages() {
try {
whiteOverlayStreak = ImageIO.read(new File(IMAGE_PATH_WHITESTREAK));
blackOverlayStreak = ImageIO.read(new File(IMAGE_PATH_BLACKSTREAK));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Dimension size = this.getSize();
Insets insets = this.getInsets();
int w = size.width - insets.left - insets.right;
int h = size.height - insets.top - insets.bottom;
Random randomInteger = new Random();
randomInteger.nextInt(900);
for (int i = 0; i < 3; i++) {
int x = randomInteger.nextInt() % w;
int y = randomInteger.nextInt() % h;
g2d.drawImage(blackOverlayStreak, x, y, null);
}
for (int i2 = 0; i2 < 5; i2++){
int x2 = randomInteger.nextInt() % w;
int y2 = randomInteger.nextInt() % h;
g2d.drawImage(whiteOverlayStreak, x2, y2, null);
}
}
}
The relevant part of the main code:
// Makes the Initial BorderLayout
allContent = new ImagePanel(image);
allContent.setLayout(new BorderLayout());
allContent.add(new DiagonalImages());
allContent.add(tabbedPane, BorderLayout.CENTER);
allContent.add(logoImage, BorderLayout.NORTH);
allContent.setVisible(true);
allContent.setOpaque(false);
// Add ScrollPane
scrollPane = new JScrollPane(allContent);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.getVerticalScrollBar().setUnitIncrement(10);
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
scrollPane.setBorder(new EmptyBorder(0, 0, 0, 0));
scrollPane.setWheelScrollingEnabled(true);
// JFrame programFrame Constructors
programFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
programFrame.setLayout(new BorderLayout());
programFrame.add(scrollPane);
programFrame.pack();
programFrame.setVisible(true);
programFrame.setResizable(true);
programFrame.setSize(1280, 720);
programFrame.setLocationRelativeTo(null);
And here's the ImagePanel I have:
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
class ImagePanel extends JPanel {
private Image image;
private boolean tile;
ImagePanel(Image image) {
this.image = image;
this.tile = false;
};
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int iw = image.getWidth(this);
int ih = image.getHeight(this);
if (iw > 0 && ih > 0) {
for (int x = 0; x < getWidth(); x += iw) {
for (int y = 0; y < getHeight(); y += ih) {
g.drawImage(image, x, y, iw, ih, this);
}
}
}
}
}
Thanks for the (future) help!
EDIT: Made a small change based on the answer given, and it's still not working.
Okay, so the problem is that the image that's supposed to be repeated isn't actually even showing up.
EDIT2: Rewrote my entire code for this, and it's still not working. Even setting the background color isn't working, which leads me to believe it's a problem with my paintComponent.
EDIT3: paintComponent is working thanks to help. My final problem is getting it to work correctly in my main method.
First JFrame.setVisible(true); should be done last, after pack() which does layouting.
framePanel.pack();
framePanel.setVisible(true);
The images maybe better reside in the application (jar) itself, then you can use getClass().getResource("...").
They should be loaded outside paint, say in the constructor. I guess, it was test code.
public static Image whiteOverlayStreak;
public static Image blackOverlayStreak;
DiagonalImages() {
loadImages();
}
private void loadImages() {
whiteOverlayStreak = new ImageIcon(
getClass().getResource("/white.jpg")).getImage();
blackOverlayStreak = new ImageIcon(
getClass().getResource("/black.jpg")).getImage();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int x = r.nextInt(w);
int y = r.nextInt(h);
Your failure was not using #Override because then you would have seen, that you miswrote Graphics2D g instead of Graphics g. The function paintComponent never got called! LoL
Additional question: adding a second panel
framePanel.setLayout(new BorderLayout());
framePanel.add(diagTest, BorderLayout.CENTER);
framePanel.add(otherPanel, BorderLayout.SOUTH);
It wasn't really an SSCCE.
I haven't tested this fully, mainly because I didn't want to have to set up an entire Eclipse project just to point out the obvious mistake.
Separate the image process from the JPanel.
Only extend Swing components when you're modifying a component method.
Here's my version of your code. I had to modify your code to read an image to get it to work. You're going to have to figure out that part of the code yourself.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
class GUIImages {
private Image whiteDiagonal;
// private Image blackDiagonal;
public GUIImages() {
loadImages();
}
private void loadImages() {
try {
whiteDiagonal = ImageIO.read(new File(
"C:/Documents and Settings/BOP00082/" +
"My Documents/My Pictures/Places-icon.png"));
} catch (IOException e) {
e.printStackTrace();
}
// whiteDiagonal = new ImageIcon(this.getClass().getResource(
// "imageFolder/whiteBackgroundStreakOverlay.png")).getImage();
// blackDiagonal = new ImageIcon(this.getClass().getResource(
// "imageFolder/blackBackgroundStreakOverlay.png")).getImage();
}
public void doDrawing(JPanel panel, Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(createDiagonalImage(panel), 0, 0, null);
}
private Image createDiagonalImage(JPanel panel) {
BufferedImage buffImg = new BufferedImage(677, 856,
BufferedImage.TYPE_INT_ARGB);
Graphics2D gbi = buffImg.createGraphics();
Dimension size = panel.getSize();
Insets insets = panel.getInsets();
int w = size.width - insets.left - insets.right;
int h = size.height - insets.top - insets.bottom;
Random r = new Random();
for (int i = 0; i < 5; i++) {
int x = Math.abs(r.nextInt()) % w;
int y = Math.abs(r.nextInt()) % h;
gbi.drawImage(whiteDiagonal, x, y, null);
}
gbi.dispose();
return buffImg;
}
}
class Surface extends JPanel {
GUIImages images;
public Surface(GUIImages images) {
this.images = images;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
images.doDrawing(this, g);
}
}
public class RepeatDiagonals implements Runnable {
JFrame frame;
#Override
public void run() {
frame = new JFrame();
frame.setTitle("Repeat Diagonals");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Surface(new GUIImages()));
frame.setSize(350, 250);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new RepeatDiagonals());
}
}

Categories