Java Swing JLabel.setIcon() not working the way I expect - java

I have a probably easy to solve problem. I used Intellij Idea to build a GUI form. Now I am trying to change the imageIcon of the imageLabel JLabel.
I don't really understand why but when I use the JLabel.setIcon() it neither throws an exception nor displays the image. I have no idea what is wrong with it. It seems like a very simple command.
( I added ico.getImage().flush(); line because when I was searching around people said you have to flush the image before displaying it. I don't actually know what that line does.)
Thanks for any help.
public class App
{
private JPanel mainPanel;
private JPanel imagePanel;
private JPanel optionsPanel;
private JPanel palletesPanel;
private JPanel buttonsPanel;
private JPanel originalPalletePanel;
private JPanel newPalletePanel;
private JLabel originalPalleteLabel;
private JLabel newPalleteLabel;
private JPanel leftButtonsPanel;
private JPanel rightButtonsPanel;
private JButton previewButton;
private JButton revertButton;
private JButton convertImageButton;
private JButton matchPalleteButton;
private JLabel originalPalleteImageLabel;
private JLabel newPalleteImageLabel;
private JLabel imageLabel;
public static void main(String[] args)
{
App app = new App();
JFrame frame = new JFrame("Pixel Pigeon");
frame.setContentPane(new App().mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
pigeon pigey = new pigeon();
try
{
app.loadImage(frame, app);
}
catch(java.io.IOException e)
{
e.printStackTrace();
}
}
private void loadImage(JFrame frame, App app) throws IOException
{
JFileChooser chooser = new JFileChooser();
if(chooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION)
{
BufferedImage img = ImageIO.read(chooser.getSelectedFile());
ImageIcon ico = new ImageIcon(img);
ico.getImage().flush();
app.imageLabel.setIcon(ico);
}
}
}

There were a lot of problems with that short section of code. After removing the many redundant components, the reference to a class not in evidence, fixing the two instances of NullPointerException, removing the call to flush the image, and fixing the problem with the new creation of an App() that already existed, it 'works'. But it is still so bad I'd recommend tossing the lot out and starting again with reference to the JavaDocs for investigating things random people recommend, and the Java Tutorial for the basics of GUI development.
So here is the 'fixed' code: It will load an image, but the GUI then needs to be stretched to make the image visible.
import java.awt.image.BufferedImage;
import java.io.*;
import javax.swing.*;
import javax.imageio.ImageIO;
public class App {
private JPanel mainPanel = new JPanel();
private JLabel imageLabel = new JLabel();
public static void main(String[] args) {
App app = new App();
JFrame frame = new JFrame("Pixel Pigeon");
app.mainPanel.add(app.imageLabel);
frame.setContentPane(app.mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
try {
app.loadImage(frame, app);
}
catch(java.io.IOException e) {
e.printStackTrace();
}
}
private void loadImage(JFrame frame, App app) throws IOException {
JFileChooser chooser = new JFileChooser();
if(chooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
BufferedImage img = ImageIO.read(chooser.getSelectedFile());
ImageIcon ico = new ImageIcon(img);
app.imageLabel.setIcon(ico);
}
}
}

Related

How can I add my button on top of my Gif/Png [duplicate]

This question already exists:
Using an image for background
Closed 8 months ago.
Earlier I made a post of having both of them showing up and that got solved but the other problem I ran into is that I am having a hard time stacking them over each other
This is how I have it currently
The way I want it to have is the blue box being on top of the Signup part of the image
Like this
import javax.swing.*;
import java.awt.*;
public class Panel extends JFrame {
private ImageIcon FirstPageImage;
private JLabel FirstPageLabel;
private JLayeredPane SignupButtonLayer;
private JButton Button;
public Panel(){
setLayout (new FlowLayout());
FirstPageImage = new ImageIcon(getClass().getResource("FirstPageAnimationUsing.gif"));
FirstPageLabel = new JLabel(FirstPageImage);
FirstPageImage.setImage(FirstPageImage.getImage().getScaledInstance(343,820,Image.SCALE_DEFAULT));
add(FirstPageLabel);
Button = new JButton();
SignupButtonLayer = new JLayeredPane();
SignupButtonLayer.setPreferredSize(new Dimension(370,850));
//Button.setOpaque(true);
Button.setBackground(Color.cyan);
Button.setBounds(94,617,159,82);
SignupButtonLayer.add(Button, JLayeredPane.DEFAULT_LAYER);
add(SignupButtonLayer);
}
public static void main(String[] args) {
Panel gui = new Panel();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.pack();
gui.setTitle("Reminder App");
gui.setVisible(true);
//gui.setSize(360,850);
}
}
I have a feeling that it has something to do with the Layout but I am not sure

importing images causes rendering issues

Modifiers.java
package game;
import java.awt.*;
import java.io.*;
import javax.swing.*;
public class Modifiers extends Data{
public static void setupJcomponents(){
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try{
PixelFont = Font.createFont(Font.TRUETYPE_FONT, new File("src/game/PixelFont.ttf"));
ge.registerFont(PixelFont);
} catch (IOException | FontFormatException e) {
PixelFont = new Font("OCR A Extended", Font.PLAIN, heightUnits*2);
ge.registerFont(PixelFont);
}
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setSize(MW,MH);
frame.setResizable(false);
frame.setVisible(true);
frame.setLayout(null);
uiPanelMenu.setLayout(null);
uiPanelMenu.setVisible(true);
uiPanelMenu.setBounds(0,0,MW,MH);
uiPanelMenu.setOpaque(false);
for(int btn=0; btn<4; btn++) {
try {
buttonImage[btn] = new ImageIcon(Frame.class.getResource("/game/SelectionButton.png"));
} catch (Exception e) {
e.printStackTrace();
}
buttons[btn] = new JPanel();
buttonLabel[btn] = new JLabel("",SwingConstants.CENTER);
buttonLabel[btn].setIcon(buttonImage[btn]);
buttons[btn].setBounds(widthUnits*15,(heightUnits*13)+(heightUnits*3*btn),widthUnits*15,heightUnits*3);
buttonLabel[btn].setBounds(0,0,buttons[btn].getWidth(),buttons[btn].getHeight());
buttons[btn].setLayout(null);
uiPanelMenu.add(buttons[btn]);
buttons[btn].add(buttonLabel[btn]);
buttonLabel[btn].setForeground(Color.black);
buttons[btn].setBackground(Color.white);
buttonLabel[btn].setText("Button "+(btn+1));
buttonLabel[btn].setFont(new Font("PixelFont", Font.PLAIN, heightUnits*2));
buttons[btn].setVisible(true);
buttonLabel[btn].setVisible(true);
}
menuBackground.setBounds(0,0,MW,MH);
menuBackground.setBackground(Color.black);
menuBackground.setVisible(true);
uiPanelMenu.add(menuBackground);
healthIndicator.setText(String.valueOf(healthValue));
healthIndicator.setFont(new Font("PixelFont", Font.PLAIN, heightUnits*2));
healthIndicator.setBounds(widthUnits*20,heightUnits*20,widthUnits*5,heightUnits*2);
healthIndicator.setVisible(true);
healthIndicator.setOpaque(false);
healthIndicator.setForeground(Color.blue);
uiPanelFight.add(healthIndicator);
frame.getContentPane().add(uiPanelMenu);
}
}
data.java
package game;
import java.awt.*;
import javax.swing.*;
public class Data {
// this is where I will declare and alter all variable that will be used
public static JFrame frame = new JFrame();
public static JLabel healthIndicator = new JLabel("",SwingConstants.CENTER);
public static JPanel buttons[] = new JPanel[5];
public static JLabel buttonLabel[] = new JLabel[5];
public static JPanel menuBackground = new JPanel();
public static JPanel title = new JPanel();
public static JPanel uiPanelMenu = new JPanel();
public static JPanel uiPanelFight = new JPanel();
public static ImageIcon buttonImage[] = new ImageIcon[5];
public static final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public static final int MW = (int) screenSize.getWidth();
public static final int MH = (int) screenSize.getHeight();
public static final int widthUnits = MW/45;
public static final int heightUnits = MH/25;
public static Font PixelFont;
public static int maxHealth = 100;
public static int healthValue = maxHealth;
}
frame.java
package game;
public class Frame {
public static void main(String[] args) {
Modifiers.setupJcomponents();
}
}
whenever i try to reference the image here:
buttonImage[btn] = new ImageIcon(Frame.class.getResource("/game/SelectionButton.png"));
if it is wrong then it will just give me a NullPointerException, but if the image name is correct then the entire panel that holds everything disappears, all of the objects i used are properly declared in a separate Data.java class, i know it is instantiated correctly but i dont know why everything is not rendering when the line hits the image location.
So your code raises so many questions it's not funny. However, your basic problem(s) come down to lack of understanding in how the basic Swing API works.
Swing is lazy. It won't update the UI when you add/remove components from containers, that's up to you.
So, your basic code currently looks like...
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
//frame.setUndecorated(true);
frame.setSize(MW, MH);
//frame.setResizable(false);
frame.setVisible(true);
// ?? Why ?? Besides, it's not doing what you think it is
frame.setLayout(null);
// Add all the stuff to uiPanelMenu ...
frame.getContentPane().add(uiPanelMenu);
The problem is, once you make the window visible, you are responsible for triggering layout and paint passes.
You can fix the basic problem by adding
frame.getContentPane().revalidate();
frame.getContentPane().repaint();
after frame.getContentPane().add(uiPanelMenu); or moving frame.setVisible(true); after frame.getContentPane().add(uiPanelMenu); which will probably produce a more desirable result.
I know you think you're making your life easier by using null layouts, but your not, nor are you taking into considerations all the differences in how text is rendered on different platforms/hardware.
You're doing yourself a massive disservice by not making use of the layout management API (and will end up having to replicate much of its functionality yourself).
Instead, take the time learn more about the available layout managers - Laying Out Components Within a Container

BufferedImage only Appears when Window is Minimized and Re-Maximized

I'm currently writing an application using Java Swing. So far, the application is simple, it creates a window (JFrame) that fills the screen. This JFrame has a main JPanel, and in that JPanel is a JLabel for the title and a JLabel that I'm loading a BufferedImage into. When I run the program, the JLabel containing the title shows up, but the JLabel containing the image I'm loading in doesn't appear. However, when I hit the "minimize" button on the window, and then maximize the window again, the image appears as it should. Why isn't the image showing up when the program is opened? My code is shown below:
public class MainWindow extends JFrame {
private static final int DEFAULT_WIDTH = 1400;
private static final int DEFAULT_HEIGHT = 800;
private JPanel mainPanel;
public MainWindow() {
setup();
}
private void setup() {
this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH);
this.mainPanel = new JPanel(new BorderLayout());
mainPanel.setBackground(Color.BLUE);
this.add(mainPanel);
setupObjectInsertPanel();
}
private void setupObjectInsertPanel() {
JLabel label = new JLabel("TileSets");
mainPanel.add(label, BorderLayout.NORTH);
try{
BufferedImage tilesetImage = ImageIO.read(new File(...)); // path ommitted
JLabel tilesetIcon = new JLabel(new ImageIcon(tilesetImage));
mainPanel.add(tilesetIcon, BorderLayout.SOUTH);
System.out.println("Loaded tileset into panel");
} catch (IOException e) {
System.out.println("Could not open tileset");
e.printStackTrace();
}
}
}
The try statement always succeeds, and the success message is printed when the program starts up, but the image isn't showing up until the window is minimized/re-maximized. Why is this behavior happening?

Swing Intellij GUIDesigner image disappears if placed in JScrollPane

I'm using IntelliJ GUIDesigner.
I have JScrollPanel which contains JPanel.
The idea is that I want to add image to JPanel and to have it load at full size so I can use scrollers to move around and see whole image.
And My problem is that it paints itself alright if I won't change the size of JPanel. But the moment I'm chaning JPanel size it just repaints itself to orginal state (I suppose, IntelliJ hides a lot of code from me).
The code is:
private JPanel panel1;
private JButton button1;
private JPanel drawingPanel;
public MainPanel(){
button1.addActionListener(e -> {
JFileChooser openFile = new JFileChooser();
File chosenFile;
if(openFile.showSaveDialog(panel1) == JFileChooser.APPROVE_OPTION){
chosenFile = openFile.getSelectedFile();
drawImage(chosenFile);
}
});
}
private void drawImage(File file){
try {
BufferedImage image = ImageIO.read(file);
//Works OK if line belowed is removed, but doesn't adjust size so I can't scroll.
drawingPanel.setSize(image.getWidth(), image.getHeight());
Graphics g = drawingPanel.getGraphics();
g.drawImage(image, 0, 0, null);
drawingPanel.paintComponents(g);
}
catch (IOException e) {
e.printStackTrace();
}
}
As I wrote in comment, if the line below the comment is removed then I can load the image and it shows OK but it's too big and I can't see whole image.
If I add the line then it just clears everything and I can't see nothing.
This is important - I need to get the image to show in full size.
How do I do it?
I have JScrollPanel which contains JPanel.
Don't do custom painting.
Just create a JLabel and add the label to the viewport of the scroll pane. Then when you want to change the image you use the setIcon(...) method of the JLabel and the label will automatically repaint itself and scrollbars will appear if necessary.
Maybe you can share your IntelliJ GUI forms? Otherwise it's difficult to reproduce the scrolling problem that you're facing. Without the custom painting and using a label as camickr suggested, you can get scrolling working like this:
public class MainPanel {
private static JFrame frame;
private JPanel panel1;
private JButton button1;
private JPanel drawingPanel;
private JLabel drawingLabel;
public static void main(String[] args) {
MainPanel.test();
}
private static void test() {
frame = new JFrame("");
frame.setBounds(100, 100, 640, 480);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
new MainPanel();
frame.setVisible(true);
}
public MainPanel() {
initializeGui();
button1.addActionListener(e -> {
JFileChooser openFile = new JFileChooser("[...]");
File chosenFile;
if (openFile.showSaveDialog(panel1) == JFileChooser.APPROVE_OPTION) {
chosenFile = openFile.getSelectedFile();
System.out.println("chosenFile: " + chosenFile);
drawImage(chosenFile);
}
});
}
private void initializeGui() {
panel1 = new JPanel(new BorderLayout());
frame.getContentPane().add(panel1);
button1 = new JButton("Open image");
panel1.add(button1, BorderLayout.NORTH);
drawingPanel = new JPanel(new BorderLayout());
panel1.add(drawingPanel, BorderLayout.CENTER);
drawingLabel = new JLabel();
drawingPanel.add(new JScrollPane(drawingLabel), BorderLayout.CENTER);
}
private void drawImage(File file){
try {
BufferedImage image = ImageIO.read(file);
//Works OK if line below is removed, but doesn't adjust size so I can't scroll.
// drawingPanel.setSize(image.getWidth(), image.getHeight());
// Graphics g = drawingPanel.getGraphics();
// g.drawImage(image, 0, 0, null);
// drawingPanel.paintComponents(g);
drawingLabel.setIcon(new ImageIcon(image));
drawingPanel.validate();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Not sure how easy it is to do something similar with the IntelliJ GUI designer; I do prefer IntelliJ (over Eclipse and NetBeans) but I also prefer to create my Java GUIs in code... ;-)

Troubleshooting a Swing Radio Buttons Applet

I have to create a Swing applet for a school assignment, and was given a link (http://java.sun.com/docs/books/tutorial/uiswing/components/index.html) to look at various Swing tutorials and use one of them to create a unique Java applet. I chose to follow the code for the How To Use Radio Buttons tutorial. I read through the code and typed it up while changing things so that they would match my pictures. The code I have is
package components;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class OSButtons extends JPanel implements ActionListener {
static String windowsString = "Windows";
static String linuxString = "Linux";
static String macString = "Mac";
JLabel picture;
public OSButtons() {
super(new BorderLayout());
JRadioButton windowsButton = new JRadioButton(windowsString);
windowsButton.setMnemonic(KeyEvent.VK_W);
windowsButton.setActionCommand(windowsString);
windowsButton.setSelected(true);
JRadioButton linuxButton = new JRadioButton(linuxString);
linuxButton.setMnemonic(KeyEvent.VK_L);
linuxButton.setActionCommand(linuxString);
JRadioButton macButton = new JRadioButton(macString);
macButton.setMnemonic(KeyEvent.VK_M);
macButton.setActionCommand(macString);
ButtonGroup group = new ButtonGroup();
group.add(windowsButton);
group.add(linuxButton);
group.add(macButton);
windowsButton.addActionListener(this);
linuxButton.addActionListener(this);
macButton.addActionListener(this);
picture = new JLabel(createImageIcon("images/" + windowsString + ".gif"));
picture.setPreferredSize(new Dimension(200, 150));
JPanel radioPanel = new JPanel(new GridLayout(0, 1));
radioPanel.add(windowsButton);
radioPanel.add(linuxButton);
radioPanel.add(macButton);
add(radioPanel, BorderLayout.LINE_START);
add(picture, BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
}
public void actionPerformed(ActionEvent e) {
picture.setIcon(createImageIcon("images/" + e.getActionCommand() + ".gif"));
}
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = OSButtons.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("OSButtons");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new RadioButtonDemo();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
I hope that's readable. Anyways, I compiled the code and it came up with these errors:
I really have no idea how to proceed from here as far as fixing these, this assignment was kind of thrown onto me and I had to research Swing, SWT, and AWT completely on my own. Any help that could be offered would be greatly appreciated.
Change...
picture = newJLabel(createImageIcon("images/"+ windowsString + ".gif"));
to...
picture = new JLabel(createImageIcon("images/"+ windowsString + ".gif"));
Change
radiopanel.add(macButton);
to...
radioPanel.add(macButton);
Java is case sensitve, variable names case must match
This...
JComponent newContentPane = new RadioButtonDemo();
I suspect is a copy/paste error. You change the class name of the original code, but forgot to change any references to it.
Try...
JComponent newContentPane = new OSButtons();
Instead
Update
Okay. Let's assume that you have your source files in C:\Users\Keith\Desktop\components.
At the command prompt your would compile them by using something like...
C:\> cd C:\Users\Keith\Desktop
C:\Users\Keith\Desktop> javac components.OSButtons.java
C:\Users\Keith\Desktop> java components.OSButtons
There is a direct coalition between the package name and the expected directory of the class files.

Categories

Resources