Two classes and image does not appear - java

I created two classes which one extending. I create an object, but a file is not appearing (method work fine, because title form draw() method appears. There is all code:
public class Main_class extends JFrame implements ActionListener{
//**************************//
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable(){
public void run(){
new Main_class().setVisible(true);
}
});
}
//**************************//
JPanel panel;
JMenuBar mbar;
JMenuItem item;
JMenuItem open;
JMenu file;
BufferedImage my_image;
public Main_class(){
setSize(800, 600);
setTitle("TEST");
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel=new JPanel();
mbar=new JMenuBar();
setJMenuBar(mbar);
file=new JMenu("File");
mbar.add(file);
open=new JMenuItem("Open");
open.addActionListener(this);
file.add(open);
}
#Override
public void actionPerformed(ActionEvent e) {
String zrodlo=e.getActionCommand();
image_class k=new image_class();
if(zrodlo.equals("Open")) try {
k.load(my_image);
} catch (IOException ex) {
Logger.getLogger(Main_class.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
///////////////////////////////////////////
public class image_class extends Main_class{
public void load(BufferedImage my_image) throws IOException{
JFileChooser open_chooser=new JFileChooser("//");
FileNameExtensionFilter rast=new FileNameExtensionFilter("Pliki grafiki rastrowej(.jpeg,.png.,gif...)", "jpeg","jpg", "gif","png","bmp");
open_chooser.setFileFilter(rast);
int a=open_chooser.showOpenDialog(null);
if(a==JFileChooser.APPROVE_OPTION){
String image_name=open_chooser.getSelectedFile().getAbsolutePath();
String roz=image_name.substring(image_name.lastIndexOf('.')+1);
my_image=ImageIO.read(open_chooser.getSelectedFile());
draw();
}
}
public void draw(){
panel=new JPanel(){
protected void paintComponent(Graphics g){
Graphics g2 = g.create();
g2.drawImage(my_image, 0, 0, getWidth(), getHeight(), null);
g2.dispose();
}
};
panel.setBounds(0, 0, 200, 200);
add(panel);
revalidate();
repaint();
System.out.print("LOADED!!!!!!");
}
}

Your image does not appear as you
Never display your 2nd JFrame, image_class, by calling setVisible.
Because Java is pass-by-value, you are not assigning my_image to the class member variable of the same name in your load method, but rather a local copy of the variable:
Replace
my_image = ImageIO.read(open_chooser.getSelectedFile());
with
this.my_image = ImageIO.read(open_chooser.getSelectedFile());
(or simply don't pass in the variable)
Would recommend that you use a single JFrame here, add a sub-class of JComponent and draw the image on that component.
Related:
The Use of Multiple JFrames, Good/Bad Practice?
How to add an image to a JPanel?

One of your main problems is that you're misusing inheritance. Your code here from image_class.java:
public void draw() {
panel = new JPanel() {
protected void paintComponent(Graphics g) {
Graphics g2 = g.create();
g2.drawImage(my_image, 0, 0, getWidth(), getHeight(), null);
g2.dispose();
}
};
panel.setBounds(0, 0, 200, 200);
add(panel);
revalidate();
repaint();
System.out.print("LOADED!!!!!!");
}
You are adding the new JPanel to a Main_class instance, but not the one that is displayed but rather to the one that image_class inherits from. These are two completely distinct objects and making changes to one will not affect the other.
The solution is not to misuse inheritance for this but rather to display the image in the original GUI.
Also, you should never dispose of a Graphics object that was given to you from the JVM as this can have nasty side effects.

Related

Painting mutliple objects in 1 JFrame

I'm trying to make my program object oriented and I'm attempting to split it into several classes. The short version is that I want to paint different objects in 1 JFrame. So I created a class per object that I wanted to paint, defined the object in my method and then add them to my frame. The problem is that only the last component is painted in the frame. I tried adding the objects to a JPanel first but that doesn't seem to work.
trees1
public class trees1 extends JComponent{
public final ImageIcon pokemontree;
public trees1(){
ImageIcon poke = new ImageIcon("pokemontree.png");
Image image = poke.getImage(); // transform it
pokemontree = new ImageIcon(newimg); // transform it back
}
public void paintComponent (Graphics g){
Graphics2D g2 = (Graphics2D) g;
pokemontree.paintIcon(this,g2 , 100,200);
}
}
testing
// main program
public class testing {
public static void main(String[] args){
JFrame win = new JFrame();
win.setSize(600,400);
win.setTitle("Test");
win.setResizable(false);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
trees1 exo = new trees1();
Playerwalking p1 = new Playerwalking(1,2);
win.add(exo);
win.add(p1);
win.setVisible(true);
}
JFrame content pane default uses BorderLayout
The default content pane will have a BorderLayout.
For BorderLayout, the "add()" method always set to "CENTER" if you don't specify the location (NORTH/EAST/SOUTH/WEST/CENTER etc) of the components you adding.
You need to specify your "getPreferredSize()" in your component, also understand how to use the BorderLayout (or other layout manager properly).
public class Test1 extends JFrame {
public static void main(String[] args) throws Exception {
JFrame win = new JFrame();
win.setSize(600,400);
win.setTitle("Test");
win.setResizable(false);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.add(new trees1(), BorderLayout.CENTER);
win.add(new trees1(), BorderLayout.SOUTH);
win.add(new trees1(), BorderLayout.EAST);
win.pack();
win.setVisible(true);
}
}
class trees1 extends JComponent {
public final ImageIcon pokemontree;
public trees1(){
ImageIcon poke = new ImageIcon("c:\\temp\\2.png");
Image image = poke.getImage(); // transform it
pokemontree = new ImageIcon(image); // transform it back
}
#Override
public Dimension getPreferredSize() {
return new Dimension(pokemontree.getIconWidth(), pokemontree.getIconHeight());
}
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
pokemontree.paintIcon(this,g2 , 0,0);
}
}

How can I stop an image from flickering/dislocating when a JFrame is resized?

I have a JFrame. Within that JFrame I have a JLayeredPane layed out with an OverlayLayout that contains multiple Jpanels. in one of those JPanels I have a BufferedImage. When the JFrame is resized, the image quickly dissapears and dislocates, then it jumps back again, dislocates again, back again, and so on.
I have tried a lot of things to stop the image from flickering, but I don't know what the cause of the problem exactly is.
The Jpanel that holds the image contains the following code to render the image:
protected void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawImage(myBufferedImage, 0, 0, 200, 200, null);
}
In trying to reconstruct and simplify the problem, I got a working version of what I wanted. I still don't know what the problem is with my other code though.
This is the code that works:
import java.awt.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Main {
public Main() {
// Create the JFrame:
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(600, 400);
window.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
// Create the pane to hold layers:
JLayeredPane layers = new JLayeredPane();
layers.setLayout(new OverlayLayout(layers));
// Add two layers:
layers.add(new MyGraphics());
layers.add(new MyImage());
//
window.add(layers);
window.setVisible(true);
}
public static void main(String[] args) {
Main app = new Main();
}
public class MyImage extends JPanel {
public BufferedImage source;
public MyImage () {
this.setPreferredSize(new Dimension(180,180));
this.setLocation(0,0);
try {
this.source = ImageIO.read(new File("image.jpg"));
} catch (IOException ie) {
ie.printStackTrace();
}
}
protected void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawImage(this.source, 0, 0, 180, 180, null);
}
}
public class MyGraphics extends JPanel {
public MyGraphics () {
this.setOpaque(false);
this.setPreferredSize(new Dimension(180,180));
this.setLocation(0,0);
}
protected void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawLine(0, 0, 180, 180);
}
}
}
Try adding below line of code in constructor:
public FlickerDemo()
{
// No flickering during resize
System.setProperty("sun.awt.noerasebackground", "true");
}

How to add picture out of JFrame, attached to border

Hi I Would like add to my JFrame border some image.
Is this Possible to attach picture to borders for JFrame and create it as 1 object ?
Something like this:
I'm not sure if it's possible to add the image directly to the border of a JFrame (suggestions welcome). I decided to solve this issue by using a transparent content pane, and using an inner frame to "appear" like the outer frame.
The code is pretty simple, however, let me know if you'd like an explanation of how the code works.
Here's the minimum code you'll need to get up and running.
You'll need to provide your own transparent-phone.png image, in the root of the classpath (i.e. next to your PhoneWindow.java file, in the root package).
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
public class PhoneWindow {
public static void main(String[] args) {
new PhoneWindow();
}
public PhoneWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create the inner frame
final JInternalFrame frame2 = new JInternalFrame("My Telephone");
frame2.setClosable(true);
frame2.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
// add elements to the outer frame
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
JPanel pane = new TranslucentPane();
frame.setContentPane(pane);
frame.setLayout(new BorderLayout());
// add inner frame and phone picture
frame.add(frame2, BorderLayout.CENTER);
frame.add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/transparent-phone.png")))), BorderLayout.EAST);
frame.setLocationRelativeTo(null);
frame.setMinimumSize(new Dimension(400, 300));
frame.pack();
// show
frame2.setVisible(true);
frame.setVisible(true);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
});
}
public class TranslucentPane extends JPanel {
public TranslucentPane() {
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(0f));
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
}
Here's the full Java class (including close and draggable behaviour)
https://gist.github.com/nickgrealy/16901a6428cb79d4f179
And here's a screenshot of the final product
N.B. the transparent sections inside/outside the phone.
References:
How to make a transparent JFrame but keep everything else the same?
Trying to disable dragging of a JInternalFrame

An ImageIcon not even used is affecting my JFrame/JPanel. Why?

I hope this isn’t a stupid first question; I can’t seem to find an answer anyway.
I have this JFrame constructor where a JPanel is added to the JFrame. The JPanel paints a Rectangle in the JFrame, and that’s fine. However, if I add an ImageIcon object as in the code below (for later use), the rectangle isn’t painted. It does appear if I resize the window though.
One solution is to put the setVisible(true) as the last line, or to instantiate the ImageIcon above the constructor, but I really want to understand this. It doesn’t make sense to me that an object not even used can cause this behaviour. Thanks.
public class AJFrame extends JFrame {
ImageIcon ii;
public AJFrame() {
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
ImageIcon ii = new ImageIcon("Untitled.png");
JPanel jp = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
g.fillRect(0, 0, 50, 50);
}
};
add(jp);
}
public static void main(String[] args) {
AJFrame jf = new AJFrame();
}
}
All actions within a frame should be done in the EDT (Event Dispatching Thread) of Swing. Therefore the right way to start your frame is
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AJFrame().setVisible(true);
}
});
So maybe it all comes down to the wrong start of your frame.
The main routine of a Java program is not started within the EDT. All Swing actions that are not within the EDT could produce strange refresh/visibility issues.
Here is the complete sourcecode:
public class AJFrame extends JFrame {
ImageIcon ii;
public AJFrame() {
setSize(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
//setVisible(true);
//ImageIcon ii = new ImageIcon("Untitled.png");
JPanel jp = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
g.fillRect(0, 0, 50, 50);
}
};
add(jp);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AJFrame().setVisible(true);
}
});
}
}

Simplest way to set image as JPanel background

How would I add the backgroung image to my JPanel without creating a new class or method, but simply by inserting it along with the rest of the JPanel's attributes?
I am trying to set a JPanel's background using an image, however, every example I find seems to suggest extending the panel with its own class.
I have been looking for a way to simply add the image without creating a whole new class and within the same method (trying to keep things organized and simple).
Here is an example of the method that sets my JPanel:
public static JPanel drawGamePanel(){
//Create game panel and attributes
JPanel gamePanel = new JPanel();
Image background = Toolkit.getDefaultToolkit().createImage("Background.png");
gamePanel.drawImage(background, 0, 0, null);
//Set Return
return gamePanel;
}
I am trying to set a JPanel's background using an image, however, every example I find seems to suggest extending the panel with its own class
yes you will have to extend JPanel and override the paintcomponent(Graphics g) function to do so.
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bgImage, 0, 0, null);
}
I have been looking for a way to simply add the image without creating a whole new class and within the same method (trying to keep things organized and simple).
You can use other component which allows to add image as icon directly e.g. JLabel if you want.
ImageIcon icon = new ImageIcon(imgURL);
JLabel thumb = new JLabel();
thumb.setIcon(icon);
But again in the bracket trying to keep things organized and simple !! what makes you to think that just creating a new class will lead you to a messy world ?
Simplest way to set image as JPanel background
Don't use a JPanel. Just use a JLabel with an Icon then you don't need custom code.
See Background Panel for more information as well as a solution that will paint the image on a JPanel with 3 different painting options:
scaled
tiled
actual
As I know the way you can do it is to override paintComponent method that demands to inherit JPanel
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // paint the background image and scale it to fill the entire space
g.drawImage(/*....*/);
}
The other way (a bit complicated) to create second custom JPanel and put is as background for your main
ImagePanel
public class ImagePanel extends JPanel
{
private static final long serialVersionUID = 1L;
private Image image = null;
private int iWidth2;
private int iHeight2;
public ImagePanel(Image image)
{
this.image = image;
this.iWidth2 = image.getWidth(this)/2;
this.iHeight2 = image.getHeight(this)/2;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if (image != null)
{
int x = this.getParent().getWidth()/2 - iWidth2;
int y = this.getParent().getHeight()/2 - iHeight2;
g.drawImage(image,x,y,this);
}
}
}
EmptyPanel
public class EmptyPanel extends JPanel{
private static final long serialVersionUID = 1L;
public EmptyPanel() {
super();
init();
}
#Override
public boolean isOptimizedDrawingEnabled() {
return false;
}
public void init(){
LayoutManager overlay = new OverlayLayout(this);
this.setLayout(overlay);
ImagePanel iPanel = new ImagePanel(new IconToImage(IconFactory.BG_CENTER).getImage());
iPanel.setLayout(new BorderLayout());
this.add(iPanel);
iPanel.setOpaque(false);
}
}
IconToImage
public class IconToImage {
Icon icon;
Image image;
public IconToImage(Icon icon) {
this.icon = icon;
image = iconToImage();
}
public Image iconToImage() {
if (icon instanceof ImageIcon) {
return ((ImageIcon)icon).getImage();
} else {
int w = icon.getIconWidth();
int h = icon.getIconHeight();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
Graphics2D g = image.createGraphics();
icon.paintIcon(null, g, 0, 0);
g.dispose();
return image;
}
}
/**
* #return the image
*/
public Image getImage() {
return image;
}
}
Draw the image on the background of a JPanel that is added to the frame. Use a layout manager to normally add your buttons and other components to the panel. If you add other child panels, perhaps you want to set child.setOpaque(false).
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.net.URL;
public class BackgroundImageApp {
private JFrame frame;
private BackgroundImageApp create() {
frame = createFrame();
frame.getContentPane().add(createContent());
return this;
}
private JFrame createFrame() {
JFrame frame = new JFrame(getClass().getName());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}
private void show() {
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private Component createContent() {
final Image image = requestImage();
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
};
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
for (String label : new String[]{"One", "Dois", "Drei", "Quatro", "Peace"}) {
JButton button = new JButton(label);
button.setAlignmentX(Component.CENTER_ALIGNMENT);
panel.add(Box.createRigidArea(new Dimension(15, 15)));
panel.add(button);
}
panel.setPreferredSize(new Dimension(500, 500));
return panel;
}
private Image requestImage() {
Image image = null;
try {
image = ImageIO.read(new URL("http://www.johnlennon.com/wp-content/themes/jl/images/home-gallery/2.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new BackgroundImageApp().create().show();
}
});
}
}
class Logo extends JPanel
{
Logo()
{
//code
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
ImageIcon img = new ImageIcon("logo.jpg");
g.drawImage(img.getImage(), 0, 0, this.getWidth(), this.getHeight(), null);
}
}
INITIALIZE YOUR JPANEL AS BELOW. NOTE THE MISSING SEMICOLON.. INSTEAD OPEN A CURLY BRACE THEN OVERRIDE THAT METHOD.. THIS WAY YOU DON'T HAVE TO EXTEND TO ANYTHING
ImageIcon img = new ImageIcon("background.jpg");
JPanel panel1 = new JPanel()
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(img.getImage(), 0, 0, null);
}
};
public demo1() {
initComponents();
ImageIcon img = new ImageIcon("C:\\Users\\AMIT TIWARI\\Documents\\NetBeansProjects\\try\\src\\com\\dd.jpeg"); //full path of image
Image img2 = img.getImage().getScaledInstance(mylabel.getWidth(), mylabel.getHeight(),1);
ImageIcon img3 = new ImageIcon(img2);
mylabel.setIcon(img3);
}

Categories

Resources