Search code examples
javajframejbutton

Button not visible until mouse hovering


I am new in java. I've searched for this problem and found some solutions. But i am not getting any improvements. Can you guys tell me whats wrong with my code. This program converts image to base64 string and decodes into image. Also can save the string to file. The problem is 1st button is visible after running. but other two buttons are not visible until mouse hovering.

Here's my full code:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;

public class ImageConverter extends JFrame implements ActionListener {

JPanel jp = new JPanel();
JFileChooser directory = new JFileChooser();
JFileChooser fileChooser = new JFileChooser();
File selectedFile = null;
BufferedImage img;
FileInputStream in;
String imgstr;

JLabel imageLabel = new JLabel();

public ImageConverter() {
    super("Image Converter");

    // create Panel
    jp = new JPanel();
    setLayout(new FlowLayout());
    setBackground(Color.white);

    add(jp);

    JButton encode = new JButton("Encode");
    JButton decode = new JButton("Decode");
    JButton save = new JButton("Save Code");

    jp.add(encode);
    jp.add(decode);
    jp.add(save);


    encode.addActionListener(this);
    decode.addActionListener(this);
    save.addActionListener(this);

}

public void actionPerformed(ActionEvent e) {
    if (e.getActionCommand().equals("Encode")) {
        File selectedFile = null;
        fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
        int result = fileChooser.showOpenDialog(null);
        if (result == JFileChooser.APPROVE_OPTION) {
            selectedFile = fileChooser.getSelectedFile();
            System.out.println("Selected file: " + selectedFile.getAbsolutePath());
            try {
                img = ImageIO.read(selectedFile);
            } catch (IOException ie) {
                // TODO Auto-generated catch block
                ie.printStackTrace();
            }
            repaint();
            imgstr = encodeToString(img, getFileExtension(selectedFile));
            System.out.println(imgstr);
        }
    } else if (e.getActionCommand().equals("Decode")) {
        File selectedFile = null;
        String code = "";
        fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
        int result = fileChooser.showOpenDialog(null);
        if (result == JFileChooser.APPROVE_OPTION) {
            selectedFile = fileChooser.getSelectedFile();
            System.out.println("Selected file: " + selectedFile.getAbsolutePath());
            try {

                code = new Scanner(new File(selectedFile.getAbsolutePath())).useDelimiter("\\Z").next();
            } catch (IOException ie) {
                // TODO Auto-generated catch block
                ie.printStackTrace();
            }
            System.out.println(code);
            img = decodeToImage(code);
            repaint();
        }

    } else {
        directory.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        directory.showOpenDialog(null);
        System.out.println(directory.getCurrentDirectory());
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter(directory.getCurrentDirectory() + "/code.txt"));
            writer.write(imgstr);

        } catch (IOException ex) {
        } finally {
            try {
                if (writer != null)
                    writer.close();
            } catch (IOException ex) {
              ie.printStackTrace();
            }
        }

    }

}

public void paint(Graphics g) {
    g.drawImage(img, 50, 100, 450, 450, null);
}

public static BufferedImage decodeToImage(String imageString) {

    BufferedImage image = null;
    byte[] imageByte;
    try {
        imageByte = Base64.getDecoder().decode(imageString);
        ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
        image = ImageIO.read(bis);
        bis.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return image;
}

public static String encodeToString(BufferedImage image, String type) {
    String imageString = null;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    try {
        ImageIO.write(image, type, bos);

        byte[] imageBytes = bos.toByteArray();

        imageString = Base64.getEncoder().encodeToString(imageBytes);

        bos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return imageString;
}

private static String getFileExtension(File file) {
    String fileName = file.getName();
    if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0)
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    else
        return "";
}

public static void main(String Args[]) {
    ImageConverter frame = new ImageConverter();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.setSize(600, 600);
    frame.setVisible(true);
}

}

PS: please ignore my bad English and coding convention.


Solution

  • Here's one of your problems:

    public void paint(Graphics g) {
        g.drawImage(img, 50, 100, 450, 450, null);
    }
    

    You're not calling the super's paint method, super.paint(g); and thus breaking the paint chain, preventing the container from drawing its children (the button). But having said that, you should never override the paint method of a JFrame, and you should almost always instead draw within a JPanel's paintComponent overridden method, again calling the super's method within your override.

    Other issues:

    • Be sure to start your GUI on the Swing event thread by placing the start up code within a Runnable and passing that into SwingUtilities.invokeLater(...).
    • Do any long-running code on a background thread such as with a SwingWorker.