鼠标悬停前按钮不可见
Button not visible until mouse hovering
我是 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: 请忽略我糟糕的英语和编码规范。
这是您遇到的问题之一:
public void paint(Graphics g) {
g.drawImage(img, 50, 100, 450, 450, null);
}
您没有调用 super 的绘制方法,super.paint(g);
从而打破了绘制链,阻止了容器绘制其子项(按钮)。但话虽如此,您永远不应该重写 JFrame 的 paint 方法,您几乎应该总是在 JPanel 的 paintComponent 重写方法中绘制,再次在重写中调用 super 的方法。
其他问题:
- 一定要在 Swing 事件线程上启动 GUI,方法是将启动代码放在 Runnable 中并将其传递到
SwingUtilities.invokeLater(...)
。
- 在后台线程上执行任何长运行代码,例如使用 SwingWorker。
我是 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: 请忽略我糟糕的英语和编码规范。
这是您遇到的问题之一:
public void paint(Graphics g) {
g.drawImage(img, 50, 100, 450, 450, null);
}
您没有调用 super 的绘制方法,super.paint(g);
从而打破了绘制链,阻止了容器绘制其子项(按钮)。但话虽如此,您永远不应该重写 JFrame 的 paint 方法,您几乎应该总是在 JPanel 的 paintComponent 重写方法中绘制,再次在重写中调用 super 的方法。
其他问题:
- 一定要在 Swing 事件线程上启动 GUI,方法是将启动代码放在 Runnable 中并将其传递到
SwingUtilities.invokeLater(...)
。 - 在后台线程上执行任何长运行代码,例如使用 SwingWorker。