This is for a class assignment. I am supposed to load a file and display it on my Swing application.
I followed the process from the notes but they were vague, I also used other stackoverflow posts, but I am not able to get this to work. When I load an image the program does not crash, but nothing displays.
-Do I have to repaint or refresh the file after the image is loaded? I tried that but it did not work. what am I doing wrong? The repaint method is commented.
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Part1 {
public static File selectedFile;
public static void main(String[] args) {
JFrame frame = buildFrame();
JButton button = new JButton("Select File");
frame.add(button);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JFileChooser fileChooser = new JFileChooser();
int returnValue = fileChooser.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION)
{
selectedFile = fileChooser.getSelectedFile();
CardImagePanel image = new CardImagePanel(selectedFile);
frame.add(image);
// frame.repaint();
}
}
});
}
private static JFrame buildFrame()
{
JFrame frame = new JFrame();
frame.setSize(1000,1000);
frame.setLayout(new FlowLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
return frame;
}
}
class CardImagePanel extends JPanel {
private BufferedImage image;
public CardImagePanel(File newImageFile)
{
try {
image = ImageIO.read(newImageFile);
} catch (IOException e){
e.printStackTrace();}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, 500, 500, this);
}
}
As was mentioned, you need to call frame.revalidate(); after you add the new component.
You also should call image.setPreferredSize(new Dimension(500, 500)); or similar to ensure that your image isn't tiny.
Related
So I want to use the ocr-a font for my Text in my little Brick Breaker Game.
I tried to import a font I downloaded as .ttf. Then I tried to use it on my JButton with "btn_StartGame.setFont(ocr);". But then when I try to run it the Font didn't change. Can somebody please help me. I'm still learning to code so if I can do something better just tell me.
This should only be something like a starting window and a game window where the actual game runs which is not created yet.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.IOException;
public class BrickBreaker extends JFrame
{
Font ocr;
private javax.swing.JButton btn_StartGame;
public BrickBreaker()
{
components();
}
private void components()
{
try
{
ocr = Font.createFont(Font.TRUETYPE_FONT, new File("ocr-aregular.ttf")).deriveFont(100f);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(ocr);
} catch(IOException | FontFormatException e)
{
}
JFrame menuFrame = new JFrame();
JFrame gameFrame = new JFrame();
ImageIcon frameIcon = new ImageIcon("C:/Users/xxx/Desktop/Programmieren/Java/Brick Breaker/BrickBreakerLogo.png");
menuFrame.setDefaultCloseOperation(menuFrame.EXIT_ON_CLOSE);
menuFrame.setPreferredSize(new Dimension(800, 600));
menuFrame.setLocationRelativeTo(null);
menuFrame.setTitle("Menu");
menuFrame.setIconImage(frameIcon.getImage());
menuFrame.setResizable(false);
menuFrame.getContentPane().setBackground(Color.gray);
menuFrame.pack();
menuFrame.setVisible(true);
gameFrame.setIconImage(frameIcon.getImage());
gameFrame.setDefaultCloseOperation(gameFrame.EXIT_ON_CLOSE);
gameFrame.setLocationRelativeTo(null);
gameFrame.setTitle("Brick Breaker");
gameFrame.setPreferredSize(new Dimension(800, 600));
gameFrame.setResizable(false);
gameFrame.getContentPane().setBackground(Color.gray);
gameFrame.pack();
gameFrame.setVisible(false);
btn_StartGame = new JButton();
btn_StartGame.setText("Start Game");
btn_StartGame.setFont(ocr);
btn_StartGame.setBounds(250, 400, 300, 100);
btn_StartGame.setBackground(Color.black);
btn_StartGame.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent evt)
{
menuFrame.setVisible(false);
gameFrame.setVisible(true);
}
});
menuFrame.getContentPane().setLayout(null);
menuFrame.getContentPane().add(btn_StartGame);
}
public static void main(String[] args)
{
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
new BrickBreaker().setVisible(true);
}
});
}
}
I am getting files from JFileChooser and showing them by reading with BufferedImage and putting in JLabels but there is a problem that my images are not completely shown in JLabels. Here is my code
public class ImagePreview
{
JPanel PicHolder= new JPanel();
public ImagePreview()
{
JButton GetImages = new JButton("Browse Images");
GetImages.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent evt)
{
CreatePreviews();
};
});
PicHolder.add(GetImages);
JFrame MainFrame = new JFrame("Image Preview");
MainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MainFrame.getContentPane().add(PicHolder);
MainFrame.pack();
MainFrame.setVisible(true);
}
public void CreatePreviews()
{
JFileChooser chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(true);
File[] selectedCarImages = chooser.getSelectedFiles();
for(int a=0; a<selectedImages.length; a++)
{
try
{
BufferedImage myPicture = ImageIO.read(new File(selectedImages[a].getAbsolutePath()));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
PicHolder.add(picLabel);
}
}
}
public static void main(String[] args)
{
java.awt.EventQueue.invokeLater(() -> {
new ImagePreview();
});
}
}
When I run this code, it shows user selected images but they are kind of automatically croped and not showing completely in JLabels.
What's wrong here? Why JLabels do not show full images?
You're adding all the components and images to a single panel having the default FlowLayout. Instead, use GridLayout for the picture labels and add the browse button to the frame's default BorderLayout, as shown below.
As tested:
import java.awt.BorderLayout;
import java.awt.GridLayout;
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.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class ImagePreview {
JFrame mainFrame = new JFrame("Image Preview");
JPanel picHolder = new JPanel(new GridLayout(0, 1));
public ImagePreview() {
JButton getImages = new JButton("Browse Images");
getImages.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent evt) {
CreatePreviews();
}
});
mainFrame.add(getImages, BorderLayout.NORTH);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.add(new JScrollPane(picHolder));
mainFrame.pack();
mainFrame.setLocationByPlatform(true);
mainFrame.setVisible(true);
}
public void CreatePreviews() {
JFileChooser chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(true);
chooser.showOpenDialog(mainFrame);
File[] selectedImages = chooser.getSelectedFiles();
for (int a = 0; a < selectedImages.length; a++) {
try {
BufferedImage myPicture = ImageIO.read(new File(selectedImages[a].getAbsolutePath()));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
picHolder.add(picLabel);
mainFrame.pack();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(() -> {
new ImagePreview();
});
}
}
I'm trying to load a background image with a JFileChooser, but when the operation ends, the paintcomponent() method is not called as expected.
[EDIT] for this reason, instead of having a red ball over the background image, I have the red ball only.
I read in several other topics that the instance of my Mappa Object should be added to the frame:
Why is paint()/paintComponent() never called?
paintComponent not being called at the right time
PaintComponent is not being called
But this does not solve my problem: I created a JScrollPane that gets my component in the constructor and linked the JScrollPane and added it in the main frame with
frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER);
This is the code of the main Gui
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
public class Gui implements ActionListener {
private JFrame frmEditor;
Mappa content;
private JMenuItem mntmSfondo;
private JScrollPane scrollabile;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Gui window = new Gui();
window.frmEditor.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Gui() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmEditor = new JFrame();
frmEditor.setFont(UIManager.getFont("TextArea.font"));
frmEditor.setBounds(50, 50, 1024, 768);
frmEditor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmEditor.getContentPane().setLayout(new BorderLayout(0, 0));
JPanel panelTile = new JPanel();
panelTile.setLayout(new BorderLayout(0, 0));
JPanel panelStrum = new JPanel();
panelStrum.setLayout(new GridLayout(15, 2));
content = new Mappa(null);
content.setMinimumSize(new Dimension(150, 150));
scrollabile = new JScrollPane(content);
scrollabile
.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollabile
.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER);
inizializzaMenu();
}
/**
* Initialize the menu.
*/
private void inizializzaMenu() {
JMenuBar menuBar = new JMenuBar();
frmEditor.setJMenuBar(menuBar);
JMenu mnFile = new JMenu("File");
mnFile.setFont(UIManager.getFont("TextArea.font"));
JMenu mnAltro = new JMenu("Modify");
mnAltro.setFont(UIManager.getFont("TextArea.font"));
menuBar.add(mnAltro);
mntmSfondo = new JMenuItem("Load Background");
mntmSfondo
.setIcon(new ImageIcon(
Gui.class
.getResource("/com/sun/java/swing/plaf/windows/icons/TreeOpen.gif")));
mntmSfondo.setFont(UIManager.getFont("TextArea.font"));
mntmSfondo.addActionListener(this);
mnAltro.add(mntmSfondo);
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == mntmSfondo) {
JFileChooser fc = new JFileChooser("tuttiSfondi");
int result = fc.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
try {
content = new Mappa(file);
} catch (Exception ex) {
}
}
if (result == JFileChooser.CANCEL_OPTION) {
}
}
}
}
while this is the code of the class Mappa, that I would like to use to load the background from the JFileChooser.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Mappa extends JPanel {
Image immagine;
public Mappa(File fileImmagine) {
if (fileImmagine != null ) {
BufferedImage img = null;
try {
img = ImageIO.read(new File(fileImmagine.getPath()));
} catch (IOException e) {
e.printStackTrace();
}
this.immagine = img;
}
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.clearRect(0, 0, 4000, 4000);
g.drawImage(immagine, 0, 0, null);
g.setColor(Color.red);
g.fillOval(170, 170, 150, 150);
System.out.println("Called Repaint() on Mappa");
}
}
The problem is not in an incorrect image path, since it loads if I set the path on the Mappa class "manually", by giving the path instead of using new File(fileImmagine.getPath()) in the ImageIO.read, but that paintComponent is called only once, when the constructor of Mappa is called from the Gui class
When you set the background, you only allocate the new Mappa instance, but not actually adding it to any container. Try adding the following:
scrollabile.setViewportView(content);
Or instead, replace an image in the Mappa class. Ie:
public void setImage(File file) throws IOException {
this.immagine = ImageIO.read(file);
repaint();
}
Also, in paintComponent(), you could use panel dimensions to fill the whole area:
g.drawImage(immagine, 0, 0, getWidth(), getHeight(), this);
And don't forget to use a valid ImageObserver as JPanel implements one.
You aren't actually modifying the Mapa instance that you've added to the frame. The line
content = new Mappa(file);
in actionPerformed() doesn't change the panel in the frame, it reassigns the local variable only. You should instead put a method such as updateImage() in Mapa that will update the image that Mapa displays. You will also need to call repaint() after this so that it redraws the new image.
I didn't know how, and there is no background image property. I researched the answer but all I could find was to set a labels icon inside a panel with a null layout. This worked and my image is there, but it is covering all but a single text field. Can I change the Z value of this label? I do not see a 'move to back' option, if there is one.
This should solve your problem:
import java.awt.Dimension;
import java.awt.Graphics;
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;
public class TestImage {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ContentPane panel = new ContentPane();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
});
}
private static class ContentPane extends JPanel {
BufferedImage image = null;
public ContentPane() {
try {
String pathToImage = "C:/Users/Branislav/Pictures/sun.jpg";
image = ImageIO.read(new File(pathToImage));
} catch (IOException e) {
e.printStackTrace();
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
};
#Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(), image.getHeight());
}
}
}
Basically, I set image on JPanel (ContentPane). Also, size of your JPanel depends on size of image (at least in this case).
Regards.
Designing a questionary, the scope of answer can be elected by radioButtons.
To display a greater clickable area (the application is for touchscreen), I layed icon_1 over the radiobuttons.
Every mouseclick can change the displayed icon to icon_2 and permantly vice versa.
I am sorry, using
jRadioButtonActionPerformed
ImageIcon o_ButtonIcon = new ImageIcon ("....")
jRadioButton.setIcon(Icon m_ButtonIcon).
I get no changing, clickable image.
Can you please give me a helping hand?
Seems to be working fine.
Post an SSCCE to show specific problems.
Here is example ( i do not recommend getScaledInstance(..) just used it for quick example)
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
public class Test {
private ImageIcon ii1;
private ImageIcon ii2;
private JRadioButton jrb = new JRadioButton("Click me :)");
private JFrame frame = new JFrame();
public Test() {
try {
ii1 = new ImageIcon(ImageIO.read(new URL("http://cdn.macrumors.com/article/2010/09/03/145454-itunes_10_icon.jpg")).getScaledInstance(48, 48, Image.SCALE_SMOOTH));
ii2 = new ImageIcon(ImageIO.read(new URL("http://www.quarktet.com/Icon-small.jpg")).getScaledInstance(48, 48, Image.SCALE_SMOOTH));
} catch (Exception ex) {
ex.printStackTrace();
}
initComponents();
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
private void initComponents() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jrb.setIcon(ii1);
jrb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (jrb.getIcon() == ii1) {
jrb.setIcon(ii2);
} else {
jrb.setIcon(ii1);
}
}
});
frame.add(jrb);
frame.pack();
frame.setVisible(true);
}
}