简体   繁体   English

鼠标悬停之前按钮不可见

[英]Button not visible until mouse hovering

I am new in java. 我是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. 该程序将图像转换为base64字符串,然后解码为图像。 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. PS:请忽略我糟糕的英语和编码约定。

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); 您不是在调用super的paint方法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. 话虽如此,您永远不应覆盖JFrame的paint方法,而应该几乎总是在JPanel的paintComponent覆盖方法内进行绘制,并在覆盖范围内再次调用super的方法。

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(...) . 确保通过将启动代码放在Runnable中并将其传递到SwingUtilities.invokeLater(...)来在Swing事件线程上启动GUI。
  • Do any long-running code on a background thread such as with a SwingWorker. 在后台线程上执行任何长时间运行的代码,例如使用SwingWorker。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM