Trying to paint an image in java - java

int x = 0;
int y = 0;
Image img;
Screen screen;
GamePanel() {
setBounds(0, 0, 600, 600);
setLayout(null);
setVisible(true);
setBackground(new Color(100, 0, 0));
screen = new Screen();
screen.setBounds(0, 0, 600, 600);
add(screen);
img = Toolkit.getDefaultToolkit().createImage("monster.jpg");
}
public void repaintScreen(){
screen.repaint();
}
private class Screen extends JLabel{
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawRect(10, 10, 100, 100);
g.drawImage(img, 0, 0, this);
}
}
Hello I am trying to draw an Image but it never works. I also tryed to load the image in Different ways but allways the same. But there is noch warning so something like that showing up.
But when I put it as an Icon in an JLable it works.

final BufferedImage image = ImageIO.read(new File("C:\image.png"));
Confused are you trying to draw to a JPanel/JFrame?
https://docs.oracle.com/javase/tutorial/2d/images/
final BufferedImage image = ImageIO.read(new File("C:\image.png"));
GamePanel gamePanel;
JPanel pane = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
};
gamePanel(or screen).add(pane);
}

Related

Laggy window when displaying images for the first time with JScrollPane

I am trying to display a bunch of ImagePanels in a JScrollPane. The problem with this application is that every time a new row of panels enters the viewport the whole window freezes for a small amount of time. Once scrolled through to the end though, the window will not lag again.
What is the cause of this lagging and how can I prevent it from happening in the first place?
My guess is the panels don't get painted until they are scrolled to. So I tried to call repaint on them after adding them to the background but that didn't work :(
MainClass.java:
import javax.swing.SwingUtilities;
public class MainClass {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MainFrame frame = new MainFrame();
}
});
}
}
MainFrame.java:
import java.awt.*;
import javax.swing.*;
public class MainFrame extends JFrame {
private static final long serialVersionUID = -254980289568295701L;
public MainFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setExtendedState(JFrame.MAXIMIZED_BOTH);
JPanel background = new JPanel();
JScrollPane scrollPane = new JScrollPane(background,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
ImagePanel ipanel;
background.setPreferredSize(new Dimension(this.getWidth(),
this.getHeight() + 3000));
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
scrollPane.getVerticalScrollBar().setUnitIncrement(20);
add(scrollPane);
for (int i = 0; i < 40; i++) {
ipanel = new ImagePanel();
ipanel.setPreferredSize(new Dimension(300, 400));
ipanel.setSize(new Dimension(300, 400));
background.add(ipanel);
}
setVisible(true);
}
}
ImagePanel.java:
import java.awt.*;
import javax.swing.JPanel;
import java.awt.image.BufferedImage;
public class ImagePanel extends JPanel {
private static final long serialVersionUID = 1997246878999790104L;
private Image image;
private int width;
private int height;
public ImagePanel() {
width = 300;
height = 400;
BufferedImage bufferedImage = new BufferedImage(2000, 2000, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, 2000, 2000);
g2d.setColor(Color.black);
g2d.fillOval(0, 0, 2000, 2000);
g2d.setColor(Color.yellow);
g2d.fillOval(1500, 300, 400, 400);
g2d.fillOval(1200, 600, 400, 400);
g2d.fillOval(900, 900, 400, 400);
g2d.fillOval(600, 1200, 400, 400);
g2d.fillOval(300, 1500, 400, 400);
g2d.dispose();
image = bufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
}
I changed your code to us a JLabel to display the image.
It takes longer to load, but the scrolling worked fine:
import java.awt.*;
import javax.swing.*;
import java.awt.image.BufferedImage;
//public class ImagePanel extends JPanel {
public class ImagePanel extends JLabel {
private static final long serialVersionUID = 1997246878999790104L;
private Image image;
private int width;
private int height;
public ImagePanel() {
width = 300;
height = 400;
BufferedImage bufferedImage = new BufferedImage(2000, 2000, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, 2000, 2000);
g2d.setColor(Color.black);
g2d.fillOval(0, 0, 2000, 2000);
g2d.setColor(Color.yellow);
g2d.fillOval(1500, 300, 400, 400);
g2d.fillOval(1200, 600, 400, 400);
g2d.fillOval(900, 900, 400, 400);
g2d.fillOval(600, 1200, 400, 400);
g2d.fillOval(300, 1500, 400, 400);
g2d.dispose();
image = bufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
setIcon( new ImageIcon(image) );
}
// #Override
protected void xxxpaintComponent(Graphics g) {
super.paintComponent(g);
// g.drawImage(image, 0, 0, this);
g.drawImage(image, 0, 0, null);
}
}

How do I capture the contents of a Scrollpane using graphics

I'm trying to create a buffered image from the contents of a JScrollpane. The Jscrollpane dimesions are 250x200. The contents spillover and only the visible section gets captured in the image. I'm using Java graphics 2D.
Is there a way to capture the complete contents of the scrollpage?
Just paint the contents to the BufferedImage, and not the scroll pane.
For example:
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
final Image image =
new ImageIcon("stackoverflow.png").getImage();
JPanel imagePanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(this),
image.getHeight(this));
}
};
JScrollPane pane = new JScrollPane(imagePanel);
pane.setPreferredSize(new Dimension(200, 200));
JOptionPane.showMessageDialog(null, pane);
BufferedImage newImage = getImageFromComponent(imagePanel);
JLabel label = new JLabel(new ImageIcon(newImage));
JOptionPane.showMessageDialog(null, label);
}
});
}
private static BufferedImage getImageFromComponent(Component component) {
BufferedImage img = new BufferedImage(
component.getWidth(), component.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = img.createGraphics();
component.paint(g);
g.setFont(new Font("impact", Font.PLAIN, 30));
g.drawString("Image of Panel", 40, 50);
g.dispose();
return img;
}
}
First the panel is put inside scroll pane.
When we close it, the contents of the panel are drawn to to a BufferedImage, and added to a label.

How to paint specific coordinates of one JPanel onto another JPanel

This is my problem :
I have one JPanel and i paint in this panel one rectangle ex. 100x100.
In another JPanel I wouldlike show/paint fragments on first JPanel ex. 50x50, but if I change first JPanel, another JPanel change too (dont copy graphics or Panel)
What I can do this?
First Panel Second Panel
Public class Okienko extends JFrame {
Panel p = new Panel();
public Okienko(){
//setLayout(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(p);
pack();
setVisible(true);
}
private class Panel extends JPanel{
public Panel(){
setPreferredSize(new Dimension(300,400));
setBackground(Color.red);
setVisible(true);
}
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
super.paint(g2);
g2.setColor(Color.blue);
g2.fill(new Rectangle2D.Float(100,100,100,100));
g2.setColor(Color.green);
g2.fill(new Rectangle2D.Float(50,50,50,50));
}
}
private class Panel2 extends Panel{
#Override
public void paint(Graphics g) {
//I would like to show/paint only fragment painted Panel, ex. 50x50 (only show one rectangle)
}
}
public static void main(String[] args) {
Okienko o = new Okienko();
}
}
So this is what you need to do.
You need to save the first JPanel's Graphics context to a BufferedImage. Here is a helper method, I used in the example program below
BufferedImage bi;
....
private void setImage(JPanel panel) {
Dimension d = panel.getPreferredSize();
int w = (int)d.getWidth();
int h =(int)d.getHeight();
bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
g.dispose();
}
This saves the entire JPanel to a BufferedImage.
Use that BufferedImage to paint on the second JPanel. Use whatever coordinates you want. Use this method from Graphics class
public abstract boolean drawImage(Image img,
int dx1,
int dy1,
int dx2,
int dy2,
int sx1,
int sy1,
int sx2,
int sy2,
ImageObserver observer)
img - the specified image to be drawn. This method does nothing if img is null.
dx1 - the x coordinate of the first corner of the destination rectangle.
dy1 - the y coordinate of the first corner of the destination rectangle.
dx2 - the x coordinate of the second corner of the destination rectangle.
dy2 - the y coordinate of the second corner of the destination rectangle.
sx1 - the x coordinate of the first corner of the source rectangle.
sy1 - the y coordinate of the first corner of the source rectangle.
sx2 - the x coordinate of the second corner of the source rectangle.
sy2 - the y coordinate of the second corner of the source rectangle.
observer - object to be notified as more of the image is scaled and converted.
g.drawImage(bi, 0, 0, 200, 200, 0, 0, 50, 50, this);
Here's the result
Here's the full code
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
public class TestTwoPanels {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JPanel panel = new JPanel();
PanelTwo panelTwo = new PanelTwo();
PanelOne panelOne = new PanelOne(panelTwo);
JSplitPane split = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT, panelOne, panelTwo);
panel.add(split);
JFrame frame = new JFrame("Test Graphics");
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private static class PanelOne extends JPanel {
Dimension size;
BufferedImage image;
PanelTwo panelTwo;
public PanelOne(PanelTwo panelTwo) {
this.panelTwo = panelTwo;
try {
URL url = new URL("http://swoo.co.uk/content/images/icons/stackoverflow.png");
image = ImageIO.read(url);
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panelTwo.setImage(PanelOne.this);
panelTwo.repaint();
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(image, 0, 0, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(250, 250);
}
}
private static class PanelTwo extends JPanel {
BufferedImage bi;
public PanelTwo() {
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
public void setImage(BufferedImage image) {
this.bi = image;
}
private void setImage(JPanel panel) {
Dimension d = panel.getPreferredSize();
int w = (int)d.getWidth();
int h =(int)d.getHeight();
System.out.println(d);
bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
g.dispose();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bi, 25, 25, 225, 225, 50, 50, 175, 175, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(250, 250);
}
}
}
private void setImage(JPanel panel) {
Dimension d = panel.getPreferredSize();
int w = (int)d.getWidth();
int h =(int)d.getHeight();
System.out.println(d);
bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
This code is clearify for me.
Graphics2D g = bi.createGraphics();
You create blank BufferedImage and init to Graphics2D?
panel.paint(g);
You paint graphics context on panel and copy to bi?
g.dispose();
You release g.
}

How to decrease a height of a rectangle? (Java, AWT)

I'm beginner in Java. So, please help me with my problem.
I can do animation when a rectangle's height increases. But I have problem with decreasing rectangle's height. Please look at this code:
public class Animation extends JPanel implements ActionListener {
Timer timer;
int i = 100;
public Animation() {
timer = new Timer(10, this);
timer.start();
}
public void paint(Graphics g) {
Graphics2D g2d1 = (Graphics2D) g;
g2d1.fillRect(0, 100, 30, i);
}
public static void main(String[] args) {
JFrame frame = new JFrame("animation");
frame.add(new Animation());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 800);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
--i;
repaint();
}
}
Please help me.
Best regards
Pawel
It isn't clearing the screen between draws, so it draws over the old larger rectangle.
Try this:
public void paint(Graphics g) {
Graphics2D g2d1 = (Graphics2D) g;
g.setColor(getBackground());
g.fillRect(0,0,getWidth(),getHeight()); // draw a rectangle over the display area in the bg color
g.setColor(Color.BLACK);
g2d1.fillRect(0, 100, 30, i);
}
Or:
public void paint(Graphics g) {
super.paint(g); // call superclass method, which does clear the screen
Graphics2D g2d1 = (Graphics2D) g;
g2d1.fillRect(0, 100, 30, i);
}
And as camickr pointed out below, custom painting should be done in paintComponent not paint, so you should change the name of the method to paintComponent.

make whole jinternalframe transparent

Right now I am making my jinternal frames transparent using this code:
double rgbConversionBackpack = Double.parseDouble(MyClient.configFile.getProperty("BACKPACK_FRAME_ALPHA"));
double tmp = (rgbConversionBackpack / 100.0) * 255.0;
this.getContentPane().setBackground(new Color(140, 0, 0, (int)tmp));
this.setOpaque(false);
I have code on the sliders to set the alpha which all works perfectly and saves it to a properties file, yada, yada, yada. The question is how do I make the entire JInternal Frame transparent.
Right now I have only be able to set the content pane, and any other panels (etc) that are in the jinternal frames transparent, but I want to make the entire JinternalFrame(borders and all) transparent.
Screenshot below shows how on the backpack the red tinted are is partially transparent and looks decent, but still want the border to be transparent also.
Is there a way to override the draw super method for each of my classes the extend JInternalFrame to have it draw semi transparent(depending on value obviously)?
You could do this by changing the AlphaComposite that the JInternalFrame's paint method uses. You have to be careful though to repaint the containing top level window at the location of the transparent component lest you have funny side effects. For example:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
#SuppressWarnings("serial")
public class TransparentInternalFrame extends JDesktopPane {
private static final Color COLOR_1 = Color.red;
private static final Color COLOR_2 = Color.blue;
private static final float PT_2 = 30f;
private static final int PREF_W = 800;
private static final int PREF_H = 500;
public TransparentInternalFrame() {
add(new MyInternalFrame("Foo", 50, 50, 300, 300, 0.2f));
add(new MyInternalFrame("Foo", 400, 100, 300, 300, 0.4f));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(new GradientPaint(0, 0, COLOR_1, PT_2, PT_2, COLOR_2, true));
g2.fillRect(0, 0, getWidth(), getHeight());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
TransparentInternalFrame mainPanel = new TransparentInternalFrame();
JFrame frame = new JFrame("TransparentInternalFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class MyInternalFrame extends JInternalFrame {
private AlphaComposite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
public MyInternalFrame(String title, int x, int y, int w, int h, final float alpha) {
super(title);
setClosable(true);
setBounds(x, y, w, h);
setVisible(true);
int sliderValue = (int) (alpha * 100);
comp = comp.derive(alpha);
final JSlider slider = new JSlider(0, 100, sliderValue);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(5);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
slider.setBorder(BorderFactory.createTitledBorder("Alpha Value"));
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent cEvt) {
float alpha = (float) slider.getValue() / 100f;
setAlpha(alpha);
MyInternalFrame.this.repaint();
Window win = SwingUtilities.getWindowAncestor(MyInternalFrame.this);
win.repaint();
}
});
add(new JLabel("My Label", SwingConstants.CENTER));
add(slider, BorderLayout.SOUTH);
}
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(comp);
super.paint(g);
}
public void setAlpha(float alpha) {
comp = comp.derive(alpha);
}
}
But note that this program is not fully fixed. You'll still see pixel errors if you drag one JInternalFrame over another. I still need to work the bugs out...

Categories

Resources