How to fit ImageIcon within JButton borders - java

I want to color some JButtons, some other questions here showed me, that it would be easier
to paint a little image (did it with gimp) and set it as icon for the JButton.
The number and size of the buttons should be variable (they're in a grid), so I want a high res image that I can scale how i need it.
The problem now is, I don't know how to 'cut the edges' of the icon, because the buttons have rounded edges.
Here you can see that the image is not inside of the button border.
And here is my method in the class that extends JButton.
public void setYellow() {
URL u = getClass().getResource("/img/yellow.png");
ImageIcon i = new javax.swing.ImageIcon(u);
//Image img = i.getImage();
//img = img.getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH);
//i = new ImageIcon(img);
setIcon(i);
}
EDIT
package test;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import control.Control;
import view.Field;
import view.View;
public class HelloWorldSwing {
/**
* #param args
*/
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
TestView.initialize();
}
});
}
}
class TestView {
private static TestView view = new TestView();
public static TestView getView() {
return view;
}
private TestView() {
JFrame frame = new JFrame("HelloWorldSwing");
frame.setLayout(new GridLayout(0,3));
int buttonSize = 40;
frame.getContentPane().add(new MyButton(buttonSize));
frame.getContentPane().add(new MyButton(buttonSize));
frame.getContentPane().add(new MyButton(buttonSize));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void initialize() {
}
}
class MyButton extends JButton {
int size;
public MyButton(int size) {
this.size = size;
setPreferredSize(new Dimension(size, size));
this.addActionListener(new ButtonHandler());
setBorder(LineBorder.createGrayLineBorder());
setOpaque(true);
}
public void setYellow() {
//URL u = getClass().getResource("/img/test.png"); // 64x64 png pic
URL u1 = null;
try {
u1 = new URL("http://assets1.qypecdn.net/uploads/users/0195/7210"
+ "/calvin_yellow_original_thumb.jpg");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ImageIcon i = new javax.swing.ImageIcon(u1);
// Image img = i.getImage();
// img = img.getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH);
// i = new ImageIcon(img);
setIcon(i);
// setBorderPainted(false);
// setContentAreaFilled(false); did not help
}
}
class ButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
MyButton mb = (MyButton) e.getSource();
mb.setYellow();
}
}
EDIT 2
Here are the pictures where the lines in setYellow()
setBorderPainted(false);
setContentAreaFilled(false);
are not commented out (unfortunately there is no difference)
Before button is clicked:
After button is clicked:
UPDATE
I added Borders to the MyButton constructor
setBorder(LineBorder.createGrayLineBorder());
and now the icons are inside the button borders. I added pictures.
But as you can see, we don't have these rounded button edges anymore.

button.setBorderPainted(false);
button.setContentAreaFilled(false);
As seen in this answer.
Update
I do not quite get what you are trying to achieve if not this.
I made the rollover icon to be orange so that we could easily see the size of one button, but otherwise I put 4 in a row to ensure the minimum frame width did not insert extra space between the buttons in a row.
import java.awt.*;
import java.awt.Image;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class HelloWorldSwing {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
TestView.getView();
}
});
}
}
class TestView {
private static TestView view = new TestView();
public static TestView getView() {
return view;
}
private TestView() {
JFrame frame = new JFrame("HelloWorldSwing");
frame.setLayout(new GridLayout(3,4));
int buttonSize = 40;
for (int i=0; i<12; i++) {
frame.getContentPane().add(new MyButton(buttonSize));
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void initialize() {
}
}
class MyButton extends JButton {
int size;
public MyButton(int size) {
this.size = size;
setPreferredSize(new Dimension(size, size));
this.addActionListener(new ButtonHandler());
setOpaque(true);
setYellow();
}
public Image getImage(int sz, Color color) {
BufferedImage bi = new BufferedImage(sz,sz,BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
g.setColor(color);
g.fillRect(0, 0, sz, sz);
g.dispose();
return bi;
}
public void setYellow() {
Image img = getImage(64, Color.YELLOW).getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH);
setIcon(new ImageIcon(img));
Image rollover = getImage(64, Color.ORANGE).getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH);
setRolloverIcon(new ImageIcon(rollover));
setBorderPainted(false);
setContentAreaFilled(false);
}
}
class ButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
MyButton mb = (MyButton) e.getSource();
mb.setYellow();
}
}

Related

Can I change the location of the ImageIcon that I put on a JLabel in my code?

I tried using, "label.setBounds(100,100,250,250)" and "label.setLocation(100,100)" but the image does not move from the top and center of the JLabel.
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Machine extends JPanel
{
public Machine()
{
ImageIcon imageIcon = new ImageIcon("res/robot.png");
JLabel label = new JLabel(imageIcon);
add(label);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.add(new Machine());
frame.setVisible(true);
frame.setSize(new Dimension(1080, 720));
}
}
What are you trying to do?
The default layout of a JPanel is a FlowLayout with center alignment and the label is displayed at its preferred size. So the label is displayed in the center.
You have a couple of options:
Change the alignment of the FlowLayout to be either LEFT or RIGHT
Don't add the label to the panel. Just add it directly to the frame which uses a BorderLayout.
Then you can do something like:
label.setHorizontalAlignment(JLabel.LEFT);
label.setVerticalAlignment(JLabel.CENTER);
Edit:
was just trying to get the image to be in the middle of the frame
Then post your actual requirement when you ask a question. We don't know what "can I change the location" means to you.
So you would either use the BorderLayout and adjust the horizontal/vertical alignment as already demonstrated.
Or, you could set the layout manager of the frame to be a GridBagLayout and then add the label directly to the frame and use:
frame.add(label, new GridBagConstraints());
Now the label will move dynamically as the frame is resized.
If you want to place an image in a certain location, perhaps best is to draw it directly in your JPanel in a paintComponent method override, using one of Graphics drawImage(...) methods, one that allows placement of the image.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class Machine extends JPanel {
private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/f/f2/Abraham_Lincoln_O-55%2C_1861-crop.jpg/"
+ "250px-Abraham_Lincoln_O-55%2C_1861-crop.jpg";
private BufferedImage img;
private int x;
private int y;
public Machine() {
setPreferredSize(new Dimension(1080, 720));
x = 100; // or wherever you want to draw the image
y = 100;
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, x, y, this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Machine());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
Version 2: MouseListener / MouseMotionListener so that the image can be moved
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class Machine extends JPanel {
private static final String IMG_PATH = "https://upload.wikimedia.org/"
+ "wikipedia/commons/thumb/f/f2/"
+ "Abraham_Lincoln_O-55%2C_1861-crop.jpg/"
+ "250px-Abraham_Lincoln_O-55%2C_1861-crop.jpg";
private BufferedImage img;
private int x;
private int y;
public Machine() {
setPreferredSize(new Dimension(1080, 720));
x = 100; // or wherever you want to draw the image
y = 100;
MyMouse mouse = new MyMouse();
addMouseListener(mouse);
addMouseMotionListener(mouse);
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, x, y, this);
}
}
private class MyMouse extends MouseAdapter {
private Point offset;
#Override
public void mousePressed(MouseEvent e) {
// check if left mouse button pushed
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
// get bounds of the image and see if mouse press within bounds
Rectangle r = new Rectangle(x, y, img.getWidth(), img.getHeight());
if (r.contains(e.getPoint())) {
// set the offset of the mouse from the left upper
// edge of the image
offset = new Point(e.getX() - x, e.getY() - y);
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (offset != null) {
moveImg(e);
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (offset != null) {
moveImg(e);
}
offset = null;
}
private void moveImg(MouseEvent e) {
x = e.getX() - offset.x;
y = e.getY() - offset.y;
repaint();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Machine());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

Java - Creating PNG/Textlogo and drawing it to JFrame

I'm trying to print a string that the user can enter to a textbox, to a JFrame.
My problem is that the paintComponent method is never being called. Why?
PNGCreatorWindow Class:
public class PNGCreatorWindow {
private JFrame frame;
private JTextField txtText;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
PNGCreatorWindow window = new PNGCreatorWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public PNGCreatorWindow() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 678, 502);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
txtText = new JTextField();
txtText.setBounds(121, 13, 216, 22);
frame.getContentPane().add(txtText);
txtText.setColumns(10);
JButton btnGenerate = new JButton("Generate");
btnGenerate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
}
});
btnGenerate.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
GeneratePNGImage();
}
});
btnGenerate.setBounds(436, 6, 183, 36);
frame.getContentPane().add(btnGenerate);
JPanel panel = new JPanel();
panel.setBounds(107, 151, 338, 160);
frame.getContentPane().add(panel);
}
protected void GeneratePNGImage() {
PNGImage img = new PNGImage(txtText.getText());
frame.getContentPane().add(img);
frame.getContentPane().validate();
frame.getContentPane().setVisible(true);
frame.repaint();
}
}
PNGImage Class:
public class PNGImage extends JComponent {
private String text;
public PNGImage(String text){
this.text = text;
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.red);
g2.drawString(this.text, 100,100);
g2.fillRect(50, 50, 1000, 1000);
}
}
I made a few changes to your code to get it to draw the text on the JPanel.
I put the JTextField and the JButton inside of a control panel (JPanel) and set a layout manager (FlowLayout) for the control panel. You should always use a layout manager for laying out Swing components.
I defined the image panel (PNGImage) as part of the laying out of the Swing components. First, you lay all of the Swing components out. Then, you change their state.
I removed the mouse adapter and just used an action listener on the JButton. The action listener works with the mouse.
In the PNGImage class, I added a setter, so I could pass the text to the class later, after the user typed the text in the JTextField.
I added a call to setPreferredSize so that I could set the size of the drawing canvas. I removed all other sizing, and used the pack method of JFrame to make the JFrame the appropriate size to hold the Swing components.
I added a null test to paintComponent, so that the text would only be drawn when there was some text to draw.
Here's the code. I put all the code in one module to make it easier to paste.
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class PNGCreatorWindow {
private JFrame frame;
private JTextField txtText;
private PNGImage imagePanel;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new PNGCreatorWindow();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public PNGCreatorWindow() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
txtText = new JTextField(10);
controlPanel.add(txtText);
JButton btnGenerate = new JButton("Generate");
btnGenerate.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
generatePNGImage();
}
});
controlPanel.add(btnGenerate);
imagePanel = new PNGImage();
frame.getContentPane().add(controlPanel, BorderLayout.NORTH);
frame.getContentPane().add(imagePanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
protected void generatePNGImage() {
imagePanel.setText(txtText.getText());
imagePanel.repaint();
}
public class PNGImage extends JPanel {
private static final long serialVersionUID = 602718701626241645L;
private String text;
public PNGImage() {
setPreferredSize(new Dimension(400, 300));
}
public void setText(String text) {
this.text = text;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.text != null) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red);
g2.drawString(this.text, 100, 100);
}
}
}
}
Edited to add an action listener that saves the contents of a JPanel as a .png file:
package com.ggl.crossword.controller;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import com.ggl.crossword.view.CrosswordFrame;
public class CreateImageActionListener implements ActionListener {
private CrosswordFrame frame;
private JPanel panel;
public CreateImageActionListener(CrosswordFrame frame,
JPanel panel) {
this.frame = frame;
this.panel = panel;
}
#Override
public void actionPerformed(ActionEvent event) {
writeImage();
}
public void writeImage() {
FileFilter filter =
new FileNameExtensionFilter("PNG file", "png");
JFileChooser fc = new JFileChooser();
fc.setFileFilter(filter);
int returnValue = fc.showSaveDialog(frame.getFrame());
if (returnValue == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
if (!file.getAbsolutePath().endsWith(".png")) {
file = new File(file.getAbsolutePath() + ".png");
}
RenderedImage image = createImage(panel);
try {
ImageIO.write(image, "png", file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private BufferedImage createImage(JPanel panel) {
int w = panel.getWidth();
int h = panel.getHeight();
BufferedImage bi = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
g.dispose();
return bi;
}
}

Background image in java swing issue

I've made a Jpanel with a background image and a Jbutton also with its background. The problem is that background sometimes is loaded sometimes no.
public class Window extends JFrame {
public static JFrame createwindow() {//fare singleton
JFrame frame = new JFrame("Battaglia navale");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(740, 740);
frame.setVisible(true);
frame.setResizable( false );
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(((int)dim.getWidth()-(int)frame.getWidth())/2, ((int)dim.getHeight()-(int)frame.getHeight())/2);
return frame;
}
}
public class StartWindow {
JFrame frame;
private JButton button;
private JButton button2;
final String button_start = "img/start.png";
ImageIcon start = new ImageIcon(button_start);
public void CreateStartWindow() {
frame = Window.createwindow();
Container container = frame.getContentPane();
JpanelStart panel = new JpanelStart();
container.add(panel);
this.button = new JButton(start);
button.setActionCommand("start");
button.setHideActionText(true);
button.setOpaque(false);
button.setFocusPainted(false);
button.setBorderPainted(false);
button.setContentAreaFilled(false);
this.button2 = new JButton("Classifica");
panel.add(button);
panel.add(button2);
frame.setVisible(true);
}
public void addActionListener(ActionListener al) {
this.button.addActionListener(al);
this.button2.addActionListener(al);
}
public void chiudi() {
frame.dispose();
}
}
class JpanelStart extends JPanel {
private Image img;
private String path_img = "img/sfondo.jpg";
public JpanelStart() {
img = Toolkit.getDefaultToolkit().createImage(path_img);
loadImage(img);
}
private void loadImage(Image img) {
try {
MediaTracker track = new MediaTracker(this);
track.addImage(img, 0);
track.waitForID(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
protected void paintComponent(Graphics g) {
setOpaque(false);
g.drawImage(img, 0, 0, this);
super.paintComponent(g);
}
}
super.paintComponet should go right after the method signature.
you set the button opacity to false, so it won't be seen.
Run your program from the Event Dispatch Thread.
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new StartWindow().CreateStartWindow();
}
});
}
In your method, you're making the frame visible before adding anything. Leave that out in the method
Don't set the size of the frame. Instead override the getPrefereedSize() of the JPanel and call pack() on the frame.
IMO, I see no use at all for this so-called helper method. I would toss it out the window
You should load your image as an embedded resource, and not from the file system.
img = ImageIO.read(StartWindow.class.getResource(path_img));
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class StartWindow {
JFrame frame;
private JButton button;
private JButton button2;
final String button_start = "img/start.png";
ImageIcon start = new ImageIcon(button_start);
public void CreateStartWindow() throws IOException {
frame = Window.createwindow();
Container container = frame.getContentPane();
JpanelStart panel = new JpanelStart();
container.add(panel);
this.button = new JButton(start);
button.setActionCommand("start");
button.setHideActionText(true);
button.setOpaque(false);
button.setFocusPainted(false);
button.setBorderPainted(false);
button.setContentAreaFilled(false);
this.button2 = new JButton("Classifica");
panel.add(button);
panel.add(button2);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run() {
try {
new StartWindow().CreateStartWindow();
} catch (IOException ex) {
Logger.getLogger(StartWindow.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public void addActionListener(ActionListener al) {
this.button.addActionListener(al);
this.button2.addActionListener(al);
}
public void chiudi() {
frame.dispose();
}
}
class Window {
public static JFrame createwindow() {//fare singleton
JFrame frame = new JFrame("Battaglia navale");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
return frame;
}
}
class JpanelStart extends JPanel {
private static final int D_W = 700;
private static final int D_H = 700;
private Image img;
private String path_img = "/images/logo.gif";
public JpanelStart() throws IOException {
img = ImageIO.read(StartWindow.class.getResource(path_img));
loadImage(img);
}
private void loadImage(Image img) {
try {
MediaTracker track = new MediaTracker(this);
track.addImage(img, 0);
track.waitForID(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, D_W, D_W, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(D_W, D_H);
}
}
**Shows Up Every time **
draw the image after super.paintComponent(g) (which draws the component that you want to draw on top of)
call repaint() in loadImage() after the image is set (so that it redraws it)
loadImage() doesn't seem to be setting the img variable does it need to?
(not essential but recommended) you should also move UI changes into the EDT (Event Dispatch Thread).
Example of running a UI task on EDT
This puts UI operations on a queue so that all UI changes are made from the same thread and avoid interference.
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
//UI Operations
}
} );

move image from one panel to another

I have Code where I can move image.
Everything works well.
here I have only one ImagePanel (children of JPanel) on the frame.
Questions:
I need to drag and drop image from one JPanel to another JPanel.
Then I need to move dragged image to current panel.
Can you give me an example code, please?
class ImagePanel extends JPanel {
int x, y;
BufferedImage image;
ImagePanel() {
setBackground(Color.white);
setSize(450, 400);
addMouseMotionListener(new MouseMotionHandler());
Image img = getToolkit().getImage("C:\\2.png");
MediaTracker mt = new MediaTracker(this);
mt.addImage(img, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Image not found.");
}
image = new BufferedImage(img.getWidth(this), img.getHeight(this),BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
g2.drawImage(img, 0, 0, this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(image, x, y, this);
}
class MouseMotionHandler extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e) {
}
}
}
I need to do that code, with this following design. I need to add image with some layout (I don't need to done this with Point pixels). or how to add image with some layout? for example Grid bag layout. I don't need Points (x,y). because I need to add another components too.
public class DragAndDrop {
private JFrame frame;
/* .. another component here .. */
private JPanel leftPanel; // here is my image
public JPanel rightContentPanel; // destination of dragable image
public static void main(String[] args) {
DragAndDrop window = new DragAndDrop();
}
public DragAndDrop() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.getContentPane().setLayout(new BorderLayout(0, 0));
leftPanel = new leftPanel();
/* add components to left panel */
rightContentPanel = new rightPanel();
/* add component to right panel */
frame.getContentPane().add(rightContentPanel, BorderLayout.CENTER);
frame.getContentPane().add(leftPanel, BorderLayout.WEST);
frame.setVisible(true);
frame.setResizable(false);
}
}
class leftPanel extends JPanel {
/ ... /
}
class rightPanel extends JPanel{
/ ... /
}
There's probably any number of ways to achieve what you want. You could use the glass pane or JXLayer or you could stop treating the two panels as separate elements and more like they were just windows into a large virtual space.
This example basically treats the parent component as the "virtual space" into which the two image panes are windows.
They both share the same image and image location details. They, individual, convert the image location (which is in virtual coordinates) to local coordinates and draw as much of the image as would appear on them...
Mouse control is maintained by the parent. This greatly simplifies the process, as it can notify both the panels simultaneously
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class CrossImage {
public static void main(String[] args) {
new CrossImage();
}
public CrossImage() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage img;
private ImagePane left;
private ImagePane right;
private Point imagePoint;
public TestPane() {
setBorder(new EmptyBorder(10, 10, 10, 10));
setLayout(new GridLayout(0, 2, 10, 10));
left = new ImagePane();
right = new ImagePane();
imagePoint = new Point(10, 10);
left.setImageLocation(imagePoint);
right.setImageLocation(imagePoint);
try {
img = ImageIO.read(new File("Background.jpg"));
left.setImage(img);
right.setImage(img);
} catch (IOException ex) {
ex.printStackTrace();
}
add(left);
add(right);
MouseAdapter mouseHandler = new MouseAdapter() {
private Point delta;
#Override
public void mousePressed(MouseEvent e) {
Point origin = e.getPoint();
Rectangle bounds = new Rectangle(imagePoint, new Dimension(img.getWidth(), img.getHeight()));
if (bounds.contains(origin)) {
delta = new Point(origin.x - imagePoint.x, origin.y - imagePoint.y);
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (delta != null) {
imagePoint = e.getPoint();
imagePoint.translate(-delta.x, -delta.y);
left.setImageLocation(imagePoint);
right.setImageLocation(imagePoint);
}
}
#Override
public void mouseReleased(MouseEvent e) {
delta = null;
}
};
addMouseListener(mouseHandler);
addMouseMotionListener(mouseHandler);
}
}
public class ImagePane extends JPanel {
private Image image;
private Point imageLocation;
public ImagePane() {
setBorder(new LineBorder(Color.DARK_GRAY));
}
#Override
public Dimension getPreferredSize() {
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this));
}
public void setImage(Image image) {
this.image = image;
repaint();
}
public void setImageLocation(Point imageLocation) {
this.imageLocation = imageLocation;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null && imageLocation != null) {
Point p = SwingUtilities.convertPoint(getParent(), imageLocation, this);
g.drawImage(image, p.x, p.y, this);
}
}
}
}

JPanel with a background image which has some part transparent

My image is like a frame which is transparent in the middle. I want to make it as background image of a JPanel. I have done this but for the transparent part of image, white color is coming. I want to remove this white color so that the components below this Jpanel become visible.
My code for custom JPanel is
public class JPanelWithBackground extends JPanel {
private static final long serialVersionUID = 1L;
Image imageOrg = null;
Image image = null;
{
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
int w = JPanelWithBackground.this.getWidth();
int h = JPanelWithBackground.this.getHeight();
image = w>0&&h>0?imageOrg.getScaledInstance(w,h,
java.awt.Image.SCALE_SMOOTH):imageOrg;
JPanelWithBackground.this.repaint();
});
}
public JPanelWithBackground(Image image2) {
imageOrg=image2;
image=image2;
setOpaque(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (image!=null)
g.drawImage(image, 0, 0, null);
}
}
I don't have any particular problem with your code. The problem is probably that your image is not transparent as you expect.
Here is an example that seems to work perfectly (I only took the liberty to fix minor issues in your code):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JPanelWithBackground extends JPanel {
private static final long serialVersionUID = 1L;
Image imageOrg = null;
public JPanelWithBackground(Image image2) {
imageOrg = image2;
setOpaque(false);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(imageOrg.getWidth(this), imageOrg.getHeight(this));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (imageOrg != null) {
System.err.println("painting");
g.drawImage(imageOrg, 0, 0, getWidth(), getHeight(), this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanelWithBackground panel = new JPanelWithBackground(new ImageIcon(new URL(
"http://www.lemondedemario.fr/images/dossier/bowser/bowser.png")).getImage());
JPanel greenPanel = new JPanel(new BorderLayout());
greenPanel.setBackground(Color.GREEN);
greenPanel.add(panel);
frame.add(greenPanel);
frame.pack();
frame.setVisible(true);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}

Categories