我是java的新手。我搜索了这个问题并找到了一些解决方案。但我没有得到任何改进。你能告诉我我的代码有什么问题吗? 该程序将图像转换为base64字符串并解码为图像。也可以将字符串保存到文件中。 问题是第一个按钮在运行后可见。但是在鼠标悬停之前,其他两个按钮都不可见。
这是我的完整代码:
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:请忽略我糟糕的英语和编码惯例。
答案 0 :(得分:1)
这是你的一个问题:
public void paint(Graphics g) {
g.drawImage(img, 50, 100, 450, 450, null);
}
你没有调用super的paint方法super.paint(g);
,从而破坏了绘制链,阻止了容器绘制其子项(按钮)。但话说回来,你永远不应该覆盖JFrame的paint方法,你应该总是在JPanel的paintComponent重写方法中绘制,再次在你的覆盖中调用super的方法。
其他问题:
SwingUtilities.invokeLater(...)
。