I have a GridBagConstraints gbcImage and a JLabel that is initialized like this:
gbcImage.gridx = 1; // column 0
gbcImage.gridy = 2; // row 2
gbcImage.ipady = 100;
gbcImage.ipadx = 100;
JLabel label = new JLabel("", null, JLabel.CENTER);
label.setOpaque(true);
label.setBackground(Color.WHITE);
panel.add(label, gbcImage);
Where panel is added to a JFrame.
So I implemented a MouseListener to the label:
public void mouseClicked(MouseEvent e) {
JFileChooser jfc = new JFileChooser();
int iRet = jfc.showOpenDialog(panel);
if (iRet == jfc.APPROVE_OPTION)
{
File file = jfc.getSelectedFile();
try
{
BufferedImage bi = ImageIO.read(file);
image = new ImageIcon(bi);
JLabel label = new JLabel("", image, JLabel.CENTER);
panel.add(label, gbcImage);
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
}
But it didn't work. The image doesn't show in the panel at runtime.
What am I missing?
There is no need to create a new JLabel. The problem is you added a new label to the panel but its default size is (0, 0) because you didn't reavalidate() and repaint() the panel.
There is no need to create a new label.
Instead you keep a reference to the original label (like you do for the panel) and then you just replace the icon:
image = new ImageIcon(bi);
label.setIcon( image );
I've been searching for an answer, but everything else comes very close, but isn't the problem I'm having.
So my main class creates a new JFrame, adds a panel as the content panel, and I add a scrollpanel to that content panel.
Now I create some of my extending JPanel classes, add them to the scroll pane and see nothing but an empty frame.
And I have checked to make sure there is indeed a list of FTPFile's
Here is the main code:
public browser(ftpHandler _FTP) {
FTP = _FTP;
Panels = new ArrayList<JPanel>();
frame = new JFrame("File Browser");
frame.setContentPane(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(750, 500));
frame.setSize(frame.getPreferredSize());
frame.setMinimumSize(frame.getSize());
mainPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
listFiles();
frame.pack();
frame.setVisible(true);
}
public void listFiles(){
Panels.clear();
FTPFile[] list = null;
try {
list = FTP.listFiles();
} catch (Exception e) {
e.printStackTrace();
}
for(FTPFile file : list){
fileObject FO = new fileObject(file);
Panels.add(FO);
scrollPane.add(FO);
}
scrollPane.updateUI();
}
And my extended JPanel, fileObject
public class fileObject extends JPanel {
private FTPFile file;
private JLabel Label;
private ImageIcon Icon;
private int FileType;
private final int IconSize = 25;
private final Dimension panelSize = new Dimension(150, 40);
public fileObject(FTPFile FILE){
file = FILE;
FileType = file.getType();
this.setSize(panelSize);
this.setPreferredSize(panelSize);
this.setMinimumSize(panelSize);
this.setLayout(new WrapLayout());
switch (FileType){
case FTPFile.TYPE_DIRECTORY:
Icon = resizeImage(new ImageIcon(getClass().getResource("/com/taylor/48px/folder.png")),IconSize);
break;
case FTPFile.TYPE_FILE:
try {
String FileExtension = file.getName().substring(file.getName().lastIndexOf(".")+1);
Icon = resizeImage(new ImageIcon(getClass().getResource("/com/taylor/48px/"+FileExtension+".png")),IconSize);
} catch(Exception e) {
Icon = resizeImage(new ImageIcon(getClass().getResource("/com/taylor/48px/_blank.png")),IconSize);
}
break;
case FTPFile.TYPE_LINK:
Icon = resizeImage(new ImageIcon(getClass().getResource("/com/taylor/48px/_page.png")),IconSize);
break;
}
Label = new JLabel(file.getName(), Icon, JLabel.LEFT);
this.add(Label);
}
private ImageIcon resizeImage(ImageIcon II, int Size){
Image img = II.getImage();
BufferedImage resizedImage = new BufferedImage(Size, Size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resizedImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, 0, 0, Size, Size, null);
g2.dispose();
return new ImageIcon(resizedImage);
}
}
I got this working, it turns out I was had my panels set up wrong, they were setup like this:
JFrame
--mainPanel
----scrollPane
And I was adding my extended panel to the scrollPane
And this seemed to not work, so I added another panel inside the scrollPane and started adding my extended panels to this new panel and it started working!
I'm creating a gui that has 2 panels. When the gui is first loaded only one panel is visible and when a button is pressed the new panel is displayed. The problem is that on the 2nd panel when it loads the buttons are invisible and only display when the mouse hovers over them. On top of that when you move the screen they become invisible again and need to be hovered over to be displayed again.
I really don't know what to try as I have looked at methods of having multiple panels and this seems the best way to do it and aswell as this the buttons are implmented the same way I have implemented them for the 1st panel and they render correctly.
Full Code
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Gui {
private JFrame frame;
private JPanel panel1;
private JPanel panel2;
private JButton btnShip1, btnShip2, btnShip3, btnTutorial, btnLeftControl, btnHull, btnTargeting, btnRadar, btnWarning, btnRightControl;
private JTextField txtCharacterName, txtShipName;
private JLabel welcome, background;
public static void main(String[] args) {
new Gui();
}
public Gui(){
createWindow();
addButtons();
addFields();
addWelcome();
frame.add(panel1);
frame.setVisible(true);
addBackground();
addShipControls();
}
public void createWindow(){
frame = new JFrame();
frame.setTitle("Space Battle");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(642, 518);
panel1 = new JPanel();
panel1.setLayout(null);
panel1.setBackground(Color.decode("#242627"));
panel2 = new JPanel();
panel2.setLayout(null);
panel2.setBackground(Color.decode("#242627"));
}
public void addButtons(){
btnShip1 = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/cruiserSelectBtn.jpg");
btnShip1.setIcon(img);
}
catch (Exception e) {}
try
{
ImageIcon img = new ImageIcon ("resources/button_1_hover.gif");
btnShip1.setRolloverIcon(img);
}
catch (Exception e) {}
btnShip1.setBounds(246,0,380,160);
btnShip1.setMargin(new Insets(0, 0, 0, 0));
btnShip1.addActionListener(new cruiserSelectHandler());
btnShip1.setBorder(null);
panel1.add (btnShip1);
btnShip2 = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/fighterSelectBtn.jpg");
btnShip2.setIcon(img);
}
catch (Exception e) {}
try
{
ImageIcon img = new ImageIcon ("resources/button_2_hover.gif");
btnShip2.setRolloverIcon(img);
}
catch (Exception e) {}
btnShip2.setBounds(246,160,380,160);
btnShip2.setMargin(new Insets(0, 0, 0, 0));
btnShip2.addActionListener(new fighterSelectHandler());
btnShip2.setBorder(null);
panel1.add (btnShip2);
btnShip3 = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/battleSelectBtn.jpg");
btnShip3.setIcon(img);
}
catch (Exception e) {}
try
{
ImageIcon img = new ImageIcon ("resources/button_3_hover.gif");
btnShip3.setRolloverIcon(img);
}
catch (Exception e) {}
btnShip3.setBounds(246,320,380,160);
btnShip3.setMargin(new Insets(0, 0, 0, 0));
btnShip3.addActionListener(new battleSelectHandler());
btnShip3.setBorder(null);
panel1.add (btnShip3);
btnTutorial = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/tutorialBtn.jpg");
btnTutorial.setIcon(img);
}
catch (Exception e) {}
btnTutorial.setBounds(5,426,234,49);
btnTutorial.setMargin(new Insets(0, 0, 0, 0));
panel1.add (btnTutorial);
}
public void addFields(){
txtCharacterName = new JTextField("Insert Character Name");
txtCharacterName.setBounds(12,260,220,35);
panel1.add(txtCharacterName);
txtShipName = new JTextField("Insert Ship Name");
txtShipName.setBounds(12,315,220,35);
panel1.add(txtShipName);
}
public void addWelcome(){
welcome = new JLabel ();
try
{
ImageIcon img = new ImageIcon ("resources/welcome.jpg");
welcome.setIcon(img);
}
catch (Exception e) {}
welcome.setBounds(0,0,247,229);
panel1.add(welcome);
}
//Class used to change panels
class cruiserSelectHandler implements ActionListener {
public void actionPerformed(ActionEvent even) {
frame.add(panel2);
panel1.setVisible(false);
}
}
class fighterSelectHandler implements ActionListener {
public void actionPerformed(ActionEvent even) {
frame.add(panel2);
panel1.setVisible(false);
}
}
class battleSelectHandler implements ActionListener {
public void actionPerformed(ActionEvent even) {
frame.add(panel2);
panel1.setVisible(false);
}
}
public void addBackground(){
//Is the background interfering?
background = new JLabel ();
try
{
ImageIcon img = new ImageIcon ("resources/background.jpg");
background.setIcon(img);
}
catch (Exception e) {}
background.setBounds(0,0,640,480);
panel2.add(background);
}
//Class used to add controls/buttons
public void addShipControls(){
btnLeftControl = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/left_controls.png");
btnLeftControl.setIcon(img);
}
catch (Exception e) {}
btnLeftControl.setBounds(-8,319,131,160);
btnLeftControl.setMargin(new Insets(0, 0, 0, 0));
btnLeftControl.setBorder(null);
panel2.add (btnLeftControl);
btnHull = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/hull_controls.png");
btnHull.setIcon(img);
}
catch (Exception e) {}
btnHull.setBounds(123,319,91,160);
btnHull.setMargin(new Insets(0, 0, 0, 0));
btnHull.setBorder(null);
panel2.add (btnHull);
btnTargeting = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/targeting_controls.png");
btnTargeting.setIcon(img);
}
catch (Exception e) {}
btnTargeting.setBounds(214,319,202,160);
btnTargeting.setMargin(new Insets(0, 0, 0, 0));
btnTargeting.setBorder(null);
panel2.add (btnTargeting);
btnWarning = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/warning_controls.png");
btnWarning.setIcon(img);
}
catch (Exception e) {}
btnWarning.setBounds(416,411,86,68);
btnWarning.setMargin(new Insets(0, 0, 0, 0));
btnWarning.setBorder(null);
panel2.add (btnWarning);
btnRadar = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/radar_idea.gif");
btnRadar.setIcon(img);
}
catch (Exception e) {}
btnRadar.setBounds(416,319,86,92);
btnRadar.setMargin(new Insets(0, 0, 0, 0));
btnRadar.setBorder(null);
panel2.add (btnRadar);
btnRightControl = new JButton ();
try
{
ImageIcon img = new ImageIcon ("resources/right_controls.png");
btnRightControl.setIcon(img);
}
catch (Exception e) {}
btnRightControl.setBounds(502,319,131,160);
btnRightControl.setMargin(new Insets(0, 0, 0, 0));
btnRightControl.setBorder(null);
panel2.add (btnRightControl);
}
}
when a button is pressed the new panel is displayed.
The problem is:
you are using a null layout
you are add two different panels to the frame.
By default Swing paints components in the reverse order that they were added.
So when you add panel1, it is the only panel of the frame so it is painted.
Then you click a button and add panel2. So Swing paints panel2 and then repaints panel1 on top, so panel2 is hidden. When you mouse over the button it appears because buttons listen for mouseEntered events and the button gets repainted.
When you resize the screen panel2 is painted and then panel1 is painted so you have the problem again.
The solution is to use a proper layout manager. In your case you should be using a Card Layout. The Card Layout will swap panels making sure only one panel is ever visible at a time. Read the Swing tutorial on Using Card Layout. Then get rid of all the null layouts and setBounds() methods.
I am not able to dynamically repaint() inside the Jframe.
public static BufferedImage createBufferedImage(BufferedImage image)
{
ColorModel cm = image.getColorModel();
boolean premultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = image.copyData(image.getRaster());
return new BufferedImage(cm, raster, premultiplied, null);
}
public static void main(String[] args) {
BufferedImage img = new BufferedImage(old_width_i, old_height_i, BufferedImage.TYPE_INT_RGB);
img=createBufferedImage(img_white_screen);
JFrame frame=new JFrame();
JLabel label = new JLabel(new ImageIcon(img));
frame.getContentPane().add(label, BorderLayout.WEST);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
img.flush();
img=createBufferedImage(img_black_screen);
// frame.removeAll();
// frame.revalidate();
// label.removeAll();
// label = new JLabel(new ImageIcon(img));
// frame.getContentPane().add(label, BorderLayout.WEST);
frame.repaint();
}
It basically, creates a screen with the first assignment to the "img" (i.e. img_white_screen) variable and does not change to the second assignment i.e. img_black_screen
don't to use Thread.sleep(1000);, this code line lock Event Dispatch Thread,
no idea for why reason you need to pause code execution for one second, use Swing Timer instead
for showing the Image in Java to use
XxxImage as Icon /IconImage to JLabel
paintComponent() for JComponent or JPanel
don't paint XxxImage or Icon / ImageIcon directly to the JFrame, use JPanel / JComponent or JLabel
I'm trying to make an experiment in image manipulation.
Basically I have an image that is continously updated by a timer and i display that image in a JLabel.
My problem is that JLabel does'nt refresh the image.
Here is my timer code:
Timer timer = new Timer(200, new ActionListener() {
public void actionPerformed(ActionEvent e) {
count++;
System.out.println("timer");
System.out.println(filename);
ImageIcon icon = new ImageIcon(filename);
label = new JLabel();
label.setIcon(icon);
label.setText(""+count);
panel = new JPanel();
panel.add(label);
frame.getContentPane().removeAll();
frame.getContentPane().add(panel);
frame.repaint();
frame.validate();
try{
FileWriter fstream;
fstream = new FileWriter(filename,true);
BufferedWriter out = new BufferedWriter(fstream);
out.write("text to append");
out.close();
}catch (Exception ex){
System.err.println("Error: " + ex.getMessage());
}
}
});
Where filename is path to my image.
Image is displayed but JLabel never refresh my image.
I tested my code and is working if I swich between two different images...
EDIT:
I solved by duplicate every time last image created and renaming with a timestamp.
label = new JLabel();
label.setIcon(icon);
label.setText(""+count);
panel = new JPanel();
panel.add(label);
frame.getContentPane().removeAll();
frame.getContentPane().add(panel);
frame.repaint();
frame.validate();
Replace all that with something like:
label.setIcon(icon);
If the label is not visible at that point, declare it as a class attribute of the outer class or at the same level as the frame (which is obviously accessible in that snippet).