所以我有一个JTextPane
对象需要在运行时将其背景更改为特定图像的背景。我所拥有的似乎非常多(JComboBox
用于更改背景并调用repaintBackground()
似乎不会在选择时自动关闭等),它也会抛出一个nullpointer而我不知道为什么背景变化。
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.text.BoxView.paint(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI$RootView.paint(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI.paintSafely(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthEditorPaneUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthEditorPaneUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
etc etc etc....
这是我的目标:
public class PreviewPane extends JTextPane {
private String _name = "bg3";
public PreviewPane() {
super();
setOpaque(false);
StyledDocument document = this.getStyledDocument();
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
document.setParagraphAttributes(0, document.getLength(), center, false);
}
@Override
protected void paintComponent(Graphics g) throws RuntimeException{
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
BufferedImage img = null;
try {
img = ImageIO.read(new File(getClass().getResource("/icons/"+_name+".png").toURI()));
} catch (IOException | URISyntaxException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
g.drawImage(img, 0, 0, this);
super.paintComponent(g);
}
public void repaintBackground(String bgName){
_name = bgName;
paintComponent(this.getGraphics());
}
}
任何帮助都将不胜感激。
答案 0 :(得分:4)
paintComponent(this.getGraphics());
- 否。您永远不必明确调用paintComponent
。而是致电repaint()
。
super.paintComponent(g);
方法的开头调用 paintComponent
,或者至少在使用Graphics
上下文进行任何绘制之前调用。
请勿使用paintComponent
方法加载图片。一种选择是将缓存保留在Map<String, Image>
中。这样您就可以轻松地引用它们,而无需在每次想要更改时加载它们。总的来说,无论你是否决定缓存它们,它都不是 的大问题。您只需在repaintBackground
方法中加载它。
保留班级成员Image image;
。这将是您用来绘制的Image
。您的repaintBackground
,我会接受Image
而不是字符串。您传递的Image
将是用于绘画的类成员Image image
。如果您决定从该方法加载图像,您仍然可以让方法接受String。
classs MyPanel extends JPanel {
Image image;
public void repaintBackground(Image image) {
this.image = image;
repaint();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image);
}
}
paintComponent
不应抛出RuntimeException
这是一个完整的例子。我决定使用Map
缓存。由你决定如何做到这一点。有很多方法可以解决这个问题。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class ImageChangeDemo {
private ImagePanel imagePanel = new ImagePanel();
public ImageChangeDemo() {
JFrame frame = new JFrame();
frame.add(imagePanel);
frame.add(createCombo(), BorderLayout.PAGE_START);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JComboBox createCombo() {
String[] items = {
ImagePanel.DIRECTORY,
ImagePanel.COMPUTER,
ImagePanel.FILE,
ImagePanel.FLOPPY,
ImagePanel.HARD_DRIVE
};
JComboBox comboBox = new JComboBox(items);
comboBox.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
imagePanel.repaintBackground(comboBox.getSelectedItem().toString());
}
});
return comboBox;
}
private class ImagePanel extends JPanel {
public static final String DIRECTORY = "directory";
public static final String FILE = "file";
public static final String COMPUTER = "computer";
public static final String HARD_DRIVE = "harddrive";
public static final String FLOPPY = "floppy";
Map<String, Image> images = new HashMap<>();
private Image currentImage;
public ImagePanel() {
initImageMap();
repaintBackground(DIRECTORY);
}
private void initImageMap() {
ImageIcon dirIcon = (ImageIcon)UIManager.getIcon("FileView.directoryIcon");
ImageIcon fileIcon =(ImageIcon)UIManager.getIcon("FileView.fileIcon");
ImageIcon compIcon = (ImageIcon)UIManager.getIcon("FileView.computerIcon");
ImageIcon hdIcon = (ImageIcon)UIManager.getIcon("FileView.hardDriveIcon");
ImageIcon flopIcon = (ImageIcon)UIManager.getIcon("FileView.floppyDriveIcon");
images.put(DIRECTORY, dirIcon.getImage());
images.put(FILE, fileIcon.getImage());
images.put(COMPUTER, compIcon.getImage());
images.put(HARD_DRIVE, hdIcon.getImage());
images.put(FLOPPY, flopIcon.getImage());
}
protected void repaintBackground(String key) {
currentImage = images.get(key);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(currentImage, 0, 0, getWidth(), getHeight(), this);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new ImageChangeDemo();
}
});
}
}
答案 1 :(得分:2)
首先单独进行图像初始化和绘图。将img装载移出油漆。也不要尝试创建文件。如果无法创建JAR文件中的图像。
public PreviewPane() {
super();
setOpaque(false);
StyledDocument document = this.getStyledDocument();
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
document.setParagraphAttributes(0, document.getLength(), center, false);
}
BufferedImage img = null;
private void initImg() {
if( img==null) {
img = ImageIO.read(getClass().getResourceAsStream("/icons/"+_name+".png")));
//process missing img here
}
}
@Override
protected void paintComponent(Graphics g) throws RuntimeException{
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
initImg();
BufferedImage img = null;
g.drawImage(img, 0, 0, this);
super.paintComponent(g);
}