Hi i want to convert panel which contains components like label and buttons to image file.
I have done the following code. The image was saved. but the content of the panel not visible or saved. Can anyone tell me how to save the panel with its components.
Code:
package PanelToImage;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
public class sample extends JPanel {
public JPanel firstpanel;
public JPanel secondpanel;
JLabel label1, label2;
JButton button1, button2;
public sample() {
firstpanel = new JPanel();
firstpanel.setSize(400,300);
firstpanel.setBackground(Color.RED);
secondpanel = new JPanel();
secondpanel.setBackground(Color.GREEN);
secondpanel.setSize(400,300);
label1 = new JLabel("label1");
label2 = new JLabel("label2");
button1 = new JButton("button1");
button2 = new JButton("button2");
firstpanel.add(label1);
firstpanel.add(button1);
secondpanel.add(label2);
secondpanel.add(button2);
saveImage(firstpanel);
add(firstpanel);
// add(secondpanel);
}
public static void main(String args[]) {
JFrame frame = new JFrame();
sample sam = new sample();
frame.setContentPane(sam);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
}
private void saveImage(JPanel panel) {
BufferedImage img = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
panel.paint(img.getGraphics());
try {
ImageIO.write(img, "png", new File("E://Screen.png"));
System.out.println("panel saved as image");
} catch (Exception e) {
System.out.println("panel not saved" + e.getMessage());
}
}
}
Tthis code works for me (in the JFrame):
Container c = getContentPane();
BufferedImage im = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_INT_ARGB);
c.paint(im.getGraphics());
ImageIO.write(im, "PNG", new File("shot.png"));
Maybe you have used custom panels. If true, try to add super.paint(g) at the beginning of the paint methods of your panels.
EDIT: You have to call saveImage after display the frame:
public static void main(String args[]) {
...
frame.setSize(400, 300);
sam.saveImage(sam.firstpanel);
}
EDIT 2: This is the saved image (is little because the layout, but is the proof that it should work):
I called the saveImage as last call in the main, and used a file in the user dir (new File("Screen.png")) as nIcE cOw said.
Here try this example program, instead of using getGraphics() seems like you have to use createGraphics() for the BufferedImage you are about to make.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
public class SnapshotExample
{
private JPanel contentPane;
private void displayGUI()
{
JFrame frame = new JFrame("Snapshot Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
contentPane.setBackground(Color.WHITE);
JLabel label = new JLabel("This JLabel will display"
+ " itself on the SNAPSHOT", JLabel.CENTER);
contentPane.add(label);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
makePanelImage(contentPane);
}
private void makePanelImage(Component panel)
{
Dimension size = panel.getSize();
BufferedImage image = new BufferedImage(
size.width, size.height
, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
panel.paint(g2);
try
{
ImageIO.write(image, "png", new File("snapshot.png"));
System.out.println("Panel saved as Image.");
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new SnapshotExample().displayGUI();
}
});
}
}
Related
Previously I had just 1 canvas with mouse events, and the "buttons" were just coordinates that executed a method when the cursor clicked within its box.
Then I decided against doing that, and just implemented JButtons with ImageIcons, but that made it so that I couldn't put the JButtons on top of my Canvas, so instead I poked around and saw some topics telling me to use a JLabel & ImageIcon that fills up the whole screen. (In addition, I tried doing the same thing with a JPanel & PaintComponent instead of a JLabel & ImageIcon)
I posted this on Reddit but apparently it worked for other people, and I couldn't find out why it didn't work for me. Here is workable code that I snipped off from my actual project:
package hoverProblem;
import java.awt.Canvas;
public class ClientReddit extends Canvas {
public static void main(String args[]) {
ClientReddit client = new ClientReddit();
ClientWindow window = new ClientWindow();
}
}
And here is the Window:
package hoverProblem;
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ClientWindow {
// Attributes
private JFrame frame;
private static Dimension dm = new Dimension();
private String title;
private final Dimension BUTTONSIZE = new Dimension(100, 50);
private final Dimension MENUSIZE = new Dimension(600, 500);
// Main Menu
private JLabel mainMenuBG = new JLabel(new ImageIcon("graphics/gui/MainMenu.png"));
private ImageIcon loginButtonImg = new ImageIcon("graphics/gui/buttons/LoginButton.png");
private ImageIcon signUpButtonImg = new ImageIcon("graphics/gui/buttons/SignUpButton.png");
private ImageIcon optionsButtonImg = new ImageIcon("graphics/gui/buttons/OptionsButton.png");
private ImageIcon updateButtonImg = new ImageIcon("graphics/gui/buttons/UpdateButton.png");
private ImageIcon creditsButtonImg = new ImageIcon("graphics/gui/buttons/CreditsButton.png");
private JButton loginButton = new JButton(loginButtonImg);
private JButton signUpButton = new JButton(signUpButtonImg);
private JButton optionsButton = new JButton(optionsButtonImg);
private JButton updateButton = new JButton(updateButtonImg);
private JButton creditsButton = new JButton(creditsButtonImg);
// Borders count for some reason
private final int hOffset = 29, wOffset = 6;
public ClientWindow() {
frame = new JFrame();
frame.setLayout(null);
title = "Reddit";
dm.setSize(600 + wOffset, 500 + hOffset);
loginButton.setSize(BUTTONSIZE);
signUpButton.setSize(BUTTONSIZE);
optionsButton.setSize(BUTTONSIZE);
updateButton.setSize(BUTTONSIZE);
creditsButton.setSize(BUTTONSIZE);
loginButton.setLocation(20, 430);
signUpButton.setLocation(135, 430);
optionsButton.setLocation(250, 430);
updateButton.setLocation(365, 430);
creditsButton.setLocation(480, 430);
mainMenuBG.setSize(MENUSIZE);
frame.setTitle(title);
frame.setSize(dm);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.add(mainMenuBG);
frame.add(loginButton);
frame.add(signUpButton);
frame.add(optionsButton);
frame.add(updateButton);
frame.add(creditsButton);
frame.setVisible(true);
}
}
You're overlaying and placing objects incorrectly. If you're going to use the JLabel as a background image and want to place components over it, then give the actually add components to the JLabel, not to the JFrame, and then finally add only the JLabel to the JFrame. Your other option is to draw the background image in a JPanel's paintComponent method and then add all your components to it.
Other problems include your use of null layout and set size and position. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
For example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ClientPanel extends JPanel {
private static final String COMMON = "https://upload.wikimedia.org/wikipedia/commons/";
private static final String BACKGROUND = "0/0e/Farol_-_Prieto_Coussent.jpg";
private static final String[] BTN_PATHS = {
"thumb/0/09/HanDev.jpg/100px-HanDev.jpg",
"thumb/3/3f/SugababesInEntirety.png/100px-SugababesInEntirety.png",
"thumb/c/c5/GeorgesDanton.jpg/100px-GeorgesDanton.jpg",
"thumb/5/54/Written_on_the_wind8.jpg/100px-Written_on_the_wind8.jpg",
"thumb/6/6d/COP_20000_anverso_%281996-2016%29.jpg/100px-COP_20000_anverso_%281996-2016%29.jpg"
};
private Image background = null;
public ClientPanel() throws IOException {
URL imgUrl = new URL(COMMON + BACKGROUND);
background = ImageIO.read(imgUrl);
JPanel btnPanel = new JPanel(new GridLayout(1, 0, 15, 0));
btnPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
btnPanel.setOpaque(false);
for (String btnPath : BTN_PATHS) {
String imgPath = COMMON + btnPath;
imgUrl = new URL(imgPath);
Image img = ImageIO.read(imgUrl);
Icon icon = new ImageIcon(img);
JButton btn = new JButton(icon);
JPanel wrapperPanel = new JPanel();
wrapperPanel.setOpaque(false);
wrapperPanel.add(btn);
btnPanel.add(wrapperPanel);
}
setLayout(new BorderLayout());
add(btnPanel, BorderLayout.PAGE_END);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
g.drawImage(background, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || background == null) {
return super.getPreferredSize();
}
int prefW = background.getWidth(this);
int prefH = background.getHeight(this);
return new Dimension(prefW, prefH);
}
private static void createAndShowGui() {
ClientPanel mainPanel = null;
try {
mainPanel = new ClientPanel();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("Client");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
I am creating a Flight Reservation system for a project, having trouble with the GUI of the app. I am using a CardLayout to manage the multiple cards for this program.
In the login card I am trying to add a background image, but the input fields are shown below the image.
The code for the program is
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import javax.imageio.*;
import java.net.*;
public class CardPanel {
public static void main(String[] args) {
try {
CardLayout cardLayout = null;
JFrame frame = new JFrame("Welcome");
JPanel contentPane = new JPanel(cardLayout);
URL url = new URL("https://i.stack.imgur.com/P59NF.png");
BufferedImage img = ImageIO.read(url);
ImageIcon imageIcon = new ImageIcon(img);
JLabel logo = new JLabel(imageIcon);
JPanel buttonsPanel = new JPanel();
JButton login = new JButton("Login");
buttonsPanel.add(login);
contentPane.setLayout(new BorderLayout(10, 15));
contentPane.add(logo, BorderLayout.NORTH);
contentPane.add(buttonsPanel, BorderLayout.SOUTH);
frame.add(contentPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
A screenshot of the app is also attached (http://i.imgur.com/PkjblPu.png).
I would like the button to be above the background image.
A test suggests a card layout cannot be used to show a BG image. It seems that internally it removes one card and adds another when swapping components. Use a custom painted JPanel to draw the BG image.
Here is the evidence.
That red color is the panel with the card layout, the button panel is set to be transparent.
import java.awt.*;
import javax.swing.*;
import java.net.URL;
public class CardPanel {
public static void main(String[] args) throws Exception {
CardLayout cardLayout = new CardLayout();
JFrame frame = new JFrame("Welcome");
JPanel contentPane = new JPanel(cardLayout);
contentPane.setBackground(Color.RED);
ImageIcon imageIcon = new ImageIcon(new URL("https://i.stack.imgur.com/OVOg3.jpg"));
JLabel logo = new JLabel(imageIcon);
JPanel buttonsPanel = new JPanel();
JButton login = new JButton("Login");
buttonsPanel.add(login);
buttonsPanel.setOpaque(false);
contentPane.add(logo, "logo");
contentPane.add(buttonsPanel, "button");
cardLayout.show(contentPane, "button");
frame.add(contentPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
I am doing a layout, and I have a pair of buttons that I would like to be flush together. I can think of a couple ways to accomplish this, but I am wondering if there is a good way.
Here is some template code:
package helloworld;
import javax.swing.BoxLayout;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.EventQueue;
/**
* Created by matt on 22/07/16.
*/
public class FlushButtons {
private void showGui(){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton plus = new JButton("+");
JButton minus = new JButton("-");
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(plus);
panel.add(minus);
frame.setContentPane(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
EventQueue.invokeLater(()->{
new FlushButtons().showGui();
});
}
}
That produces the image on the left, but I would like it to look more like the image on the right.
I tried using JButton#setMargin, but that did not have any effect. I have used JButton#setPreferredSize which I can get the desired result, but I need to know the size of the button beforehand.
Here's my solution which looks ..pretty neat!
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class FlushButtons {
private JComponent ui = null;
FlushButtons() {
initUI();
}
private JButton getFlushButton(String text) {
JButton b = new JButton();
b.setBorderPainted(false);
b.setContentAreaFilled(false);
b.setMargin(new Insets(0,0,0,0));
b.setBorder(null);
b.setIcon(new ImageIcon(getImageOfText(text, Color.GREEN.darker())));
b.setRolloverIcon(new ImageIcon(getImageOfText(text, Color.ORANGE)));
b.setPressedIcon(new ImageIcon(getImageOfText(text, Color.RED)));
return b;
}
private BufferedImage getImageOfText(String text, Color color) {
int s = 24;
BufferedImage bi = new BufferedImage(s, s, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
g.setColor(color);
g.fillRect(0, 0, s, s);
g.setColor(Color.BLACK);
g.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 16));
// use better ways to position text..
g.drawString(text, 8, 16);
g.dispose();
return bi;
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
ui.setBorder(new EmptyBorder(4,4,4,4));
ui.add(getFlushButton("+"));
ui.add(getFlushButton("-"));
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
FlushButtons o = new FlushButtons();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
Here is my solution, which looks a bit ridiculous.
JPanel panel = new JPanel();
JButton plus = new JButton("+");
JButton minus = new JButton("-");
plus.setPreferredSize(new Dimension(29, 29));
plus.setMaximumSize(new Dimension(33, 33));
minus.setPreferredSize(new Dimension(29, 29));
minus.setMaximumSize(new Dimension(33, 33));
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(plus);
panel.add(minus);
panel.add(Box.createVerticalStrut(33));
panel.add(Box.createHorizontalGlue());
Without the vertical strut the buttons get packed without borders.
Something of a hack, hope to hear something better.
I would like, for a java project, to change the color of a hair modelisation (to change hair color) with shadows and reflects...
In fact, I wondered if there's a class which can change the color of a picture with a RGB code. If this can help you, here's the picture I need to colorize :
I assume that the question targeted NOT at blindly replacing certain pixels with a certain (fixed) color, but at really "dyeing" the image. Once I wrote a sample class showing how this could be done:
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*;
import javax.imageio.*;
class DyeImage
{
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
new DyeImage();
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
public DyeImage() throws Exception
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage image = ImageIO.read(new File("DRVpH.png"));
JPanel panel = new JPanel(new GridLayout(1,0));
panel.add(new JLabel(new ImageIcon(image)));
panel.add(new JLabel(new ImageIcon(dye(image, new Color(255,0,0,128)))));
panel.add(new JLabel(new ImageIcon(dye(image, new Color(255,0,0,32)))));
panel.add(new JLabel(new ImageIcon(dye(image, new Color(0,128,0,32)))));
panel.add(new JLabel(new ImageIcon(dye(image, new Color(0,0,255,32)))));
f.getContentPane().add(panel);
f.pack();
f.setVisible(true);
}
private static BufferedImage dye(BufferedImage image, Color color)
{
int w = image.getWidth();
int h = image.getHeight();
BufferedImage dyed = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
Graphics2D g = dyed.createGraphics();
g.drawImage(image, 0,0, null);
g.setComposite(AlphaComposite.SrcAtop);
g.setColor(color);
g.fillRect(0,0,w,h);
g.dispose();
return dyed;
}
}
The result with the given image and different dyeing colors will look like this:
hi all i am trying to add multiple components to my jframe. but i cant seem to get it to work.
private void initGUI() {
setAlwaysOnTop(true);
setUndecorated(true);
AWTUtilities.setWindowOpaque(this, false);
AWTUtilities.setWindowOpacity(this, 0.5f);
setLocation(ini.getButtonsX(), ini.getButtonsY());
setSize(ini.getButtonsW(), ini.getButtonsH());
setLayout(null);
JPanel panel = new JPanel();
panel.setLayout(null);
ImageView baron = new ImageView("image/nashor.png", 50, 50);
baron.setBounds(50, 50, 50, 50);
ImageView test = new ImageView("image/dragon.png", 50, 50);
test.setBounds(50, 150, 50, 50);
panel.add(baron);
panel.add(test);
panel.setBounds(0, 0, ini.getButtonsW(), ini.getButtonsH());
add(panel);
}
my ImageView is a class that extends a JPanel which paints a image.
at this point only nashor is painted
any help is greatly appreciated.
I recommend that you have your JPanel panel use a GridLayout, not a null layout, and that you not set your ImageView sizes but rather make sure that the class has a getPreferredSize() method override that makes sense, that returns a Dimension of the appropriate size. Then if you call pack() on your JFrame after adding components, the layout managers will take care of sizing things for you.
Consider this program:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Init extends JFrame{
JPanel view = new JPanel();
JMenuBar mBar = new JMenuBar();
JMenu menu = new JMenu("File");
JMenuItem mItemOpen = new JMenuItem("Open");
JMenuItem mItemExit = new JMenuItem("Exit");
JFileChooser fc = new JFileChooser();
JTextField txtPath = new JTextField();
BufferedImage myPicture;
File filePath;
String path;
public Init(){
mBar.add(menu);
menu.add(mItemOpen);
menu.addSeparator();
menu.add(mItemExit);
setJMenuBar(mBar);
txtPath.setEditable(false);
mItemOpen.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
fc.showOpenDialog(null);
filePath = fc.getSelectedFile();
path = filePath.getPath();
txtPath.setText(path);
try {
//view.removeAll();
myPicture = ImageIO.read(new File(path));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
view.add(picLabel);
revalidate();
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
setLayout(new BorderLayout());
getContentPane().add(new JScrollPane(view),BorderLayout.CENTER);
getContentPane().add(txtPath,BorderLayout.SOUTH);
setTitle(".:My Picture Viewer:.");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//pack();
setSize(1024,768);
setVisible(true);
}
public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new Init();
}
});
}
}